Skip to content

Commit 30233b7

Browse files
author
florianlink
committed
merged from MeVisLab: fixed wrong reuse of C++ wrappers, added unicode print support to sys.stdout redirection
git-svn-id: https://pythonqt.svn.sourceforge.net/svnroot/pythonqt/trunk@222 ea8d5007-eb21-0410-b261-ccb3ea6e24a9
1 parent cfab2a7 commit 30233b7

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/PythonQt.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,13 @@ PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
344344
return Py_None;
345345
}
346346
PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(obj);
347+
if (wrap && wrap->_wrappedPtr) {
348+
// uh oh, we want to wrap a QObject, but have a C++ wrapper at that
349+
// address, so probably that C++ wrapper has been deleted earlier and
350+
// now we see a QObject with the same address.
351+
// Do not use the old wrapper anymore.
352+
wrap = NULL;
353+
}
347354
if (!wrap) {
348355
// smuggling it in...
349356
PythonQtClassInfo* classInfo = _knownClassInfos.value(obj->metaObject()->className());
@@ -368,6 +375,16 @@ PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
368375
}
369376

370377
PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(ptr);
378+
PythonQtInstanceWrapper* possibleStillAliveWrapper = NULL;
379+
if (wrap && wrap->_wrappedPtr) {
380+
// we have a previous C++ wrapper... if the wrapper is for a C++ object,
381+
// we are not sure if it may have been deleted earlier and we just see the same C++
382+
// pointer once again. To make sure that we do not reuse a wrapper of the wrong type,
383+
// we compare the classInfo() pointer and only reuse the wrapper if it has the same
384+
// info. This is only needed for non-QObjects, since we know it when a QObject gets deleted.
385+
possibleStillAliveWrapper = wrap;
386+
wrap = NULL;
387+
}
371388
if (!wrap) {
372389
PythonQtClassInfo* info = _knownClassInfos.value(name);
373390
if (!info) {
@@ -378,7 +395,7 @@ PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
378395
return p;
379396
}
380397

381-
// we do not know the metaobject yet, but we might know it by it's name:
398+
// we do not know the metaobject yet, but we might know it by its name:
382399
if (_knownQObjectClassNames.find(name)!=_knownQObjectClassNames.end()) {
383400
// yes, we know it, so we can convert to QObject
384401
QObject* qptr = (QObject*)ptr;
@@ -445,7 +462,12 @@ PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
445462
info->setMetaObject(wrapper->metaObject());
446463
}
447464

448-
wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
465+
if (possibleStillAliveWrapper && possibleStillAliveWrapper->classInfo() == info) {
466+
wrap = possibleStillAliveWrapper;
467+
Py_INCREF(wrap);
468+
} else {
469+
wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
470+
}
449471
// mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
450472
} else {
451473
Py_INCREF(wrap);

src/PythonQtStdOut.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,32 @@ static PyObject *PythonQtStdOutRedirect_write(PyObject *self, PyObject *args)
5656
{
5757
PythonQtStdOutRedirect* s = (PythonQtStdOutRedirect*)self;
5858
if (s->_cb) {
59-
char *string;
60-
if (!PyArg_ParseTuple(args, "s", &string))
61-
return NULL;
59+
QString output;
60+
if (PyTuple_GET_SIZE(args)>=1) {
61+
PyObject* obj = PyTuple_GET_ITEM(args,0);
62+
if (PyUnicode_Check(obj)) {
63+
PyObject *tmp = PyUnicode_AsUTF8String(obj);
64+
if(tmp) {
65+
output = QString::fromUtf8(PyString_AS_STRING(tmp));
66+
Py_DECREF(tmp);
67+
} else {
68+
return NULL;
69+
}
70+
} else {
71+
char *string;
72+
if (!PyArg_ParseTuple(args, "s", &string)) {
73+
return NULL;
74+
}
75+
output = QString::fromLatin1(string);
76+
}
77+
}
6278

6379
if (s->softspace > 0) {
6480
(*s->_cb)(QString(""));
6581
s->softspace = 0;
6682
}
6783

68-
(*s->_cb)(QString(string));
84+
(*s->_cb)(output);
6985
}
7086
return Py_BuildValue("");
7187
}

0 commit comments

Comments
 (0)