2012-11-22 58 views
6

我一直在尝试使用python3和Qt4从现有的窗口调用新窗口。如何从现有窗口创建新的PyQt4窗口?

我已经创建了两个窗口使用Qt设计器(主应用程序和另一个),并且我已经将Qt设计器生成的.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 

回答

12

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

pyuic的主要目的是从Qt的Desgner ui文件,让您进口所包含GUI类为应用程序创建静态 Python模块。

假设您已经使用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

5

只能创建一个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

如果您有被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_()