Created PySide cleanup functions used to register functions to be called before the python die.
Reviewer: Hugo Parente Lima <hugo.pl@gmail.com>
Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
parent
b8436f6b1e
commit
6974551674
6 changed files with 59 additions and 20 deletions
|
|
@ -1,21 +1,20 @@
|
||||||
// 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()
|
||||||
{
|
{
|
||||||
leavingPython = true;
|
|
||||||
QCoreApplication *cpp = QCoreApplication::instance();
|
QCoreApplication *cpp = QCoreApplication::instance();
|
||||||
if (cpp) {
|
if (cpp) {
|
||||||
Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
|
Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
|
||||||
PyObject* pySelf = bmngr.retrieveWrapper(cpp);
|
PyObject* pySelf = bmngr.retrieveWrapper(cpp);
|
||||||
if (pySelf)
|
cpp->flush();
|
||||||
bmngr.invalidateWrapper(pySelf);
|
QCoreApplication::processEvents();
|
||||||
cpp->deleteLater();
|
bmngr.invalidateWrapper(pySelf);
|
||||||
|
delete cpp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +53,7 @@ int SbkQCoreApplication_Init(PyObject* self, PyObject* args, PyObject*)
|
||||||
PySide::signalUpdateSource(self);
|
PySide::signalUpdateSource(self);
|
||||||
cptr->metaObject();
|
cptr->metaObject();
|
||||||
|
|
||||||
Py_AtExit(DeleteQCoreApplicationAtExit);
|
PySide::registerCleanupFunction(DeleteQCoreApplicationAtExit);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -552,8 +552,8 @@
|
||||||
</inject-code>
|
</inject-code>
|
||||||
|
|
||||||
<add-function signature="__moduleShutdown()">
|
<add-function signature="__moduleShutdown()">
|
||||||
<inject-code class="target" position="beginning">
|
<inject-code class="target" position="beginning">
|
||||||
PySide::SignalManager::instance().clear();
|
PySide::runCleanupFunctions();
|
||||||
</inject-code>
|
</inject-code>
|
||||||
</add-function>
|
</add-function>
|
||||||
|
|
||||||
|
|
@ -1875,12 +1875,7 @@
|
||||||
<!-- Obsolete -->
|
<!-- Obsolete -->
|
||||||
<modify-function signature="argc()" remove="all"/>
|
<modify-function signature="argc()" remove="all"/>
|
||||||
<!-- Obsolete -->
|
<!-- Obsolete -->
|
||||||
<modify-function signature="notify(QObject*,QEvent*)">
|
<modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes">
|
||||||
<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 &, char **)" access="private"/>
|
<modify-function signature="QCoreApplication(int &, char **)" access="private"/>
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,29 @@ extern PyObject* moduleQtGui;
|
||||||
static int QApplicationArgCount;
|
static int QApplicationArgCount;
|
||||||
static char** QApplicationArgValues;
|
static char** QApplicationArgValues;
|
||||||
static const char QAPP_MACRO[] = "qApp";
|
static const char QAPP_MACRO[] = "qApp";
|
||||||
static bool leavingPython = false;
|
|
||||||
|
|
||||||
void DeleteQApplicationAtExit()
|
void DeleteQApplicationAtExit()
|
||||||
{
|
{
|
||||||
leavingPython = true;
|
|
||||||
PySide::SignalManager::instance().clear();
|
PySide::SignalManager::instance().clear();
|
||||||
QCoreApplication* cpp = QApplication::instance();
|
QCoreApplication* cpp = QApplication::instance();
|
||||||
if (cpp) {
|
if (cpp) {
|
||||||
Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
|
Shiboken::BindingManager &bmngr = Shiboken::BindingManager::instance();
|
||||||
PyObject* pySelf = bmngr.retrieveWrapper(cpp);
|
cpp->flush();
|
||||||
if (pySelf)
|
|
||||||
|
// 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);
|
bmngr.invalidateWrapper(pySelf);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* pySelf = bmngr.retrieveWrapper(cpp);
|
||||||
cpp->deleteLater();
|
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);
|
PyObject_SetAttrString(moduleQtGui, QAPP_MACRO, self);
|
||||||
Py_AtExit(DeleteQApplicationAtExit);
|
PySide::registerCleanupFunction(DeleteQApplicationAtExit);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,22 @@
|
||||||
#include "pyside.h"
|
#include "pyside.h"
|
||||||
#include "signalmanager.h"
|
#include "signalmanager.h"
|
||||||
#include "qproperty.h"
|
#include "qproperty.h"
|
||||||
|
#include "qsignal.h"
|
||||||
#include <basewrapper.h>
|
#include <basewrapper.h>
|
||||||
#include <conversions.h>
|
#include <conversions.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "qsignal.h"
|
#include <QStack>
|
||||||
|
|
||||||
extern "C" void init_signal(PyObject* module);
|
extern "C" void init_signal(PyObject* module);
|
||||||
extern "C" void init_slot(PyObject* module);
|
extern "C" void init_slot(PyObject* module);
|
||||||
extern "C" void init_qproperty(PyObject* module);
|
extern "C" void init_qproperty(PyObject* module);
|
||||||
|
|
||||||
|
static QStack<PySide::CleanupFunction> cleanupFunctionList;
|
||||||
|
|
||||||
namespace PySide
|
namespace PySide
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
void init(PyObject *module)
|
void init(PyObject *module)
|
||||||
{
|
{
|
||||||
init_signal(module);
|
init_signal(module);
|
||||||
|
|
@ -82,5 +86,20 @@ bool fillQtProperties(PyObject* qObj, const QMetaObject* metaObj, PyObject* kwds
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void registerCleanupFunction(CleanupFunction func)
|
||||||
|
{
|
||||||
|
cleanupFunctionList.push(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void runCleanupFunctions()
|
||||||
|
{
|
||||||
|
while (!cleanupFunctionList.isEmpty()) {
|
||||||
|
CleanupFunction f = cleanupFunctionList.pop();
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace PySide
|
} //namespace PySide
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,15 @@ template<typename T>
|
||||||
struct initQtMetaType<T, false> {
|
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
|
} //namespace PySide
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "signalmanager.h"
|
#include "signalmanager.h"
|
||||||
#include "qproperty.h"
|
#include "qproperty.h"
|
||||||
|
#include "pyside.h"
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
@ -223,6 +224,11 @@ struct SignalManager::SignalManagerPrivate
|
||||||
GlobalReceiver m_globalReceiver;
|
GlobalReceiver m_globalReceiver;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void clearSignalManager()
|
||||||
|
{
|
||||||
|
PySide::SignalManager::instance().clear();
|
||||||
|
}
|
||||||
|
|
||||||
SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
|
SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
|
||||||
{
|
{
|
||||||
// Register Qt primitive typedefs used on signals.
|
// 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>(PYTHON_TYPE);
|
||||||
TypeResolver::createValueTypeResolver<PyObjectWrapper>("object");
|
TypeResolver::createValueTypeResolver<PyObjectWrapper>("object");
|
||||||
TypeResolver::createValueTypeResolver<PyObjectWrapper>("PySide::PyObjectWrapper");
|
TypeResolver::createValueTypeResolver<PyObjectWrapper>("PySide::PyObjectWrapper");
|
||||||
|
PySide::registerCleanupFunction(clearSignalManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalManager::clear()
|
void SignalManager::clear()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue