summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@zytor.com>2012-02-27 23:16:16 -0300
committerPaulo Alcantara <pcacjr@zytor.com>2012-02-27 23:26:14 -0300
commit3f779b8307ebf4b6bdfbe777f41d76ce4ca25151 (patch)
tree184629fd744505fd54bddab51f80c7a17dc4a2b9
parentcbd3075fffa95bb9c195f90698533c8d906edaab (diff)
downloadpyside-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.cpp13
-rw-r--r--plugins/customwidget.h8
-rw-r--r--tests/QtUiTools/CMakeLists.txt1
-rw-r--r--tests/QtUiTools/bug_1135.py29
-rw-r--r--tests/QtUiTools/bug_1135.ui65
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>