Fixed Qt application cleanup.

Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
          Hugo Parente Lima <hugo.pl@gmail.com>
This commit is contained in:
Renato Filho 2010-08-24 17:14:40 -03:00
commit 42d98f91c4
4 changed files with 60 additions and 24 deletions

View file

@ -1,21 +1,30 @@
// Global variables used to store argc and argv values // Global variables used to store argc and argv values
static int QCoreApplicationArgCount; static int QCoreApplicationArgCount;
static char** QCoreApplicationArgValues; static char** QCoreApplicationArgValues;
static bool leavingPython = false;
/** /**
* Called at QtCore module exit * Called at QtCore module exit
*/ */
void DeleteQCoreApplicationAtExit() { void DeleteQCoreApplicationAtExit()
if (QCoreApplication::instance()) { {
BindingManager::instance().invalidateWrapper(QCoreApplication::instance()); leavingPython = true;
QCoreApplication::instance()->deleteLater(); QCoreApplication *cpp = QCoreApplication::instance();
for (int i = 0; i < QCoreApplicationArgCount; ++i) if (cpp) {
delete[] QCoreApplicationArgValues[i]; Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
PyObject* pySelf = bmngr.retrieveWrapper(cpp);
if (pySelf)
bmngr.invalidateWrapper(pySelf);
cpp->deleteLater();
} }
} }
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 >()))
return -1;
if (QCoreApplication::instance()) { if (QCoreApplication::instance()) {
PyErr_SetString(PyExc_RuntimeError, "A QCoreApplication instance already exists."); PyErr_SetString(PyExc_RuntimeError, "A QCoreApplication instance already exists.");
return -1; return -1;
@ -32,14 +41,20 @@ int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*)
return -1; return -1;
} }
void* cptr = new QCoreApplication(QCoreApplicationArgCount, QCoreApplicationArgValues); QCoreApplicationWrapper* cptr = new QCoreApplicationWrapper(QCoreApplicationArgCount, QCoreApplicationArgValues);
Shiboken::setCppPointer(reinterpret_cast<SbkBaseWrapper*>(self), Shiboken::setCppPointer(reinterpret_cast<SbkBaseWrapper*>(self),
Shiboken::SbkType<QCoreApplication>(), Shiboken::SbkType<QCoreApplication>(),
cptr); cptr);
SbkBaseWrapper_setValidCppObject(self, 1);
Shiboken::BindingManager::instance().registerWrapper(reinterpret_cast<SbkBaseWrapper*>(self), cptr);
Py_INCREF(self); SbkBaseWrapper_setValidCppObject(self, 1);
SbkBaseWrapper *sbkSelf = reinterpret_cast<SbkBaseWrapper*>(self);
sbkSelf->containsCppWrapper = 1;
sbkSelf->hasOwnership = 0;
Shiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);
PySide::signalUpdateSource(self);
cptr->metaObject();
Py_AtExit(DeleteQCoreApplicationAtExit); Py_AtExit(DeleteQCoreApplicationAtExit);
Py_INCREF(self);
return 1; return 1;
} }

View file

@ -1762,6 +1762,7 @@
</modify-function> </modify-function>
</object-type> </object-type>
<object-type name="QSignalMapper" /> <object-type name="QSignalMapper" />
<object-type name="QCoreApplication"> <object-type name="QCoreApplication">
<extra-includes> <extra-includes>
<include file-name="QStringList" location="global"/> <include file-name="QStringList" location="global"/>
@ -1786,16 +1787,26 @@
<modify-function signature="sendEvent(QObject*, QEvent*)" allow-thread="yes"/> <modify-function signature="sendEvent(QObject*, QEvent*)" allow-thread="yes"/>
<modify-function signature="sendPostedEvents(QObject*, int)" allow-thread="yes"/> <modify-function signature="sendPostedEvents(QObject*, int)" allow-thread="yes"/>
<modify-function signature="sendPostedEvents()" allow-thread="yes"/> <modify-function signature="sendPostedEvents()" allow-thread="yes"/>
<modify-function signature="instance()">
<modify-argument index="return">
<define-ownership owner="c++"/>
</modify-argument>
</modify-function>
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
<modify-function signature="argv()" remove="all"/> <modify-function signature="argv()" remove="all"/>
<!-- Obsolete --> <!-- Obsolete -->
<modify-function signature="argc()" remove="all"/> <modify-function signature="argc()" remove="all"/>
<!-- Obsolete --> <!-- Obsolete -->
<modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes"> <modify-function signature="notify(QObject*,QEvent*)">
<inject-code class="shell" position="beginning">
Shiboken::ThreadStateSaver threadStateSaver;
if (!leavingPython)
threadStateSaver.save();
</inject-code>
<modify-argument index="2" invalidate-after-use="yes"/> <modify-argument index="2" invalidate-after-use="yes"/>
</modify-function> </modify-function>
<modify-function signature="QCoreApplication(int &amp;, char **)" remove="all"/> <modify-function signature="QCoreApplication(int &amp;, char **)" access="private"/>
<inject-code class="native" file="glue/qcoreapplication_init.cpp" position="beginning" /> <inject-code class="native" file="glue/qcoreapplication_init.cpp" position="beginning" />
<modify-function signature="postEvent(QObject*,QEvent*)"> <modify-function signature="postEvent(QObject*,QEvent*)">
<modify-argument index="2"> <modify-argument index="2">

