2016-05-16 65 views
2

我一直工作在一個PyQt4的應用程序,這是我到目前爲止有:PyQt4的窗口關閉自動

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

我的問題是當我嘗試創建類主窗口兆瓦。出於某種原因,它會做MainWindow.initui(),然後立即關閉。我認爲它與main()函數和QApplication對象有關。編碼多個窗口並解決此問題的最佳方法是什麼?我原本是要爲每個窗口創建一個類:passwordPrompt,MainMenu等,然後實例化每個類的實例來加載一個新窗口,但是你可以看到它不工作。

+0

嗨@WewLad,你找到一個答案有幫助嗎?希望你的問題解決了:-) –

回答

0

我已經調整了一下你的代碼。我相信現在的工作:

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

我增加了一個額外的變量來PasswordPrompt類:在mySrc變量。通過所謂的「信號插槽」機制,我將mySrc變量連接到函數startMainWindow(passw)。如果您想了解更多關於信號插槽機制和方式它可以幫助你在一個線程安全的方式使用GUI的溝通,看看這個帖子:

Simplest way for PyQT Threading

也許信號插槽機制在這種特殊情況下有點矯枉過正,因爲你沒有創建其他線程。但無論如何,它的工作原理是:-)。在函數startMainWindow(passw)中,我創建了主窗口實例。之後,我關閉密碼提示實例。兩個實例都是「全局變量」是至關重要的。如果主窗口mw不是全局變量,則當函數startMainWindow(passw)退出時,它將被刪除(並且窗口立即關閉)。這是因爲mw只是該函數中的局部變量。

我希望這對你有所幫助。請讓我知道這個解決方案是否適合你。

+0

我開始理解這一點,我越想越過它。 – WewLad

+0

偉大:-) 如果有什麼我可以幫助你,請讓我知道。 –

+0

哇,我只是將原始代碼中的mw變量更改爲全局變量,它的工作原理很奇怪。 – WewLad

0

所以我簡要回顧了一下你的代碼。 我也試圖做類似的事情,但它也不適用於我。 我所做的是一個QDialog,並檢查其返回的DialogCode,如果接受,則調用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() 

我不是PyQt4中的專家,但我用這個方法做了一些應用程序,我認爲這是完全有效的。 希望它有幫助!

0

修正了它。我將mw變量初始化爲全局變量,然後將其分配給MainWindow()的實例。這就是我需要做的奇怪事情。

+0

嗨@WewLad,因爲我的回答讓你朝着正確的方向發展,有點讚賞:-) –