aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken/qapp_macro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/libshiboken/qapp_macro.cpp')
-rw-r--r--sources/shiboken2/libshiboken/qapp_macro.cpp65
1 files changed, 48 insertions, 17 deletions
diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp
index 306f53b74..827c240c5 100644
--- a/sources/shiboken2/libshiboken/qapp_macro.cpp
+++ b/sources/shiboken2/libshiboken/qapp_macro.cpp
@@ -53,19 +53,17 @@ extern "C"
// variable that monitors Q*Application.instance().
// This variable is also able to destroy the app by deleting qApp.
//
+static const char *mod_names[3] = {"PySide2.QtCore", "PySide2.QtGui", "PySide2.QtWidgets"};
+static const char *app_names[3] = {"QCoreApplication", "QGuiApplication", "QApplication"};
+
static int
qApp_module_index(PyObject *module)
{
const char *name = PyModule_GetName(module);
- int ret = 0;
-
- if (strcmp(name, "PySide2.QtCore") == 0)
- ret = 1;
- else if (strcmp(name, "PySide2.QtGui") == 0)
- ret = 2;
- else if (strcmp(name, "PySide2.QtWidgets") == 0)
- ret = 3;
- return ret;
+ for (int idx = 0; idx < 3; idx++)
+ if (strcmp(name, mod_names[idx]) == 0)
+ return idx + 1;
+ return 0;
}
#define PYTHON_IS_PYTHON3 (PY_VERSION_HEX >= 0x03000000)
@@ -109,6 +107,8 @@ reset_qApp_var(void)
return 0;
}
+static bool app_created = false;
+
/*
* Note:
* The PYSIDE-585 problem was that shutdown is called one more often
@@ -120,7 +120,6 @@ reset_qApp_var(void)
PyObject *
MakeSingletonQAppWrapper(PyTypeObject *type)
{
- static bool app_created = false;
if (type == nullptr)
type = Py_NONE_TYPE;
if (!(type == Py_NONE_TYPE || Py_TYPE(qApp_content) == Py_NONE_TYPE)) {
@@ -163,7 +162,7 @@ MakeSingletonQAppWrapper(PyTypeObject *type)
if (__moduleShutdown != nullptr)
Py_XDECREF(PyObject_CallFunction(__moduleShutdown, const_cast<char *>("()")));
} else {
- PyObject_INIT(qApp_content, type);
+ PyObject_Init(qApp_content, type);
app_created = true;
}
Py_INCREF(qApp_content);
@@ -245,13 +244,45 @@ NotifyModuleForQApp(PyObject *module, void *qApp)
* Therefore, the implementation is very simple and just redirects the
* qApp_contents variable and assigns the instance, instead of vice-versa.
*/
- PyObject *coreDict = qApp_moduledicts[1];
- if (qApp != nullptr && coreDict != nullptr) {
- PyObject *coreApp = PyDict_GetItemString(coreDict, "QCoreApplication");
- if (coreApp != nullptr) {
- qApp_content = PyObject_CallMethod(coreApp, "instance", "");
- reset_qApp_var();
+
+ // PYSIDE-1135: Make sure that at least QtCore gets imported.
+ // That problem exists when a derived instance is created in C++.
+ // PYSIDE-1164: Use the highest Q*Application module possible,
+ // because in embedded mode the instance() seems to be sticky.
+ static bool oneshot_active = false;
+ if (qApp == nullptr || app_created || oneshot_active)
+ return;
+
+ // qApp exists without an application created.
+ // We assume that we are embedded, and we simply try to import all three modules.
+ oneshot_active = true;
+ int mod_found = 0;
+ const char *mod_name, *app_name;
+ const char *thismod_name = PyModule_GetName(module);
+
+ // First go through all three modules, import and set qApp_moduledicts.
+ for (int idx = 0; idx < 3; idx++) {
+ // only import if it is not already the module
+ PyObject *mod = strcmp(thismod_name, mod_names[idx]) == 0 ? module
+ : PyImport_ImportModule(mod_names[idx]);
+ if (mod != nullptr) {
+ mod_found = idx + 1;
+ qApp_moduledicts[mod_found] = PyModule_GetDict(mod);
+ mod_name = PyModule_GetName(mod);
+ app_name = app_names[idx];
+ continue;
}
+ PyErr_Clear();
+ }
+
+ // Then take the highest module and call instance() on it.
+ if (mod_found) {
+ PyObject *mod_dict = qApp_moduledicts[mod_found];
+ PyObject *app_class = PyDict_GetItemString(mod_dict, app_name);
+ qApp_content = PyObject_CallMethod(app_class, const_cast<char *>("instance"),
+ const_cast<char *>(""));
+ app_created = true;
+ reset_qApp_var();
}
}