2012-11-22 31 views
6

Ho provato a chiamare una nuova finestra da una esistente usando python3 e Qt4.Come creare nuove finestre PyQt4 da una finestra esistente?

Ho creato due finestre utilizzando Qt Designer (l'applicazione principale e un'altra) e ho convertito i file .ui generati da Qt Designer in script .py - ma non riesco a creare nuove finestre dall'applicazione principale.

Ho provato a fare questo:

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

Ma ho questo messaggio di errore:

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

risposta

12

Sebbene pyuic possa creare script eseguibili con l'opzione -x, --execute, è principalmente destinato al test.

Lo scopo principale di pyuic è quello di creare statici moduli Python da Qt Desgner ui file che consentono di importare le classi GUI contenute nella vostra applicazione.

Supponiamo di aver creato due file ui utilizzando Qt Designer e li abbiamo denominati v1.ui e v2.ui.

Si potrebbe quindi creare i due moduli Python come questo:

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

Successivamente, si potrebbe scrivere un main.py script separato che importa le classi GUI dai moduli, e crea le istanze di loro in base alle esigenze.

Così il vostro main.py potrebbe essere simile a questa:

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

Nota che ho cambiato i nomi delle classi GUI leggermente per evitare scontri namespace. Per assegnare nomi migliori alle classi della GUI, imposta la proprietà objectName della classe di livello superiore in Qt Desgner. E non dimenticare di eseguire nuovamente pyuic dopo aver apportato le modifiche!

5

È possibile creare una sola QApplication. Dopo averlo creato, puoi creare quante finestre vuoi.

Ad esempio:

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

Ogni volta che si fa clic sul pulsante creerà una nuova finestra.

È possibile adattare l'esempio precedente per utilizzare le finestre create con Designer.

Su un lato nota:

Mai e poi mai modificare il risultato di pyuic. Quei file non dovrebbero essere cambiati. Ciò significa: non aggiungere il metodo mbutton1 allo Ui_Form.

Se avete il file mywindow_ui.py che è stato creato da pyuic, quindi si crea il file mywindow.py e mettere qualcosa di simile:

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. 

Ora dal file principale main.py fare:

from PyQt4 import QtGui 

from mywindow import MyWindow 


# ... 

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