aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2010-07-09 18:27:39 -0300
committerRenato Filho <renato.filho@openbossa.org>2010-07-09 19:27:35 -0300
commit5cc46f2f1342e085897eefd06eda453e2f28b5bc (patch)
treefa8b36cc14ae4fa5e356cdebd3b387c8643452ce
parent975edd5647f7fcebe9381ccf7d0524c736b1d069 (diff)
Fixed layout reference control on layouts.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r--PySide/QtGui/glue/qlayout_help_functions.h28
-rw-r--r--PySide/QtGui/glue/qwidget_glue.h10
-rw-r--r--tests/QtGui/qlayout_ref_test.py2
-rw-r--r--tests/QtGui/qlayout_test.py31
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()