2012-11-22 55 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_()