PyQt4窗口自动关闭

时间:2016-05-16 15:42:12

标签: python user-interface 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()

当我尝试创建类主窗口的mw时,我的问题出现了。出于某种原因,它将执行MainWindow.initui(),然后立即关闭。我假设它与main()函数和QApplication对象有关。编写多个窗口并解决此问题的最佳方法是什么?我本来打算为每个窗口创建一个类:passwordPrompt,MainMenu等然后实例化每个类的实例以加载一个新窗口但是你可以看到它不起作用。

3 个答案:

答案 0 :(得分: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只是该函数中的局部变量。

我希望这能帮到你。如果此解决方案适合您,请告诉我。

答案 1 :(得分: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的专家,但我用这种方法制作了一些应用程序,我认为它完全有效。 希望它有所帮助!

答案 2 :(得分:0)

修正了它。我将mw变量初始化为全局变量,然后将其分配给MainWindow()的实例。这就是我需要做的所有奇怪的事情。