View file

@ -3,18 +3,25 @@ extern PyObject* moduleQtGui;
static int QApplicationArgCount; static int QApplicationArgCount;
static char** QApplicationArgValues; static char** QApplicationArgValues;
static const char QAPP_MACRO[] = "qApp";
void DeleteQApplicationAtExit() { void DeleteQApplicationAtExit() {
if (QApplication::instance()) { PySide::SignalManager::instance().clear();
BindingManager::instance().invalidateWrapper(QApplication::instance()); QCoreApplication* cpp = QApplication::instance();
QApplication::instance()->deleteLater(); if (cpp) {
for (int i = 0; i < QApplicationArgCount; ++i) Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
delete[] QApplicationArgValues[i]; PyObject* pySelf = bmngr.retrieveWrapper(cpp);
if (pySelf)
bmngr.invalidateWrapper(pySelf);
cpp->deleteLater();
} }
} }
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 >()))
return -1;
if (QApplication::instance()) { if (QApplication::instance()) {
PyErr_SetString(PyExc_RuntimeError, "A QApplication instance already exists."); PyErr_SetString(PyExc_RuntimeError, "A QApplication instance already exists.");
return -1; return -1;
@ -31,25 +38,28 @@ int SbkQApplication_Init(PyObject* self, PyObject* args, PyObject*)
return -1; return -1;
} }
void* cptr = new QApplication(QApplicationArgCount, QApplicationArgValues); QApplicationWrapper* cptr = new QApplicationWrapper(QApplicationArgCount, QApplicationArgValues);
Shiboken::setCppPointer(reinterpret_cast<SbkBaseWrapper*>(self), Shiboken::setCppPointer(reinterpret_cast<SbkBaseWrapper*>(self),
Shiboken::SbkType<QApplication>(), Shiboken::SbkType<QApplication>(),
cptr); cptr);
SbkBaseWrapper_setValidCppObject(self, 1); SbkBaseWrapper_setValidCppObject(self, 1);
Shiboken::BindingManager::instance().registerWrapper(reinterpret_cast<SbkBaseWrapper*>(self), cptr); SbkBaseWrapper *sbkSelf = reinterpret_cast<SbkBaseWrapper*>(self);
sbkSelf->containsCppWrapper = 1;
sbkSelf->hasOwnership = 0;
Shiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);
PySide::signalUpdateSource(self);
cptr->metaObject();
// Verify if qApp is in main module // Verify if qApp is in main module
const char QAPP_MACRO[] = "qApp";
PyObject* globalsDict = PyEval_GetGlobals(); PyObject* globalsDict = PyEval_GetGlobals();
if (globalsDict) { if (globalsDict) {
PyObject* qAppObj = PyDict_GetItemString(globalsDict, QAPP_MACRO); PyObject* qAppObj = PyDict_GetItemString(globalsDict, QAPP_MACRO);
if (qAppObj) if (qAppObj)
PyDict_SetItemString(globalsDict, QAPP_MACRO, self); PyDict_SetItemString(globalsDict, QAPP_MACRO, self);
} }
PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self); PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self);
Py_INCREF(self);
Py_AtExit(DeleteQApplicationAtExit); Py_AtExit(DeleteQApplicationAtExit);
Py_INCREF(self);
return 1; return 1;
} }

View file

@ -4358,7 +4358,7 @@
<include file-name="QLocale" location="global"/> <include file-name="QLocale" location="global"/>
<include file-name="QStyle" location="global"/> <include file-name="QStyle" location="global"/>
</extra-includes> </extra-includes>
<modify-function signature="QApplication(int &amp;, char **)" remove="all" /> <modify-function signature="QApplication(int &amp;, char **)" access="private" />
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/> <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
<inject-code class="native" file="glue/qapplication_init.cpp" position="beginning" /> <inject-code class="native" file="glue/qapplication_init.cpp" position="beginning" />