diff options
author | Paulo Alcantara <pcacjr@zytor.com> | 2012-02-27 23:16:16 -0300 |
---|---|---|
committer | Paulo Alcantara <pcacjr@zytor.com> | 2012-02-27 23:26:14 -0300 |
commit | 3f779b8307ebf4b6bdfbe777f41d76ce4ca25151 (patch) | |
tree | 184629fd744505fd54bddab51f80c7a17dc4a2b9 | |
parent | cbd3075fffa95bb9c195f90698533c8d906edaab (diff) | |
download | pyside-bug1135.tar.gz pyside-bug1135.tar.xz pyside-bug1135.zip |
Fix BUG #1135 - "SIGSEGV when loading custom widget using QUiLoader..."bug1135
As PyCustomWidget::createWidget()'s caller is a thread which calls
the PyObject_CallObject() function it needs _exclusive_ access to the
Python interpreter so that a Shiboken::Gilstate is needed in order to
make it thread-safe and avoiding that other threads call the interpreter
at the same time.
See http://bugs.pyside.org/show_bug.cgi?id=1135.
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
-rw-r--r-- | plugins/customwidget.cpp | 13 | ||||
-rw-r--r-- | plugins/customwidget.h | 8 | ||||
-rw-r--r-- | tests/QtUiTools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/QtUiTools/bug_1135.py | 29 | ||||
-rw-r--r-- | tests/QtUiTools/bug_1135.ui | 65 |
5 files changed, 106 insertions, 10 deletions
diff --git a/plugins/customwidget.cpp b/plugins/customwidget.cpp index d573ef4..1098ebf 100644 --- a/plugins/customwidget.cpp +++ b/plugins/customwidget.cpp @@ -1,7 +1,7 @@ /* * This file is part of the PySide project. * - * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2009-2012 Nokia Corporation and/or its subsidiary(-ies). * * Contact: PySide team <contact@pyside.org> * @@ -17,10 +17,9 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "customwidget.h" #include <shiboken.h> @@ -90,7 +89,7 @@ QString PyCustomWidget::whatsThis() const QWidget* PyCustomWidget::createWidget(QWidget* parent) { - //Create a python instance and return cpp object + // Create a python instance and return cpp object PyObject* pyParent; bool unkowParent = false; if (parent) { @@ -108,9 +107,11 @@ QWidget* PyCustomWidget::createWidget(QWidget* parent) } Shiboken::AutoDecRef pyArgs(PyTuple_New(1)); - PyTuple_SET_ITEM(pyArgs, 0, pyParent); //tuple will keep pyParent reference + PyTuple_SET_ITEM(pyArgs, 0, pyParent); // this tuple will keep pyParent reference + + Shiboken::GilState gil; - //Call python constructor + // Call python constructor SbkObject* result = reinterpret_cast<SbkObject*>(PyObject_CallObject(m_data->pyObject, pyArgs)); QWidget* widget = 0; diff --git a/plugins/customwidget.h b/plugins/customwidget.h index 2f26363..72097eb 100644 --- a/plugins/customwidget.h +++ b/plugins/customwidget.h @@ -1,7 +1,7 @@ /* * This file is part of the PySide project. * - * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2009-2012 Nokia Corporation and/or its subsidiary(-ies). * * Contact: PySide team <contact@pyside.org> * @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PY_CUSTOM_WIDGET_H_ @@ -47,8 +47,8 @@ public: QString name() const; QString toolTip() const; QString whatsThis() const; - QWidget *createWidget(QWidget *parent); - void initialize(QDesignerFormEditorInterface *core); + QWidget* createWidget(QWidget* parent); + void initialize(QDesignerFormEditorInterface* core); private: PyCustomWidgetPrivate* m_data; diff --git a/tests/QtUiTools/CMakeLists.txt b/tests/QtUiTools/CMakeLists.txt index 39e2e94..f187581 100644 --- a/tests/QtUiTools/CMakeLists.txt +++ b/tests/QtUiTools/CMakeLists.txt @@ -9,6 +9,7 @@ PYSIDE_TEST(bug_913.py) PYSIDE_TEST(bug_958.py) PYSIDE_TEST(bug_965.py) PYSIDE_TEST(bug_1060.py) +PYSIDE_TEST(bug_1135.py) PYSIDE_TEST(bug_1138.py) PYSIDE_TEST(uiloader_test.py) PYSIDE_TEST(ui_test.py) diff --git a/tests/QtUiTools/bug_1135.py b/tests/QtUiTools/bug_1135.py new file mode 100644 index 0000000..4a82413 --- /dev/null +++ b/tests/QtUiTools/bug_1135.py @@ -0,0 +1,29 @@ +''' unit test for BUG #1135 ''' +''' see http://bugs.pyside.org/show_bug.cgi?id=1135 ''' + +from PySide.QtCore import * +from PySide.QtGui import * +from PySide.QtUiTools import QUiLoader +from helper import adjust_filename + +class CustomWidget(QFrame): + def __init__(self, parent=None): + super(CustomWidget, self).__init__(parent) + self.layout = QVBoxLayout() + self.label = QLabel("Custom widget") + self.layout.addWidget(self.label) + self.setLayout(self.layout) + +class CustomLoader(QUiLoader): + def __init__(self): + super(CustomLoader,self).__init__() + + def createWidget(self, className, parent=None, name=""): + return super(CustomLoader, self).createWidget(className, parent, name) + +if __name__ == "__main__": + app = QApplication([]) + loader = CustomLoader() + loader.registerCustomWidget(CustomWidget) + form = loader.load(adjust_filename("bug_1135.ui", __file__)) + form.show() diff --git a/tests/QtUiTools/bug_1135.ui b/tests/QtUiTools/bug_1135.ui new file mode 100644 index 0000000..539fc17 --- /dev/null +++ b/tests/QtUiTools/bug_1135.ui @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>380</width> + <height>280</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Regular widget</string> + </property> + </widget> + </item> + <item> + <widget class="CustomWidget" name="frame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>CustomWidget</class> + <extends>QFrame</extends> + <header>customwidget.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> |