2016-05-16 12 views
2

Ich habe auf einem PyQt4 Anwendung arbeiten, und das ist, was ich habe, so weit:PyQt4 Fenster schließt sich automatisch

import sys 
from PyQt4 import QtGui, QtCore 

class PasswordPrompt(QtGui.QWidget): 

    def __init__(self): 
     super(PasswordPrompt, self).__init__() 
     self.initUi() 

    def initUi(self): 
     self.setFixedSize(500, 75) 
     self.setWindowTitle('Please enter the password...') 

     self.prompt = QtGui.QLineEdit(self) 
     self.btn = QtGui.QPushButton('Enter', self) 
     self.btn.clicked.connect(self.btnClicked) 

     self.hbox = QtGui.QHBoxLayout() 
     self.hbox.addWidget(self.prompt) 
     self.hbox.addWidget(self.btn) 

     self.vbox = QtGui.QVBoxLayout() 
     self.vbox.addLayout(self.hbox) 
     self.vbox2 = QtGui.QVBoxLayout() 

     self.vbox2.addSpacing(300) 
     self.hbox2 = QtGui.QHBoxLayout() 
     self.hbox2.addSpacing(150) 
     self.vbox2.addLayout(self.hbox2) 

     self.vbox.addLayout(self.vbox2) 

     self.setLayout(self.vbox) 
     self.center() 
     self.show() 

    def btnClicked(self): 
     pw = self.prompt.text() 

     if pw == "password": 
      print("Permission granted!") 
      self.close() 
      mw = MainWindow() 

     else: 
      print("Permissed denied!") 
      self.prompt.clear() 
      self.warningText = QtGui.QLabel('That is the wrong password!', self) 
      self.hbox2.addWidget(self.warningText) 

    def center(self): 
     qr = self.frameGeometry() 
     cp = QtGui.QDesktopWidget().availableGeometry().center() 
     qr.moveCenter(cp) 
     self.move(qr.topLeft()) 

class MainWindow(QtGui.QWidget): 

    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.initUi() 

    def initUi(self): 
     self.setWindowTitle('Main Menu') 
     self.setFixedSize(1000, 800) 

     self.show() 

def main(): 
    application = QtGui.QApplication(sys.argv) 
    p = PasswordPrompt() 
    sys.exit(application.exec()) 


if __name__=='__main__': 
    main() 

Mein Problem kommt, wenn ich versuche, mw der Klasse Hauptfenster zu erstellen. Aus irgendeinem Grund wird MainWindow.initui() ausgeführt und dann sofort geschlossen. Ich nehme an, dass es etwas mit der main() - Funktion und dem QApplication-Objekt zu tun hat. Was ist der beste Weg, mehrere Fenster zu programmieren und dies zu umgehen? Ich wollte ursprünglich eine Klasse pro Fenster erstellen: passwordPrompt, MainMenu etc und dann eine Instanz jeder Klasse instanziieren, um ein neues Fenster zu laden, aber wie Sie sehen können, funktioniert es nicht.

+0

Hallo @WewLad, haben Sie eine der Antworten hilfreich gefunden? Hoffe, dein Problem ist gelöst :-) –

Antwort

0

Ich habe Ihren Code ein wenig optimiert. Ich glaube, es funktioniert jetzt:

import sys 
import time 
from PyQt4 import QtGui, QtCore 

# Create two global variables: 
p = None  
mw = None 


# Create the class 'Communicate'. The instance 
# from this class shall be used later on for the 
# signal/slot mechanism. 
class Communicate(QtCore.QObject): 
    myGUI_signal = QtCore.pyqtSignal(str) 

''' End class ''' 


class PasswordPrompt(QtGui.QWidget): 

    def __init__(self): 
     super(PasswordPrompt, self).__init__() 
     self.initUi() 
     self.mySrc = Communicate() 
     self.mySrc.myGUI_signal.connect(startMainWindow) 

    def initUi(self): 
     self.setFixedSize(500, 75) 
     self.setWindowTitle('Please enter the password...') 

     self.prompt = QtGui.QLineEdit(self) 
     self.btn = QtGui.QPushButton('Enter', self) 
     self.btn.clicked.connect(self.btnClicked) 

     self.hbox = QtGui.QHBoxLayout() 
     self.hbox.addWidget(self.prompt) 
     self.hbox.addWidget(self.btn) 

     self.vbox = QtGui.QVBoxLayout() 
     self.vbox.addLayout(self.hbox) 
     self.vbox2 = QtGui.QVBoxLayout() 

     self.vbox2.addSpacing(300) 
     self.hbox2 = QtGui.QHBoxLayout() 
     self.hbox2.addSpacing(150) 
     self.vbox2.addLayout(self.hbox2) 

     self.vbox.addLayout(self.vbox2) 

     self.setLayout(self.vbox) 
     self.center() 
     self.show() 

    def btnClicked(self): 
     pw = self.prompt.text() 

     if pw == "password": 
      print("Permission granted!") 
      # self.close() 
      self.mySrc.myGUI_signal.emit("password") 


     else: 
      print("Permissed denied!") 
      self.prompt.clear() 
      self.warningText = QtGui.QLabel('That is the wrong password!', self) 
      self.hbox2.addWidget(self.warningText) 

    def center(self): 
     qr = self.frameGeometry() 
     cp = QtGui.QDesktopWidget().availableGeometry().center() 
     qr.moveCenter(cp) 
     self.move(qr.topLeft()) 

''' End class ''' 


class MainWindow(QtGui.QWidget): 

    def __init__(self): 
     super(MainWindow, self).__init__() 
     self.initUi() 

    def initUi(self): 
     self.setWindowTitle('Main Menu') 
     self.setFixedSize(1000, 800) 

     self.show() 

''' End class ''' 

def main(): 
    global p 
    application = QtGui.QApplication(sys.argv) 
    p = PasswordPrompt() 
    sys.exit(application.exec()) 

def startMainWindow(passw): 
    global mw 
    global p 
    if(passw == "password"): 
     mw = MainWindow() 
     p.close() 
    else: 
     pass 


if __name__=='__main__': 
    main() 

Ich habe eine zusätzliche Variable in die PasswordPrompt Klasse: die mySrc Variable. Über den so genannten Signal-Slot-Mechanismus verbinde ich die Variable mySrc mit der Funktion startMainWindow(passw). Wenn Sie mehr über das Signal-Slot-Mechanismus lesen wollen, und die Art und Weise hilft es Ihnen, mit GUI in einem Thread-sichere Weise zu kommunizieren, lesen Sie in diesem Beitrag aus:

Simplest way for PyQT Threading

der Signal-Slot-Mechanismus Vielleicht ist ein bisschen Overkill in dieser speziellen Situation, weil Sie keine anderen Threads erstellen. Aber wie auch immer, es funktioniert :-). In der Funktion startMainWindow(passw) erstelle ich die Hauptfensterinstanz. Danach schließe ich die Instanz der Passwortabfrage. Es ist wichtig, dass beide Instanzen "globale Variablen" sind. Wenn das Hauptfenster mw keine globale Variable ist, wird es gelöscht (und das Fenster wird sofort geschlossen), wenn die Funktion startMainWindow(passw) beendet wird. Das liegt daran, dass mw nur eine lokale Variable in dieser Funktion ist.

Ich hoffe, das hat dir geholfen. Bitte lassen Sie mich wissen, ob diese Lösung für Sie funktioniert.

+0

Ich beginne zu verstehen, je mehr ich darüber denke ich denke. – WewLad

+0

Großartig :-) Wenn es etwas gibt, mit dem ich Ihnen helfen kann, lassen Sie es mich wissen. –

+0

Wow, ich habe gerade die Variable mw in meinem ursprünglichen Code in global geändert und es hat seltsam genug funktioniert. – WewLad

0

Also machte ich eine kurze Überprüfung Ihres Codes. Ich habe auch versucht, etwas ähnliches zu tun, aber es hat auch nicht für mich funktioniert. Was ich stattdessen gemacht habe, ist ein QDialog und überprüfen Sie die zurückgegebenen DialogCode, wenn akzeptiert, dann rufen Sie das MainWindow.

import sys 
from PyQt4 import QtGui, QtCore 

class PasswordPrompt(QtGui.QDialog): 

    def __init__(self): 
     super(PasswordPrompt, self).__init__() 
     self.initUi() 

    def initUi(self): 
     self.setFixedSize(500, 75) 
     self.setWindowTitle('Please enter the password...') 

     self.prompt = QtGui.QLineEdit(self) 
     self.btn = QtGui.QPushButton('Enter', self) 
     self.btn.clicked.connect(self.btnClicked) 

     self.hbox = QtGui.QHBoxLayout() 
     self.hbox.addWidget(self.prompt) 
     self.hbox.addWidget(self.btn) 

     self.vbox = QtGui.QVBoxLayout() 
     self.vbox.addLayout(self.hbox) 
     self.vbox2 = QtGui.QVBoxLayout() 

     self.vbox2.addSpacing(300) 
     self.hbox2 = QtGui.QHBoxLayout() 
     self.hbox2.addSpacing(150) 
     self.vbox2.addLayout(self.hbox2) 

     self.vbox.addLayout(self.vbox2) 

     self.setLayout(self.vbox) 
     self.center() 

    def btnClicked(self): 
     pw = self.prompt.text() 

     if pw == "password": 
      print("Permission granted!") 
      self.accept() 

     else: 
      print("Permissed denied!") 
      self.prompt.clear() 
      self.warningText = QtGui.QLabel('That is the wrong password!', self) 
      self.hbox2.addWidget(self.warningText) 

    def center(self): 
     qr = self.frameGeometry() 
     cp = QtGui.QDesktopWidget().availableGeometry().center() 
     qr.moveCenter(cp) 
     self.move(qr.topLeft()) 

class MainWindow(QtGui.QWidget): 

    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     self.initUi() 

    def initUi(self): 
     self.setWindowTitle('Main Menu') 
     self.setFixedSize(1000, 800) 

     self.show() 

def main(): 
    application = QtGui.QApplication(sys.argv) 
    p = PasswordPrompt() 
    if p.exec_() == QtGui.QDialog.Accepted: 
     mw = MainWindow() 
    sys.exit(application.exec_()) 


if __name__=='__main__': 
    main() 

Ich bin kein Experte von PyQt4 aber ich habe einige Anwendungen mit diesem Ansatz, und ich denke, es ist völlig gültig ist. Hoffe es hilft!

0

Fixed es. Ich initialisierte die mw-Variable als globale Variable, bevor ich sie einer Instanz von MainWindow() zuwies. Mehr musste ich nicht tun.

+0

Hallo @WeWLad, da meine Antwort dich in die richtige Richtung gekippt hat, wäre eine kleine Aufwertung zu begrüßen :-) –