Fix bugs 430, 426, 429, 394, 433.
These bugs are about QApplication instance being destroyed before
some QObject.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Renato Araújo <renato.filho@openbossa.org>
This commit is contained in:
parent
800fb4613c
commit
77a1654ad5
11 changed files with 112 additions and 39 deletions
|
|
@ -2,21 +2,6 @@
|
||||||
static int QCoreApplicationArgCount;
|
static int QCoreApplicationArgCount;
|
||||||
static char** QCoreApplicationArgValues;
|
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*)
|
int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*)
|
||||||
{
|
{
|
||||||
if (Shiboken::isUserType(self) && !Shiboken::canCallConstructor(self->ob_type, Shiboken::SbkType<QApplication >()))
|
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);
|
PySide::signalUpdateSource(self);
|
||||||
cptr->metaObject();
|
cptr->metaObject();
|
||||||
|
|
||||||
PySide::registerCleanupFunction(DeleteQCoreApplicationAtExit);
|
PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,28 +5,6 @@ static int QApplicationArgCount;
|
||||||
static char** QApplicationArgValues;
|
static char** QApplicationArgValues;
|
||||||
static const char QAPP_MACRO[] = "qApp";
|
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*)
|
int SbkQApplication_Init(PyObject* self, PyObject* args, PyObject*)
|
||||||
{
|
{
|
||||||
if (Shiboken::isUserType(self) && !Shiboken::canCallConstructor(self->ob_type, Shiboken::SbkType<QApplication >()))
|
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);
|
PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self);
|
||||||
PySide::registerCleanupFunction(DeleteQApplicationAtExit);
|
PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,11 @@
|
||||||
#include "pyside.h"
|
#include "pyside.h"
|
||||||
#include <basewrapper.h>
|
#include <basewrapper.h>
|
||||||
#include <conversions.h>
|
#include <conversions.h>
|
||||||
|
#include <typeresolver.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
|
#include <QCoreApplication>
|
||||||
#include "signalmanager.h"
|
#include "signalmanager.h"
|
||||||
#include "qproperty_p.h"
|
#include "qproperty_p.h"
|
||||||
#include "qproperty.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
|
} //namespace PySide
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,11 @@ typedef void (*CleanupFunction)(void);
|
||||||
PYSIDE_API void registerCleanupFunction(CleanupFunction func);
|
PYSIDE_API void registerCleanupFunction(CleanupFunction func);
|
||||||
PYSIDE_API void runCleanupFunctions();
|
PYSIDE_API void runCleanupFunctions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a QCoreApplication taking care of destroy all instances of QObject first.
|
||||||
|
*/
|
||||||
|
PYSIDE_API void destroyQCoreApplication();
|
||||||
|
|
||||||
} //namespace PySide
|
} //namespace PySide
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ PYSIDE_TEST(bug_367.py)
|
||||||
PYSIDE_TEST(bug_389.py)
|
PYSIDE_TEST(bug_389.py)
|
||||||
PYSIDE_TEST(bug_400.py)
|
PYSIDE_TEST(bug_400.py)
|
||||||
PYSIDE_TEST(bug_416.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(customproxywidget_test.py)
|
||||||
PYSIDE_TEST(deepcopy_test.py)
|
PYSIDE_TEST(deepcopy_test.py)
|
||||||
PYSIDE_TEST(float_to_int_implicit_conversion_test.py)
|
PYSIDE_TEST(float_to_int_implicit_conversion_test.py)
|
||||||
|
|
|
||||||
10
tests/QtGui/bug_429.py
Normal file
10
tests/QtGui/bug_429.py
Normal file
|
|
@ -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_())
|
||||||
14
tests/QtGui/bug_430.py
Normal file
14
tests/QtGui/bug_430.py
Normal file
|
|
@ -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_()
|
||||||
14
tests/QtGui/bug_433.py
Normal file
14
tests/QtGui/bug_433.py
Normal file
|
|
@ -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_())
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
PYSIDE_TEST(bug_360.py)
|
PYSIDE_TEST(bug_360.py)
|
||||||
PYSIDE_TEST(bug_376.py)
|
PYSIDE_TEST(bug_376.py)
|
||||||
PYSIDE_TEST(bug_392.py)
|
PYSIDE_TEST(bug_392.py)
|
||||||
|
PYSIDE_TEST(bug_426.py)
|
||||||
PYSIDE_TEST(uiloader_test.py)
|
PYSIDE_TEST(uiloader_test.py)
|
||||||
PYSIDE_TEST(ui_test.py)
|
PYSIDE_TEST(ui_test.py)
|
||||||
|
|
|
||||||
18
tests/QtUiTools/bug_426.py
Normal file
18
tests/QtUiTools/bug_426.py
Normal file
|
|
@ -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_())
|
||||||
19
tests/QtUiTools/bug_426.ui
Normal file
19
tests/QtUiTools/bug_426.ui
Normal file
|
|
@ -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>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue