diff options
-rw-r--r-- | PySide/QtCore/glue/qcoreapplication_init.cpp | 17 | ||||
-rw-r--r-- | PySide/QtGui/glue/qapplication_init.cpp | 24 | ||||
-rw-r--r-- | libpyside/pyside.cpp | 26 | ||||
-rw-r--r-- | libpyside/pyside.h | 5 | ||||
-rw-r--r-- | tests/QtGui/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tests/QtGui/bug_429.py | 10 | ||||
-rw-r--r-- | tests/QtGui/bug_430.py | 14 | ||||
-rw-r--r-- | tests/QtGui/bug_433.py | 14 | ||||
-rw-r--r-- | tests/QtUiTools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/QtUiTools/bug_426.py | 18 | ||||
-rw-r--r-- | tests/QtUiTools/bug_426.ui | 19 |
11 files changed, 112 insertions, 39 deletions
diff --git a/PySide/QtCore/glue/qcoreapplication_init.cpp b/PySide/QtCore/glue/qcoreapplication_init.cpp index 461757cc3..66247bfc8 100644 --- a/PySide/QtCore/glue/qcoreapplication_init.cpp +++ b/PySide/QtCore/glue/qcoreapplication_init.cpp @@ -2,21 +2,6 @@ static int QCoreApplicationArgCount; static char** QCoreApplicationArgValues; -/** - * Called at QtCore module exit - */ -void DeleteQCoreApplicationAtExit() -{ - QCoreApplication *cpp = QCoreApplication::instance(); - if (cpp) { - Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance(); - cpp->flush(); - QCoreApplication::processEvents(); - bmngr.destroyWrapper(cpp); - delete cpp; - } -} - int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*) { if (Shiboken::isUserType(self) && !Shiboken::canCallConstructor(self->ob_type, Shiboken::SbkType<QApplication >())) @@ -52,7 +37,7 @@ int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*) PySide::signalUpdateSource(self); cptr->metaObject(); - PySide::registerCleanupFunction(DeleteQCoreApplicationAtExit); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); Py_INCREF(self); return 1; } diff --git a/PySide/QtGui/glue/qapplication_init.cpp b/PySide/QtGui/glue/qapplication_init.cpp index d082b99f1..ba98f029a 100644 --- a/PySide/QtGui/glue/qapplication_init.cpp +++ b/PySide/QtGui/glue/qapplication_init.cpp @@ -5,28 +5,6 @@ static int QApplicationArgCount; static char** QApplicationArgValues; static const char QAPP_MACRO[] = "qApp"; -void DeleteQApplicationAtExit() -{ - PySide::SignalManager::instance().clear(); - QCoreApplication* cpp = QApplication::instance(); - if (cpp) { - Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance(); - - // Delete all widgets, this is slow but is necessary to avoid problems with python object - foreach(QWidget* w, QApplication::allWidgets()) { - PyObject* wrapper = bmngr.retrieveWrapper(w); - if (wrapper) { - if (SbkBaseWrapper_hasOwnership(wrapper)) - delete w; // destroy C++ object and invalidate wrapper object - else - bmngr.destroyWrapper(wrapper); // only invalidate wrapper object - } - } - cpp->flush(); - delete cpp; - } -} - int SbkQApplication_Init(PyObject* self, PyObject* args, PyObject*) { if (Shiboken::isUserType(self) && !Shiboken::canCallConstructor(self->ob_type, Shiboken::SbkType<QApplication >())) @@ -69,7 +47,7 @@ int SbkQApplication_Init(PyObject* self, PyObject* args, PyObject*) } PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self); - PySide::registerCleanupFunction(DeleteQApplicationAtExit); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); Py_INCREF(self); return 1; } diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index 7d9230016..c2e14350b 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -24,9 +24,11 @@ #include "pyside.h" #include <basewrapper.h> #include <conversions.h> +#include <typeresolver.h> #include <algorithm> #include <cctype> #include <QStack> +#include <QCoreApplication> #include "signalmanager.h" #include "qproperty_p.h" #include "qproperty.h" @@ -98,5 +100,29 @@ void runCleanupFunctions() } } +void destroyQCoreApplication() +{ + SignalManager::instance().clear(); + QCoreApplication* app = QCoreApplication::instance(); + if (!app) + return; + + Shiboken::BindingManager& bm = Shiboken::BindingManager::instance(); + PyObject* pyQApp = bm.retrieveWrapper(app); + PyTypeObject* pyQObjectType = Shiboken::TypeResolver::get("QObject*")->pythonType(); + assert(pyQObjectType); + + foreach (PyObject* pyObj, bm.getAllPyObjects()) { + if (pyObj != pyQApp && PyObject_TypeCheck(pyObj, pyQObjectType)) { + if (SbkBaseWrapper_hasOwnership(pyObj)) { + bm.destroyWrapper(pyObj); + delete static_cast<QObject*>(Shiboken::getCppPointer(pyObj, Shiboken::SbkType<QObject*>())); + } + } + } + app->flush(); + delete app; +} + } //namespace PySide diff --git a/libpyside/pyside.h b/libpyside/pyside.h index 2c5afb536..fe9ce3a6e 100644 --- a/libpyside/pyside.h +++ b/libpyside/pyside.h @@ -84,6 +84,11 @@ typedef void (*CleanupFunction)(void); PYSIDE_API void registerCleanupFunction(CleanupFunction func); PYSIDE_API void runCleanupFunctions(); +/** + * Destroy a QCoreApplication taking care of destroy all instances of QObject first. + */ +PYSIDE_API void destroyQCoreApplication(); + } //namespace PySide diff --git a/tests/QtGui/CMakeLists.txt b/tests/QtGui/CMakeLists.txt index 21aa7690d..7ff2f7e4b 100644 --- a/tests/QtGui/CMakeLists.txt +++ b/tests/QtGui/CMakeLists.txt @@ -13,6 +13,9 @@ PYSIDE_TEST(bug_367.py) PYSIDE_TEST(bug_389.py) PYSIDE_TEST(bug_400.py) PYSIDE_TEST(bug_416.py) +PYSIDE_TEST(bug_429.py) +PYSIDE_TEST(bug_430.py) +PYSIDE_TEST(bug_433.py) PYSIDE_TEST(customproxywidget_test.py) PYSIDE_TEST(deepcopy_test.py) PYSIDE_TEST(float_to_int_implicit_conversion_test.py) diff --git a/tests/QtGui/bug_429.py b/tests/QtGui/bug_429.py new file mode 100644 index 000000000..f49d24474 --- /dev/null +++ b/tests/QtGui/bug_429.py @@ -0,0 +1,10 @@ +from PySide.QtCore import * +from PySide.QtGui import * +import sys + +app = QApplication(sys.argv) +scene = QGraphicsScene() +label = QLabel("hello world") +label.show() +QTimer.singleShot(0, label.close) +exit(app.exec_()) diff --git a/tests/QtGui/bug_430.py b/tests/QtGui/bug_430.py new file mode 100644 index 000000000..256c4e203 --- /dev/null +++ b/tests/QtGui/bug_430.py @@ -0,0 +1,14 @@ +import sys +from PySide.QtCore import * +from PySide.QtGui import * + +class ListModel(QAbstractListModel): + def rowCount(self, parent = QModelIndex()): + return len(self._items) + +app = QApplication([]) +model = ListModel() +v = QListView() +v.setModel(model) +QTimer.singleShot(0, v.close) +app.exec_() diff --git a/tests/QtGui/bug_433.py b/tests/QtGui/bug_433.py new file mode 100644 index 000000000..97d897e81 --- /dev/null +++ b/tests/QtGui/bug_433.py @@ -0,0 +1,14 @@ +from PySide import QtCore, QtGui +import sys + +class Test(QtGui.QGraphicsView): + def __init__(self, parent=None): + super(Test, self).__init__(parent) + self.s = QtGui.QGraphicsScene() + self.setScene(self.s) + +a = QtGui.QApplication(sys.argv) +t = Test() +t.show() +QtCore.QTimer.singleShot(0, t.close) +sys.exit(a.exec_()) diff --git a/tests/QtUiTools/CMakeLists.txt b/tests/QtUiTools/CMakeLists.txt index 7cb8b6ada..ebf7a23ec 100644 --- a/tests/QtUiTools/CMakeLists.txt +++ b/tests/QtUiTools/CMakeLists.txt @@ -1,5 +1,6 @@ PYSIDE_TEST(bug_360.py) PYSIDE_TEST(bug_376.py) PYSIDE_TEST(bug_392.py) +PYSIDE_TEST(bug_426.py) PYSIDE_TEST(uiloader_test.py) PYSIDE_TEST(ui_test.py) diff --git a/tests/QtUiTools/bug_426.py b/tests/QtUiTools/bug_426.py new file mode 100644 index 000000000..11e2631fc --- /dev/null +++ b/tests/QtUiTools/bug_426.py @@ -0,0 +1,18 @@ +import sys +import os +from PySide import QtCore, QtGui +from PySide.QtUiTools import QUiLoader + +class Window(object): + def __init__(self): + loader = QUiLoader() + filePath = os.path.join(os.path.dirname(__file__), 'bug_426.ui') + self.widget = loader.load(filePath) + self.group = QtGui.QActionGroup(self.widget) + self.widget.show() + QtCore.QTimer.singleShot(0, self.widget.close) + +if __name__ == "__main__": + app = QtGui.QApplication(sys.argv) + win = Window() + sys.exit(app.exec_()) diff --git a/tests/QtUiTools/bug_426.ui b/tests/QtUiTools/bug_426.ui new file mode 100644 index 000000000..99353cd2b --- /dev/null +++ b/tests/QtUiTools/bug_426.ui @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + </widget> + <resources/> + <connections/> +</ui> |