Skip to content

Commit 2c6f7fc

Browse files
committed
COMP: Backport from patch-9 slicer
add src/PythonQt_QtBindings.cpp add src/PythonQt_QtBindings.h
1 parent e1b00df commit 2c6f7fc

File tree

4 files changed

+154
-5
lines changed

4 files changed

+154
-5
lines changed

src/PythonQt.cpp

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
258258
PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPen);
259259
PythonQtRegisterToolClassesTemplateConverterForKnownClass(QTextLength);
260260
PythonQtRegisterToolClassesTemplateConverterForKnownClass(QTextFormat);
261+
#if QT_VERSION < 0x060000
262+
PythonQtRegisterToolClassesTemplateConverterForKnownClass(QMatrix);
263+
#endif
261264

262265
PyObject* pack = PythonQt::priv()->packageByName("QtCore");
263266
PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
@@ -321,6 +324,10 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
321324
void PythonQt::cleanup()
322325
{
323326
if (_self) {
327+
// Remove signal handlers in advance, since destroying them calls back into
328+
// PythonQt::priv()->removeSignalEmitter()
329+
_self->removeSignalHandlers();
330+
324331
delete _self;
325332
_self = nullptr;
326333
}
@@ -1548,6 +1555,10 @@ PythonQtClassInfo* PythonQtPrivate::currentClassInfoForClassWrapperCreation()
15481555

15491556
void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
15501557
{
1558+
if (!o)
1559+
{
1560+
return;
1561+
}
15511562
o->setParent(this);
15521563
int numMethods = o->metaObject()->methodCount();
15531564
for (int i = 0; i < numMethods; i++) {
@@ -1841,7 +1852,13 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
18411852
PythonQtObjectPtr sys;
18421853
sys.setNewRef(PyImport_ImportModule("sys"));
18431854

1844-
if (redirectStdOut) {
1855+
if (redirectStdOut)
1856+
{
1857+
// Backup original 'sys.stdout' and 'sys.stderr'
1858+
PyModule_AddObject(sys, "pythonqt_original_stdout", PyObject_GetAttrString(sys, "stdout"));
1859+
PyModule_AddObject(sys, "pythonqt_original_stderr", PyObject_GetAttrString(sys, "stderr"));
1860+
1861+
// Create a redirection object for stdout and stderr
18451862
PythonQtObjectPtr out;
18461863
PythonQtObjectPtr err;
18471864
// create a redirection object for stdout and stderr
@@ -1850,10 +1867,11 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
18501867
err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,nullptr, nullptr);
18511868
((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB;
18521869
// replace the built in file objects with our own objects
1853-
PyModule_AddObject(sys, "stdout", out);
1854-
PyModule_AddObject(sys, "stderr", err);
1855-
}
1870+
PyModule_AddObject(sys, "pythonqt_stdout", out);
1871+
PyModule_AddObject(sys, "pythonqt_stderr", err);
18561872

1873+
setRedirectStdOutCallbackEnabled(redirectStdOut);
1874+
}
18571875
// add PythonQt to the list of builtin module names
18581876
PyObject *old_module_names = PyObject_GetAttrString(sys.object(),"builtin_module_names");
18591877
if (old_module_names && PyTuple_Check(old_module_names)) {
@@ -1876,6 +1894,42 @@ void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQ
18761894
Py_XDECREF(pyUnicodeObject);
18771895
}
18781896

1897+
bool PythonQt::redirectStdOutCallbackEnabled() const
1898+
{
1899+
PythonQtObjectPtr sys;
1900+
sys.setNewRef(PyImport_ImportModule("sys"));
1901+
1902+
PythonQtObjectPtr pythonqt_stdout;
1903+
pythonqt_stdout.setNewRef(PyObject_GetAttrString(sys.object(), "pythonqt_stdout"));
1904+
1905+
PythonQtObjectPtr sys_stdout;
1906+
sys_stdout.setNewRef(PyObject_GetAttrString(sys.object(), "stdout"));
1907+
1908+
return PyObject_RichCompareBool(pythonqt_stdout.object(), sys_stdout.object(), Py_EQ);
1909+
}
1910+
1911+
void PythonQt::setRedirectStdOutCallbackEnabled(bool enabled)
1912+
{
1913+
PythonQtObjectPtr sys;
1914+
sys.setNewRef(PyImport_ImportModule("sys"));
1915+
1916+
if (enabled) {
1917+
if( PyObject_HasAttrString(sys.object(), "pythonqt_stdout") ) {
1918+
PyModule_AddObject(sys.object(), "stdout", PyObject_GetAttrString(sys.object(), "pythonqt_stdout"));
1919+
}
1920+
if( PyObject_HasAttrString(sys.object(), "pythonqt_stderr") ) {
1921+
PyModule_AddObject(sys.object(), "stderr", PyObject_GetAttrString(sys.object(), "pythonqt_stderr"));
1922+
}
1923+
} else {
1924+
if( PyObject_HasAttrString(sys.object(), "pythonqt_original_stdout") ) {
1925+
PyModule_AddObject(sys.object(), "stdout", PyObject_GetAttrString(sys.object(), "pythonqt_original_stdout"));
1926+
}
1927+
if( PyObject_HasAttrString(sys.object(), "pythonqt_original_stderr") ) {
1928+
PyModule_AddObject(sys.object(), "stderr", PyObject_GetAttrString(sys.object(), "pythonqt_original_stderr"));
1929+
}
1930+
}
1931+
}
1932+
18791933
QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString& name)
18801934
{
18811935
QStringList tmp = name.split(".");

src/PythonQt.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,18 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
262262

263263
//@}
264264

265+
//---------------------------------------------------------------------------
266+
//! \name Standard output handling
267+
//@{
268+
269+
//! return \a true if std out/err redirection is enabled.
270+
bool redirectStdOutCallbackEnabled() const;
271+
272+
//! enable or disable std out/err redirection to pythonStdOut() and pythonStdErr() signals.
273+
void setRedirectStdOutCallbackEnabled(bool enabled);
274+
275+
//@}
276+
265277
//---------------------------------------------------------------------------
266278
//! \name Modules
267279
//@{
@@ -548,7 +560,7 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
548560
//@{
549561

550562
//! get access to internal data (should not be used on the public API, but is used by some C functions)
551-
static PythonQtPrivate* priv() { return _self->_p; }
563+
static PythonQtPrivate* priv() { return _self ? _self->_p : NULL; }
552564

553565
//! clear all NotFound entries on all class infos, to ensure that
554566
//! newly loaded wrappers can add methods even when the object was wrapped by PythonQt before the wrapper was loaded

src/PythonQt_QtBindings.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
2+
#include "PythonQt_QtBindings.h"
3+
4+
#include "PythonQt.h"
5+
6+
void PythonQt_init_QtGui(PyObject*);
7+
void PythonQt_init_QtSvg(PyObject*);
8+
void PythonQt_init_QtSql(PyObject*);
9+
void PythonQt_init_QtNetwork(PyObject*);
10+
void PythonQt_init_QtCore(PyObject*);
11+
void PythonQt_init_QtWebKit(PyObject*);
12+
void PythonQt_init_QtOpenGL(PyObject*);
13+
void PythonQt_init_QtQml(PyObject*);
14+
void PythonQt_init_QtQuick(PyObject*);
15+
void PythonQt_init_QtXml(PyObject*);
16+
void PythonQt_init_QtXmlPatterns(PyObject*);
17+
void PythonQt_init_QtUiTools(PyObject*);
18+
void PythonQt_init_QtMultimedia(PyObject*);
19+
20+
PYTHONQT_EXPORT void PythonQt_init_QtBindings()
21+
{
22+
#ifdef PYTHONQT_WRAP_Qtcore
23+
PythonQt_init_QtCore(0);
24+
#endif
25+
26+
#ifdef PYTHONQT_WRAP_Qtgui
27+
PythonQt_init_QtGui(0);
28+
#endif
29+
30+
#ifdef PYTHONQT_WRAP_Qtnetwork
31+
PythonQt_init_QtNetwork(0);
32+
#endif
33+
34+
#ifdef PYTHONQT_WRAP_Qtopengl
35+
PythonQt_init_QtOpenGL(0);
36+
#endif
37+
38+
#ifdef PYTHONQT_WRAP_Qtqml
39+
PythonQt_init_QtQml(0);
40+
#endif
41+
42+
#ifdef PYTHONQT_WRAP_Qtquick
43+
PythonQt_init_QtQuick(0);
44+
#endif
45+
46+
#ifdef PYTHONQT_WRAP_Qtsql
47+
PythonQt_init_QtSql(0);
48+
#endif
49+
50+
#ifdef PYTHONQT_WRAP_Qtsvg
51+
PythonQt_init_QtSvg(0);
52+
#endif
53+
54+
#ifdef PYTHONQT_WRAP_Qtuitools
55+
PythonQt_init_QtUiTools(0);
56+
#endif
57+
58+
#ifdef PYTHONQT_WRAP_Qtmultimedia
59+
PythonQt_init_QtMultimedia(0);
60+
#endif
61+
62+
#ifdef PYTHONQT_WRAP_Qtwebkit
63+
PythonQt_init_QtWebKit(0);
64+
#endif
65+
66+
#ifdef PYTHONQT_WRAP_Qtxml
67+
PythonQt_init_QtXml(0);
68+
#endif
69+
70+
#ifdef PYTHONQT_WRAP_Qtxmlpatterns
71+
PythonQt_init_QtXmlPatterns(0);
72+
#endif
73+
};

src/PythonQt_QtBindings.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _PYTHONQT_QTBINDINGS_H
2+
#define _PYTHONQT_QTBINDINGS_H
3+
4+
#include "PythonQtSystem.h"
5+
6+
/// Initialize Qt bindings enabled at configuration time
7+
PYTHONQT_EXPORT void PythonQt_init_QtBindings();
8+
9+
#endif
10+

0 commit comments

Comments
 (0)