Fix bug 913 - "Widgets inside QTabWidget are not exported as members of the containing widget"
Reviewer: Marcelo Lira <marcelo.lira@openbossa.org>
Renato Araújo <renato.filho@openbossa.org>
This commit is contained in:
parent
7d364bde65
commit
f3d69f65d1
6 changed files with 121 additions and 57 deletions
|
|
@ -5,73 +5,56 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <shiboken.h>
|
#include <shiboken.h>
|
||||||
|
#include <QUiLoader>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
static void
|
static void createChildrenNameAttributes(PyObject* root, QObject* object)
|
||||||
_populate_parent(PyObject* pyParent, QObject *parent)
|
|
||||||
{
|
{
|
||||||
if (parent->children().isEmpty())
|
foreach (QObject* child, object->children()) {
|
||||||
return;
|
const QByteArray name = child->objectName().toLocal8Bit();
|
||||||
|
|
||||||
foreach(QObject *child, parent->children()) {
|
|
||||||
QString name(child->objectName());
|
|
||||||
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
|
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
|
||||||
bool has_attr = PyObject_HasAttrString(pyParent, qPrintable(name));
|
bool hasAttr = PyObject_HasAttrString(root, name.constData());
|
||||||
Shiboken::AutoDecRef pyChild(Shiboken::Converter<QObject*>::toPython(child));
|
if (!hasAttr) {
|
||||||
if (!has_attr)
|
Shiboken::AutoDecRef pyChild(Shiboken::Converter<QObject*>::toPython(child));
|
||||||
PyObject_SetAttrString(pyParent, qPrintable(name), pyChild);
|
PyObject_SetAttrString(root, name.constData(), pyChild);
|
||||||
|
}
|
||||||
Shiboken::Object::setParent(pyParent, pyChild);
|
createChildrenNameAttributes(root, child);
|
||||||
_populate_parent(pyChild, qobject_cast<QObject*>(child));
|
|
||||||
}
|
}
|
||||||
|
createChildrenNameAttributes(root, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject* QUiLoadedLoadUiFromDevice(QUiLoader* self, QIODevice* dev, QWidget* parent)
|
||||||
quiloader_load_ui_from_device(QUiLoader* self, QIODevice* dev, QWidget *parent)
|
|
||||||
{
|
{
|
||||||
QWidget *w = self->load(dev, parent);
|
QWidget* wdg = self->load(dev, parent);
|
||||||
if (w) {
|
|
||||||
QObject* _parent = parent;
|
|
||||||
if (!_parent)
|
|
||||||
_parent = w;
|
|
||||||
|
|
||||||
if (parent && parent->layout())
|
if (wdg) {
|
||||||
|
PyObject* pyWdg = Shiboken::Converter<QWidget*>::toPython(wdg);
|
||||||
|
|
||||||
|
if (!parent)
|
||||||
|
parent = wdg;
|
||||||
|
|
||||||
|
if (parent->layout())
|
||||||
parent->layout()->deleteLater();
|
parent->layout()->deleteLater();
|
||||||
|
|
||||||
PyObject* pyParent = Shiboken::Converter<QWidget*>::toPython(w);
|
createChildrenNameAttributes(pyWdg, wdg);
|
||||||
_populate_parent(pyParent, _parent);
|
if (parent) {
|
||||||
|
Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(parent));
|
||||||
return pyParent;
|
Shiboken::Object::setParent(pyParent, pyWdg);
|
||||||
}
|
|
||||||
|
|
||||||
if (!PyErr_Occurred())
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unable to open ui file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject*
|
|
||||||
quiloader_load_ui(QUiLoader* self, const QString &ui_file, QWidget *parent)
|
|
||||||
{
|
|
||||||
QFile fd(ui_file);
|
|
||||||
|
|
||||||
if (fd.exists(ui_file) && fd.open(QFile::ReadOnly)) {
|
|
||||||
QWidget* w = self->load(&fd, parent);
|
|
||||||
fd.close();
|
|
||||||
if (w != 0) {
|
|
||||||
QObject *_parent = parent;
|
|
||||||
if (!_parent)
|
|
||||||
_parent = w;
|
|
||||||
|
|
||||||
Shiboken::AutoDecRef pyParent(Shiboken::Converter<QWidget*>::toPython(_parent));
|
|
||||||
if (parent && parent->layout())
|
|
||||||
parent->layout()->deleteLater();
|
|
||||||
|
|
||||||
_populate_parent(pyParent, _parent);
|
|
||||||
|
|
||||||
return Shiboken::Converter<QWidget*>::toPython(w);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pyWdg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyErr_Occurred())
|
if (!PyErr_Occurred())
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Unable to open ui file");
|
PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiFile, QWidget* parent)
|
||||||
|
{
|
||||||
|
QFile fd(uiFile);
|
||||||
|
return QUiLoadedLoadUiFromDevice(self, &fd, parent);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!--
|
||||||
This file is part of PySide project.
|
This file is part of PySide project.
|
||||||
Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
|
Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
Contact: PySide team <contact@pyside.org>
|
Contact: PySide team <contact@pyside.org>
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
</modify-argument>
|
</modify-argument>
|
||||||
<inject-code>
|
<inject-code>
|
||||||
// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
|
// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
|
||||||
%PYARG_0 = quiloader_load_ui_from_device(%CPPSELF, %1, %2);
|
%PYARG_0 = QUiLoadedLoadUiFromDevice(%CPPSELF, %1, %2);
|
||||||
</inject-code>
|
</inject-code>
|
||||||
</modify-function>
|
</modify-function>
|
||||||
|
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
</modify-argument>
|
</modify-argument>
|
||||||
<inject-code>
|
<inject-code>
|
||||||
// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
|
// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
|
||||||
%PYARG_0 = quiloader_load_ui(%CPPSELF, %1, %2);
|
%PYARG_0 = QUiLoaderLoadUiFromFileName(%CPPSELF, %1, %2);
|
||||||
</inject-code>
|
</inject-code>
|
||||||
</add-function>
|
</add-function>
|
||||||
</object-type>
|
</object-type>
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,6 @@ PYSIDE_TEST(bug_426.py)
|
||||||
PYSIDE_TEST(bug_552.py)
|
PYSIDE_TEST(bug_552.py)
|
||||||
PYSIDE_TEST(bug_797.py)
|
PYSIDE_TEST(bug_797.py)
|
||||||
PYSIDE_TEST(bug_909.py)
|
PYSIDE_TEST(bug_909.py)
|
||||||
|
PYSIDE_TEST(bug_913.py)
|
||||||
PYSIDE_TEST(uiloader_test.py)
|
PYSIDE_TEST(uiloader_test.py)
|
||||||
PYSIDE_TEST(ui_test.py)
|
PYSIDE_TEST(ui_test.py)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class BugTest(UsesQApplication):
|
||||||
|
|
||||||
filePath = os.path.join(os.path.dirname(__file__), 'action.ui')
|
filePath = os.path.join(os.path.dirname(__file__), 'action.ui')
|
||||||
result = loader.load(filePath, w)
|
result = loader.load(filePath, w)
|
||||||
self.assert_(isinstance(result.statusbar.actionFoo, QtGui.QAction))
|
self.assert_(isinstance(result.actionFoo, QtGui.QAction))
|
||||||
|
|
||||||
def testPythonCustomWidgets(self):
|
def testPythonCustomWidgets(self):
|
||||||
w = QtGui.QWidget()
|
w = QtGui.QWidget()
|
||||||
|
|
|
||||||
23
tests/QtUiTools/bug_913.py
Normal file
23
tests/QtUiTools/bug_913.py
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from helper import adjust_filename
|
||||||
|
|
||||||
|
from PySide.QtCore import *
|
||||||
|
from PySide.QtGui import *
|
||||||
|
from PySide.QtUiTools import *
|
||||||
|
|
||||||
|
class TestBug913 (unittest.TestCase):
|
||||||
|
|
||||||
|
def testIt(self):
|
||||||
|
app = QApplication([])
|
||||||
|
|
||||||
|
loader = QUiLoader()
|
||||||
|
widget = loader.load(adjust_filename('bug_913.ui', __file__))
|
||||||
|
widget.tabWidget.currentIndex() # direct child is available as member
|
||||||
|
widget.le_first.setText('foo') # child of QTabWidget must also be available!
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
57
tests/QtUiTools/bug_913.ui
Normal file
57
tests/QtUiTools/bug_913.ui
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 1</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>First name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="le_first"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Last name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="le_last"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Tab 2</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue