2012-11-22 13 views
6

Próbowałem wywołać nowe okno z istniejącego przy użyciu python3 i Qt4.Jak utworzyć nowe okna PyQt4 z istniejącego okna?

Stworzyłem dwa okna przy użyciu Qt Designer (głównej aplikacji i innej) i przekonwertowałem pliki .ui wygenerowane przez Qt Designer na skrypty .py - ale nie mogę tworzyć nowych okien z głównej aplikacji.

Próbowałem w ten sposób:

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

Ale otrzymuję komunikat o błędzie:

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

Odpowiedz

12

Chociaż pyuic może tworzyć skrypty wykonywalne z opcją -x, --execute, jest głównie przeznaczony do testowania.

Głównym celem pyuic jest stworzenie statycznych modułów Pythona z Qt Desgner ui plików, które pozwalają importu te zawarte klasy GUI do aplikacji.

Załóżmy, że utworzyłeś dwa pliki ui używając Qt Designer i nazwał je v1.ui i v2.ui.

Można by następnie utworzyć dwa moduły Pythona tak:

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

Następny, by napisać osobną main.py skrypt, który importuje klas GUI z modułów i tworzy instancje nich w razie potrzeby.

więc main.py mógłby wyglądać następująco:

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

pamiętać, że zmieniły nazwy swoich klas GUI lekko uniknąć konfliktów nazw. Aby dać GUI klasy lepsze nazwy, wystarczy ustawić właściwość objectName klasy najwyższego poziomu w Qt Desgner. I nie zapomnij ponownie uruchomić pyuic po wprowadzeniu zmian!

5

Można utworzyć tylko jedną QApplication. Po utworzeniu możesz utworzyć ile okien chcesz.

Na przykład:

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

Za każdym razem po kliknięciu przycisku spowoduje utworzenie nowego okna.

Możesz dostosować powyższy przykład, aby użyć okien utworzonych za pomocą Projektanta.

Na marginesie:

Nigdy edytować wynik pyuic. Pliki te nie powinny być zmieniane. Oznacza to: nie dodawaj metody mbutton1 do Ui_Form.

Jeśli masz plik mywindow_ui.py, który został utworzony przez pyuic, a następnie utworzyć plik mywindow.py i umieścić coś takiego:

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. 

Teraz z głównego pliku main.py zrobić:

from PyQt4 import QtGui 

from mywindow import MyWindow 


# ... 

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