Как создать новые окна PyQt4 из существующего окна?

Я пытался вызвать новое окно из существующего, используя python3 и Qt4.

Я создал два окна, используя Qt Designer (основное приложение и еще одно), и я преобразовал файлы.ui, сгенерированные Qt Designer, в сценарии.py, но я не могу создать новые окна из основного приложения.,

Я пытался сделать это:

############### MAIN APPLICATION SCRIPT ################

from PyQt4 import QtCore, QtGui
import v2

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(194, 101)
        self.button1 = QtGui.QPushButton(Form)
        self.button1.setGeometry(QtCore.QRect(50, 30, 99, 23))
        self.button1.setObjectName(_fromUtf8("button1"))

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

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
        self.button1.setText(QtGui.QApplication.translate("Form", "Ventana", None, QtGui.QApplication.UnicodeUTF8))

        self.button1.connect(self.button1, QtCore.SIGNAL(_fromUtf8("clicked()")), self.mbutton1)

    def mbutton1(self):
        v2.main()



if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())
################## SECOND WINDOW #######################

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(400, 300)
        self.label = QtGui.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(160, 40, 57, 14))
        self.label.setObjectName(_fromUtf8("label"))

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

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("Form", "LABEL 2", None, QtGui.QApplication.UnicodeUTF8))

def main():
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

Но я получаю это сообщение об ошибке:

 QCoreApplication::exec: The event loop is already running
 QPixmap: Must construct a QApplication before a QPaintDevice

2 ответа

Решение

Хотя pyuic может создавать исполняемые скрипты с -x, --execute вариант, он в основном предназначен для тестирования.

Основное назначение pyuic это создать статические модули Python из Qt Desgner ui файлы, которые позволяют вам импортировать содержащиеся классы GUI в ваше приложение.

Допустим, вы создали два ui файлы с использованием Qt Designer и назвали их v1.ui а также v2.ui,

Затем вы должны создать два модуля Python:

pyuic4 -o v1.py v1.ui
pyuic4 -o v2.py v2.ui

Далее вы бы написали отдельный main.py скрипт, который импортирует классы GUI из модулей и создает их экземпляры по мере необходимости.

Так что ваши main.py может выглядеть примерно так:

from PyQt4 import QtGui
from v1 import Ui_Form1
from v2 import Ui_Form2

class Form1(QtGui.QWidget, Ui_Form1):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)
        self.button1.clicked.connect(self.handleButton)
        self.window2 = None

    def handleButton(self):
        if self.window2 is None:
            self.window2 = Form2(self)
        self.window2.show()

class Form2(QtGui.QWidget, Ui_Form2):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Form1()
    window.show()
    sys.exit(app.exec_())

Обратите внимание, что я немного изменил имена ваших классов GUI, чтобы избежать конфликтов пространства имен. Чтобы дать классам GUI лучшие имена, просто установите objectName свойство класса верхнего уровня в Qt Desgner. И не забудьте перезапустить pyuic после того, как вы внесли свои изменения!

Вы можете создать только один QApplication, После того, как вы создали его, вы можете создать, сколько окон вы хотите.

Например:

from PyQt4 import QtGui, QtCore

class MyWindow(QtGui.QDialog):    # any super class is okay
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.button = QtGui.QPushButton('Press')
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.button)
        self.setLayout(layout)
        self.button.clicked.connect(self.create_child)
    def create_child(self):
        # here put the code that creates the new window and shows it.
        child = MyWindow(self)
        child.show()


if __name__ == '__main__':
    # QApplication created only here.
    app = QtGui.QApplication([])
    window = MyWindow()
    window.show()
    app.exec_()

Каждый раз, когда вы нажимаете кнопку, создается новое окно.

Вы можете адаптировать приведенный выше пример для использования окон, которые вы создали с помощью Designer.

На примечании стороны:

Никогда не редактируйте результат pyuic. Эти файлы не должны быть изменены. Это значит: не добавляйте mbutton1 метод к Ui_Form,

Если у вас есть файл mywindow_ui.py что было создано Pyuic, то вы создаете файл mywindow.py и поставить что-то вроде этого:

from PyQt4 import QtCore, QtGui
from mywindow_ui import Ui_MyWindow

class MyWindow(QtGui.QWidget, Ui_MyWindow):   #or whatever Q*class it is
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setupUi(self)
    def create_child(self):   #here should go your mbutton1
        # stuff
#etc.

Теперь из вашего основного файла main.py ты сделаешь:

from PyQt4 import QtGui

from mywindow import MyWindow


# ...

if __name__ == '__main__':
    app = QtGui.QApplication([])
    window = MyWindow()
    window.show()
    app.exec_()
Другие вопросы по тегам