Fixed layout reference control on layouts.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
parent
975edd5647
commit
5cc46f2f13
4 changed files with 60 additions and 11 deletions
|
|
@ -3,24 +3,40 @@
|
||||||
|
|
||||||
void addLayoutOwnership(QLayout *layout, QLayoutItem *item);
|
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)
|
inline void addLayoutOwnership(QLayout *layout, QWidget *widget)
|
||||||
{
|
{
|
||||||
//transfer ownership to parent widget
|
//transfer ownership to parent widget
|
||||||
QWidget *parent = layout->parentWidget();
|
QWidget *parent = layout->parentWidget();
|
||||||
if (!parent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(parent));
|
if (!parent) {
|
||||||
Shiboken::AutoDecRef pyChild(Shiboken::Converter<QWidget*>::toPython(widget));
|
//keep the reference while the layout is orphan
|
||||||
Shiboken::setParent(pyParent, pyChild);
|
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)
|
inline void addLayoutOwnership(QLayout *layout, QLayout *other)
|
||||||
{
|
{
|
||||||
//transfer all children widgetes from other to layout parent widget
|
//transfer all children widgetes from other to layout parent widget
|
||||||
QWidget *parent = layout->parentWidget();
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0, i_max=other->count(); i < i_max; i++) {
|
for (int i=0, i_max=other->count(); i < i_max; i++) {
|
||||||
addLayoutOwnership(layout, other->itemAt(i));
|
addLayoutOwnership(layout, other->itemAt(i));
|
||||||
|
|
|
||||||
|
|
@ -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
|
* 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::AutoDecRef pyChild(Shiboken::Converter<QLayout*>::toPython(layout));
|
||||||
Shiboken::setParent(pyParent, pyChild);
|
Shiboken::setParent(pyParent, pyChild);
|
||||||
|
|
||||||
|
//remove previous references
|
||||||
|
Shiboken::keepReference(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class SaveReference(UsesQApplication):
|
||||||
l = QHBoxLayout()
|
l = QHBoxLayout()
|
||||||
self.assertEqual(getrefcount(self.widget1), 2)
|
self.assertEqual(getrefcount(self.widget1), 2)
|
||||||
l.addWidget(self.widget1)
|
l.addWidget(self.widget1)
|
||||||
self.assertEqual(getrefcount(self.widget1), 2)
|
self.assertEqual(getrefcount(self.widget1), 3)
|
||||||
|
|
||||||
w = QWidget()
|
w = QWidget()
|
||||||
w.setLayout(l)
|
w.setLayout(l)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import unittest
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from helper import UsesQApplication
|
from helper import UsesQApplication
|
||||||
from PySide.QtGui import QLayout, QWidget, QPushButton, QWidgetItem
|
from PySide.QtGui import QLayout, QWidget, QPushButton, QWidgetItem, QHBoxLayout
|
||||||
|
|
||||||
class MyLayout(QLayout):
|
class MyLayout(QLayout):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
|
@ -29,24 +29,47 @@ class MyLayout(QLayout):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Test if a layout implemented in python, the QWidget.setLayout works
|
#Test if a layout implemented in python, the QWidget.setLayout works
|
||||||
#fine because this implement som layout functions used in glue code of
|
#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
|
#QWidget, then in c++ when call a virtual function this need call the QLayout
|
||||||
#function implemented in python
|
#function implemented in python
|
||||||
|
|
||||||
class QLayoutTest(UsesQApplication):
|
class QLayoutTest(UsesQApplication):
|
||||||
|
|
||||||
def testOwnershipTransfer(self):
|
def testOwnershipTransfer(self):
|
||||||
b = QPushButton("teste")
|
b = QPushButton("teste")
|
||||||
l = MyLayout()
|
l = MyLayout()
|
||||||
|
|
||||||
l.addWidget(b)
|
l.addWidget(b)
|
||||||
|
|
||||||
self.assertEqual(sys.getrefcount(b), 2)
|
self.assertEqual(sys.getrefcount(b), 2)
|
||||||
|
|
||||||
w = QWidget()
|
w = QWidget()
|
||||||
|
|
||||||
|
#transfer ref
|
||||||
w.setLayout(l)
|
w.setLayout(l)
|
||||||
|
|
||||||
self.assertEqual(sys.getrefcount(b), 3)
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue