【问题标题】:How to create new PyQt4 windows from an existing window?如何从现有窗口创建新的 PyQt4 窗口?
【发布时间】:2012-11-11 03:20:05
【问题描述】:

我一直在尝试使用 python3 和 Qt4 从现有窗口调用一个新窗口。

我已经使用 Qt Designer 创建了两个窗口(主应用程序和另一个),我已经将 Qt Designer 生成的 .ui 文件转换为 .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

【问题讨论】:

    标签: python window pyqt qt-designer pyuic


    【解决方案1】:

    虽然pyuic 可以使用-x, --execute 选项创建可执行脚本,但它主要用于测试。

    pyuic 的主要目的是从 Qt Desgner ui 文件创建 static python 模块,允许您将包含的 GUI 类导入到您的应用程序中。

    假设您使用 Qt Designer 创建了两个 ui 文件并将它们命名为 v1.uiv2.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 类提供更好的名称,只需在 Qt Desgner 中设置顶级类的objectName 属性。进行更改后不要忘记重新运行pyuic

    【讨论】:

      【解决方案2】:

      您只能创建一个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_()
      

      每次单击按钮都会创建一个新窗口。

      您可以修改上述示例以使用您使用设计器创建的窗口。

      附注:

      永远不要编辑 pyuic 的结果。不应更改这些文件。这意味着:不要将mbutton1 方法添加到Ui_Form

      如果你有由 pyuic 创建的文件 mywindow_ui.py,那么你创建文件 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_()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-28
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        相关资源
        最近更新 更多