Загрузка простой формы Qt Designer в Pyside

Я создаю простую форму в дизайнере Qt и пытаюсь загрузить его в приложение Qt, которое я создаю с помощью PySide, но без большой удачи.

Здесь сгенерированный код из `pyside-uic ':

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'clientEditorForm.ui'
#
# Created: Tue Nov  3 23:46:41 2009
#      by: PySide uic UI code generator
#
# WARNING! All changes made in this file will be lost!

from PySide import QtCore, QtGui

class Ui_clientEditorForm(object):
    def setupUi(self, clientEditorForm):
        clientEditorForm.setObjectName("clientEditorForm")
        clientEditorForm.resize(575, 446)
        self.horizontalLayout_3 = QtGui.QHBoxLayout(clientEditorForm)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.splitter = QtGui.QSplitter(clientEditorForm)
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.setObjectName("splitter")
        self.layoutWidget = QtGui.QWidget(self.splitter)
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout = QtGui.QVBoxLayout(self.layoutWidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtGui.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.searchLabel = QtGui.QLabel(self.layoutWidget)
        self.searchLabel.setObjectName("searchLabel")
        self.horizontalLayout_2.addWidget(self.searchLabel)
        self.searchEdit = QtGui.QLineEdit(self.layoutWidget)
        self.searchEdit.setObjectName("searchEdit")
        self.horizontalLayout_2.addWidget(self.searchEdit)
        self.clearButton = QtGui.QPushButton(self.layoutWidget)
        self.clearButton.setObjectName("clearButton")
        self.horizontalLayout_2.addWidget(self.clearButton)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.clientListView = QtGui.QListView(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.clientListView.sizePolicy().hasHeightForWidth())
        self.clientListView.setSizePolicy(sizePolicy)
        self.clientListView.setObjectName("clientListView")
        self.verticalLayout.addWidget(self.clientListView)
        self.frame = QtGui.QFrame(self.splitter)
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.verticalLayout_3 = QtGui.QVBoxLayout(self.frame)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.formLayout = QtGui.QFormLayout()
        self.formLayout.setObjectName("formLayout")
        self.nameEdit = QtGui.QLineEdit(self.frame)
        self.nameEdit.setObjectName("nameEdit")
        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.nameEdit)
        self.nameLabel = QtGui.QLabel(self.frame)
        self.nameLabel.setObjectName("nameLabel")
        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.nameLabel)
        self.profileButton = QtGui.QLabel(self.frame)
        self.profileButton.setObjectName("profileButton")
        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.profileButton)
        self.addressLabel = QtGui.QLabel(self.frame)
        self.addressLabel.setObjectName("addressLabel")
        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.addressLabel)
        self.locationLabel = QtGui.QLabel(self.frame)
        self.locationLabel.setObjectName("locationLabel")
        self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.locationLabel)
        self.secureLabel = QtGui.QLabel(self.frame)
        self.secureLabel.setObjectName("secureLabel")
        self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.secureLabel)
        self.UUIDLabel = QtGui.QLabel(self.frame)
        self.UUIDLabel.setObjectName("UUIDLabel")
        self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.UUIDLabel)
        self.passwordLabel = QtGui.QLabel(self.frame)
        self.passwordLabel.setObjectName("passwordLabel")
        self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.passwordLabel)
        self.profileComboBox = QtGui.QComboBox(self.frame)
        self.profileComboBox.setObjectName("profileComboBox")
        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.profileComboBox)
        self.addressEdit = QtGui.QLineEdit(self.frame)
        self.addressEdit.setObjectName("addressEdit")
        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.addressEdit)
        self.locationComboBox = QtGui.QComboBox(self.frame)
        self.locationComboBox.setObjectName("locationComboBox")
        self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.locationComboBox)
        self.secureComboBox = QtGui.QComboBox(self.frame)
        self.secureComboBox.setObjectName("secureComboBox")
        self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.secureComboBox)
        self.UUIDEdit = QtGui.QLineEdit(self.frame)
        self.UUIDEdit.setObjectName("UUIDEdit")
        self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole, self.UUIDEdit)
        self.passwordEdit = QtGui.QLineEdit(self.frame)
        self.passwordEdit.setObjectName("passwordEdit")
        self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.passwordEdit)
        self.verticalLayout_3.addLayout(self.formLayout)
        self.aliasesGroupBox = QtGui.QGroupBox(self.frame)
        self.aliasesGroupBox.setFlat(False)
        self.aliasesGroupBox.setCheckable(False)
        self.aliasesGroupBox.setObjectName("aliasesGroupBox")
        self.verticalLayout_2 = QtGui.QVBoxLayout(self.aliasesGroupBox)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.aliasesListView = QtGui.QListView(self.aliasesGroupBox)
        self.aliasesListView.setObjectName("aliasesListView")
        self.verticalLayout_2.addWidget(self.aliasesListView)
        self.horizontalLayout_4 = QtGui.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem)
        self.addButton = QtGui.QPushButton(self.aliasesGroupBox)
        self.addButton.setObjectName("addButton")
        self.horizontalLayout_4.addWidget(self.addButton)
        self.removeButton = QtGui.QPushButton(self.aliasesGroupBox)
        self.removeButton.setObjectName("removeButton")
        self.horizontalLayout_4.addWidget(self.removeButton)
        self.verticalLayout_2.addLayout(self.horizontalLayout_4)
        self.verticalLayout_3.addWidget(self.aliasesGroupBox)
        spacerItem1 = QtGui.QSpacerItem(20, 38, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout_3.addItem(spacerItem1)
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.revertButton = QtGui.QPushButton(self.frame)
        self.revertButton.setObjectName("revertButton")
        self.horizontalLayout.addWidget(self.revertButton)
        self.applyButton = QtGui.QPushButton(self.frame)
        self.applyButton.setObjectName("applyButton")
        self.horizontalLayout.addWidget(self.applyButton)
        self.verticalLayout_3.addLayout(self.horizontalLayout)
        self.horizontalLayout_3.addWidget(self.splitter)
        self.searchLabel.setBuddy(self.searchEdit)
        self.nameLabel.setBuddy(self.nameEdit)
        self.profileButton.setBuddy(self.profileComboBox)
        self.addressLabel.setBuddy(self.addressEdit)
        self.locationLabel.setBuddy(self.locationComboBox)
        self.secureLabel.setBuddy(self.secureComboBox)
        self.UUIDLabel.setBuddy(self.UUIDEdit)
        self.passwordLabel.setBuddy(self.passwordEdit)

        self.retranslateUi(clientEditorForm)
        QtCore.QMetaObject.connectSlotsByName(clientEditorForm)

    def retranslateUi(self, clientEditorForm):
        clientEditorForm.setWindowTitle(QtGui.QApplication.translate("clientEditorForm", "Form", None, QtGui.QApplication.UnicodeUTF8))
        self.searchLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Search", None, QtGui.QApplication.UnicodeUTF8))
        self.clearButton.setText(QtGui.QApplication.translate("clientEditorForm", "Clear", None, QtGui.QApplication.UnicodeUTF8))
        self.nameLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Name", None, QtGui.QApplication.UnicodeUTF8))
        self.profileButton.setText(QtGui.QApplication.translate("clientEditorForm", "Profile", None, QtGui.QApplication.UnicodeUTF8))
        self.addressLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Address", None, QtGui.QApplication.UnicodeUTF8))
        self.locationLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Location", None, QtGui.QApplication.UnicodeUTF8))
        self.secureLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Secure", None, QtGui.QApplication.UnicodeUTF8))
        self.UUIDLabel.setText(QtGui.QApplication.translate("clientEditorForm", "UUID", None, QtGui.QApplication.UnicodeUTF8))
        self.passwordLabel.setText(QtGui.QApplication.translate("clientEditorForm", "Password", None, QtGui.QApplication.UnicodeUTF8))
        self.aliasesGroupBox.setTitle(QtGui.QApplication.translate("clientEditorForm", "Aliases", None, QtGui.QApplication.UnicodeUTF8))
        self.addButton.setText(QtGui.QApplication.translate("clientEditorForm", "Add", None, QtGui.QApplication.UnicodeUTF8))
        self.removeButton.setText(QtGui.QApplication.translate("clientEditorForm", "Remove", None, QtGui.QApplication.UnicodeUTF8))
        self.revertButton.setText(QtGui.QApplication.translate("clientEditorForm", "Revert", None, QtGui.QApplication.UnicodeUTF8))
        self.applyButton.setText(QtGui.QApplication.translate("clientEditorForm", "Apply", None, QtGui.QApplication.UnicodeUTF8))

Тогда мое простое приложение:

import sys
from PySide import QtCore, QtGui

from clientEditorForm import Ui_clientEditorForm

class MyMainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.ui = Ui_clientEditorForm()
        self.ui.setupUi(self)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyMainWindow()
    myapp.show()
    sys.exit(app.exec_())

Однако, когда я пытаюсь запустить его, я получаю следующее:

QLayout: Attempting to add QLayout "" to QMainWindow "clientEditorForm", which already has a layout

и ошибка сегментации. Я следую основным инструкциям в этот учебник, но я не могу сказать, что я делаю неправильно.

Ответ 1

Оказывается, в PySide есть ошибка в классе QSpacerItem. Комментируя экземпляры QSpacerItem в приведенном выше коде, он отлично работает. Там сообщается отчет об ошибке PySide bugzilla.

Ответ 2

Во-первых, вы используете PySide (Nokia), а не PyQt4 (Riverbank Computing), хотя их API почти идентичны, они не являются одним и тем же проектом. Примеры PySide доступны здесь: git clone git://gitorious.org/pyside/pyside-examples.git

Я думаю, что проблема может быть связана с вашим вызовом

super(MyMainWindow, self).__init__(parent)

попробовать

QtGui.QMainWindow.__init__(self, parent)

вместо.

Я знаю, что похоже, что это одно и то же, но я столкнулся с аналогичными проблемами с супер, используя PyQt4, и из того, что я могу сказать, Nokia PySide имеет те же проблемы. Это имеет какое-то отношение к погоде, которую Python принадлежит родительскому объекту или принадлежит принадлежащему С++ объекту. По крайней мере, попробуйте, это займет менее 5 секунд!

Ниже приведен пример, который я использую для этого, из репо git для PySide.

#!/usr/bin/env python

#############################################################################
##
## Copyright (C) 2004-2005 Trolltech AS. All rights reserved.
##
## This file is part of the example classes of the Qt Toolkit.
##
## This file may be used under the terms of the GNU General Public
## License version 2.0 as published by the Free Software Foundation
## and appearing in the file LICENSE.GPL included in the packaging of
## this file.  Please review the following information to ensure GNU
## General Public Licensing requirements will be met:
## http://www.trolltech.com/products/qt/opensource.html
##
## If you are unsure which license is appropriate for your use, please
## review the following information:
## http://www.trolltech.com/products/qt/licensing.html or contact the
## sales department at [email protected]
##
## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
##
#############################################################################

import sys
from PySide import QtCore, QtGui

from ui_calculatorform import Ui_CalculatorForm


class CalculatorForm(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.ui = Ui_CalculatorForm()

        self.ui.setupUi(self)

    @QtCore.pyqtSignature("int")
    def on_inputSpinBox1_valueChanged(self, value):
        self.ui.outputWidget.setText(QtCore.QString.number(value + self.ui.inputSpinBox2.value()))

    @QtCore.pyqtSignature("int")
    def on_inputSpinBox2_valueChanged(self, value):
        self.ui.outputWidget.setText(QtCore.QString.number(value + self.ui.inputSpinBox1.value()))


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    calculator = CalculatorForm()
    calculator.show()
    sys.exit(app.exec_())