diff options
-rw-r--r-- | PySide/QtCore/glue/qcoreapplication_init.cpp | 11 | ||||
-rw-r--r-- | PySide/QtCore/typesystem_core.xml | 11 | ||||
-rw-r--r-- | PySide/QtGui/glue/qapplication_init.cpp | 20 | ||||
-rw-r--r-- | libpyside/pyside.cpp | 21 | ||||
-rw-r--r-- | libpyside/pyside.h | 9 | ||||
-rw-r--r-- | libpyside/signalmanager.cpp | 7 |
6 files changed, 59 insertions, 20 deletions
diff --git a/PySide/QtCore/glue/qcoreapplication_init.cpp b/PySide/QtCore/glue/qcoreapplication_init.cpp index 7601dbd1d..14ccbb8f9 100644 --- a/PySide/QtCore/glue/qcoreapplication_init.cpp +++ b/PySide/QtCore/glue/qcoreapplication_init.cpp @@ -1,21 +1,20 @@ // Global variables used to store argc and argv values static int QCoreApplicationArgCount; static char** QCoreApplicationArgValues; -static bool leavingPython = false; /** * Called at QtCore module exit */ void DeleteQCoreApplicationAtExit() { - leavingPython = true; QCoreApplication *cpp = QCoreApplication::instance(); if (cpp) { Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance(); PyObject* pySelf = bmngr.retrieveWrapper(cpp); - if (pySelf) - bmngr.invalidateWrapper(pySelf); - cpp->deleteLater(); + cpp->flush(); + QCoreApplication::processEvents(); + bmngr.invalidateWrapper(pySelf); + delete cpp; } } @@ -54,7 +53,7 @@ int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*) PySide::signalUpdateSource(self); cptr->metaObject(); - Py_AtExit(DeleteQCoreApplicationAtExit); + PySide::registerCleanupFunction(DeleteQCoreApplicationAtExit); Py_INCREF(self); return 1; } diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index d7c5891a7..f10ed0709 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -552,8 +552,8 @@ </inject-code> <add-function signature="__moduleShutdown()"> - <inject-code class="target" position="beginning"> - PySide::SignalManager::instance().clear(); + <inject-code class="target" position="beginning"> + PySide::runCleanupFunctions(); </inject-code> </add-function> @@ -1875,12 +1875,7 @@ <!-- Obsolete --> <modify-function signature="argc()" remove="all"/> <!-- Obsolete --> - <modify-function signature="notify(QObject*,QEvent*)"> - <inject-code class="shell" position="beginning"> - Shiboken::ThreadStateSaver threadStateSaver; - if (!leavingPython) - threadStateSaver.save(); - </inject-code> + <modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes"> <modify-argument index="2" invalidate-after-use="yes"/> </modify-function> <modify-function signature="QCoreApplication(int &, char **)" access="private"/> diff --git a/PySide/QtGui/glue/qapplication_init.cpp b/PySide/QtGui/glue/qapplication_init.cpp index 699633a1d..208d59a52 100644 --- a/PySide/QtGui/glue/qapplication_init.cpp +++ b/PySide/QtGui/glue/qapplication_init.cpp @@ -4,19 +4,29 @@ extern PyObject* moduleQtGui; static int QApplicationArgCount; static char** QApplicationArgValues; static const char QAPP_MACRO[] = "qApp"; -static bool leavingPython = false; void DeleteQApplicationAtExit() { - leavingPython = true; PySide::SignalManager::instance().clear(); QCoreApplication* cpp = QApplication::instance(); if (cpp) { Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance(); - PyObject* pySelf = bmngr.retrieveWrapper(cpp); - if (pySelf) + cpp->flush(); + + // Delete all widgets, this is slow but is necessary to avoid problems with python object + foreach(QWidget* w, QApplication::allWidgets()) { + PyObject* pySelf = bmngr.retrieveWrapper(w); + + w->deleteLater(); + //Make sure all events will send before invalidated the python object + QApplication::processEvents(); bmngr.invalidateWrapper(pySelf); + } + + PyObject* pySelf = bmngr.retrieveWrapper(cpp); cpp->deleteLater(); + QApplication::processEvents(); + bmngr.invalidateWrapper(pySelf); } } @@ -62,7 +72,7 @@ int SbkQApplication_Init(PyObject* self, PyObject* args, PyObject*) } PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self); - Py_AtExit(DeleteQApplicationAtExit); + PySide::registerCleanupFunction(DeleteQApplicationAtExit); Py_INCREF(self); return 1; } diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index ddec19803..bd4ab7c64 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -24,18 +24,22 @@ #include "pyside.h" #include "signalmanager.h" #include "qproperty.h" +#include "qsignal.h" #include <basewrapper.h> #include <conversions.h> #include <algorithm> -#include "qsignal.h" +#include <QStack> extern "C" void init_signal(PyObject* module); extern "C" void init_slot(PyObject* module); extern "C" void init_qproperty(PyObject* module); +static QStack<PySide::CleanupFunction> cleanupFunctionList; + namespace PySide { + void init(PyObject *module) { init_signal(module); @@ -82,5 +86,20 @@ bool fillQtProperties(PyObject* qObj, const QMetaObject* metaObj, PyObject* kwds return true; } +void registerCleanupFunction(CleanupFunction func) +{ + cleanupFunctionList.push(func); +} + +void runCleanupFunctions() +{ + while (!cleanupFunctionList.isEmpty()) { + CleanupFunction f = cleanupFunctionList.pop(); + f(); + } +} + + + } //namespace PySide diff --git a/libpyside/pyside.h b/libpyside/pyside.h index cae050b5d..2c5afb536 100644 --- a/libpyside/pyside.h +++ b/libpyside/pyside.h @@ -75,6 +75,15 @@ template<typename T> struct initQtMetaType<T, false> { }; + +typedef void (*CleanupFunction)(void); + +/** + * Register a function to be called before python die + */ +PYSIDE_API void registerCleanupFunction(CleanupFunction func); +PYSIDE_API void runCleanupFunctions(); + } //namespace PySide diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index 8208796b2..3724500d5 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -22,6 +22,7 @@ #include "signalmanager.h" #include "qproperty.h" +#include "pyside.h" #include <QHash> #include <QStringList> @@ -223,6 +224,11 @@ struct SignalManager::SignalManagerPrivate GlobalReceiver m_globalReceiver; }; +static void clearSignalManager() +{ + PySide::SignalManager::instance().clear(); +} + SignalManager::SignalManager() : m_d(new SignalManagerPrivate) { // Register Qt primitive typedefs used on signals. @@ -234,6 +240,7 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate) TypeResolver::createValueTypeResolver<PyObjectWrapper>(PYTHON_TYPE); TypeResolver::createValueTypeResolver<PyObjectWrapper>("object"); TypeResolver::createValueTypeResolver<PyObjectWrapper>("PySide::PyObjectWrapper"); + PySide::registerCleanupFunction(clearSignalManager); } void SignalManager::clear() |