diff options
-rw-r--r-- | PySide/QtGui/glue/qlayout_help_functions.h | 28 | ||||
-rw-r--r-- | PySide/QtGui/glue/qwidget_glue.h | 10 | ||||
-rw-r--r-- | tests/QtGui/qlayout_ref_test.py | 2 | ||||
-rw-r--r-- | tests/QtGui/qlayout_test.py | 31 |
4 files changed, 60 insertions, 11 deletions
diff --git a/PySide/QtGui/glue/qlayout_help_functions.h b/PySide/QtGui/glue/qlayout_help_functions.h index cea0b5611..9e07ff5d3 100644 --- a/PySide/QtGui/glue/qlayout_help_functions.h +++ b/PySide/QtGui/glue/qlayout_help_functions.h @@ -3,24 +3,40 @@ void addLayoutOwnership(QLayout *layout, QLayoutItem *item); +inline QString retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return QString(PyString_AsString(objName)); +} + inline void addLayoutOwnership(QLayout *layout, QWidget *widget) { //transfer ownership to parent widget QWidget *parent = layout->parentWidget(); - if (!parent) - return; - Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(parent)); - Shiboken::AutoDecRef pyChild(Shiboken::Converter<QWidget*>::toPython(widget)); - Shiboken::setParent(pyParent, pyChild); + if (!parent) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(layout)); + Shiboken::AutoDecRef pyChild(Shiboken::Converter<QWidget*>::toPython(widget)); + Shiboken::keepReference(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyParent.object()), qPrintable(retrieveObjectName(pyParent)), pyChild, true); + } else { + Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(parent)); + Shiboken::AutoDecRef pyChild(Shiboken::Converter<QWidget*>::toPython(widget)); + Shiboken::setParent(pyParent, pyChild); + } } inline void addLayoutOwnership(QLayout *layout, QLayout *other) { //transfer all children widgetes from other to layout parent widget QWidget *parent = layout->parentWidget(); - if (!parent) + if (!parent) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(Shiboken::Converter<QLayout*>::toPython(layout)); + Shiboken::AutoDecRef pyChild(Shiboken::Converter<QLayout*>::toPython(other)); + Shiboken::keepReference(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyParent.object()), qPrintable(retrieveObjectName(pyParent)), pyChild, true); return; + } for (int i=0, i_max=other->count(); i < i_max; i++) { addLayoutOwnership(layout, other->itemAt(i)); diff --git a/PySide/QtGui/glue/qwidget_glue.h b/PySide/QtGui/glue/qwidget_glue.h index a6cd3b7d4..948852240 100644 --- a/PySide/QtGui/glue/qwidget_glue.h +++ b/PySide/QtGui/glue/qwidget_glue.h @@ -1,3 +1,10 @@ +static QString retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return QString(PyString_AsString(objName)); +} + + /** * Tranfer objects ownership from layout to widget **/ @@ -26,6 +33,9 @@ qwidgetReparentLayout(QWidget *parent, QLayout *layout) Shiboken::AutoDecRef pyChild(Shiboken::Converter<QLayout*>::toPython(layout)); Shiboken::setParent(pyParent, pyChild); + + //remove previous references + Shiboken::keepReference(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None); } static inline void diff --git a/tests/QtGui/qlayout_ref_test.py b/tests/QtGui/qlayout_ref_test.py index a6342718d..27c599c70 100644 --- a/tests/QtGui/qlayout_ref_test.py +++ b/tests/QtGui/qlayout_ref_test.py @@ -46,7 +46,7 @@ class SaveReference(UsesQApplication): l = QHBoxLayout() self.assertEqual(getrefcount(self.widget1), 2) l.addWidget(self.widget1) - self.assertEqual(getrefcount(self.widget1), 2) + self.assertEqual(getrefcount(self.widget1), 3) w = QWidget() w.setLayout(l) diff --git a/tests/QtGui/qlayout_test.py b/tests/QtGui/qlayout_test.py index ae773bb0a..88c37aa4d 100644 --- a/tests/QtGui/qlayout_test.py +++ b/tests/QtGui/qlayout_test.py @@ -2,7 +2,7 @@ import unittest import sys from helper import UsesQApplication -from PySide.QtGui import QLayout, QWidget, QPushButton, QWidgetItem +from PySide.QtGui import QLayout, QWidget, QPushButton, QWidgetItem, QHBoxLayout class MyLayout(QLayout): def __init__(self, parent=None): @@ -29,24 +29,47 @@ class MyLayout(QLayout): -#Test if a layout implemented in python, the QWidget.setLayout works -#fine because this implement som layout functions used in glue code of +#Test if a layout implemented in python, the QWidget.setLayout works +#fine because this implement som layout functions used in glue code of #QWidget, then in c++ when call a virtual function this need call the QLayout #function implemented in python class QLayoutTest(UsesQApplication): - def testOwnershipTransfer(self): b = QPushButton("teste") l = MyLayout() + l.addWidget(b) self.assertEqual(sys.getrefcount(b), 2) w = QWidget() + + #transfer ref + w.setLayout(l) + + self.assertEqual(sys.getrefcount(b), 3) + + + def testReferenceTransfer(self): + b = QPushButton("teste") + l = QHBoxLayout() + + # keep ref + l.addWidget(b) + self.assertEqual(sys.getrefcount(b), 3) + + w = QWidget() + + # transfer ref w.setLayout(l) self.assertEqual(sys.getrefcount(b), 3) + # release ref + del w + + self.assertEqual(sys.getrefcount(b), 2) + if __name__ == '__main__': unittest.main() |