2012-11-22 12 views
6

Ich habe versucht, ein neues Fenster aus einem bestehenden mit Python3 und Qt4 aufzurufen.Wie erstellt man neue PyQt4-Fenster aus einem bestehenden Fenster?

Ich habe zwei Fenster mit Qt Designer erstellt (die Hauptanwendung und eine andere), und ich habe die von Qt Designer generierten .ui-Dateien in .py-Skripts konvertiert - aber ich kann scheinbar keine neuen Fenster erstellen aus der Hauptanwendung.

Ich habe versucht, dies zu tun:

############### 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_()) 

Aber ich bekomme diese Fehlermeldung:

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

Antwort

12

Obwohl pyuic ausführbare Skripts mit der Option -x, --execute erstellen kann, ist es hauptsächlich zum Testen vorgesehen.

Der Hauptzweck der pyuic ist statische Python-Module von Qt Desgner ui Dateien zu erstellen, die Sie Import die enthaltenen GUI-Klassen in Ihrer Anwendung ermöglichen.

Nehmen wir an, Sie haben zwei ui Dateien mit Qt Designer erstellt und sie v1.ui und v2.ui genannt.

Sie würden dann die beide Python-Modulen wie folgt erstellen:

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

Als nächst Sie einen separaten main.py Skript schreiben würden, die die GUI-Klassen von den Modulen und erzeugen Instanzen von ihnen je nach Bedarf importiert.

So Ihre main.py könnte wie folgt aussehen:

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_()) 

Bitte beachte, dass ich die Namen der GUI-Klassen geändert haben etwas Namespace Kollisionen zu vermeiden. Um den GUI-Klassen bessere Namen zu geben, legen Sie einfach die Eigenschaft objectName der obersten Klasse in Qt Desgner fest. Und vergessen Sie nicht, pyuic erneut auszuführen, nachdem Sie Ihre Änderungen vorgenommen haben!

5

Sie nur eine QApplication erstellen können. Nachdem Sie es erstellt haben, können Sie erstellen, wie viele Fenster Sie möchten.

Zum Beispiel:

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_() 

Jedes Mal, wenn Sie auf die Schaltfläche klicken, wird ein neues Fenster erstellen.

Sie können das obige Beispiel anpassen, um die Fenster zu verwenden, die Sie mit dem Designer erstellt haben.

Auf einer seitlichen Anmerkung:

Nie das Ergebnis pyuic bearbeiten. Diese Dateien sollten nicht geändert werden. Das bedeutet: Fügen Sie die mbutton1-Methode nicht zu Ui_Form hinzu.

Wenn Sie die Datei haben mywindow_ui.py, die von pyuic erstellt wurde, dann erstellen Sie die Datei mywindow.py und setzen so etwas wie dieses:

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. 

nun aus Ihrer Hauptdatei main.py Sie tun:

from PyQt4 import QtGui 

from mywindow import MyWindow 


# ... 

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