暂停当前​​功能,直到对话框关闭

时间:2016-02-13 13:22:33

标签: python qt pyqt

该示例有两个窗口,MainFooMain应在Foo关闭后显示Foo中的值输入。

Whole picture

代码如下:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Main(QWidget):
    def __init__(self):
        super(Main, self).__init__()
        self.setupUI()

    def setupUI(self):
        self.label = QLabel('0')

        okBtn = QPushButton('Start Foo')
        okBtn.clicked.connect(self.startFoo)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.label)
        mainLayout.addWidget(okBtn)
        self.setLayout(mainLayout)

        self.setWindowTitle('Main')
        self.show()

    def startFoo(self):
        foo = Foo()
        # I want the function to suspend until Foo() is destroyed, so I can set label's text as what I input earlier in `Foo`
        self.label.setText(str(foo.edit.text()))


class Foo(QDialog):
    def __init__(self):
        super(Foo, self).__init__()
        self.setupUI()
        self.var = 0

    def setupUI(self):

        # QLineEdit
        self.edit = QLineEdit()

        # QPushButton
        okBtn = QPushButton('OK')
        okBtn.clicked.connect(self.setVar)

        # main layout
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.edit)
        mainLayout.addWidget(okBtn)
        self.setLayout(mainLayout)

        self.setWindowTitle('Foo')
        self.show()

    def setVar(self):
        self.var = self.edit.text()
        self.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Main()
    app.exec_()

请注意这一部分:

def startFoo(self):
    foo = Foo()
    # I want the function to suspend until Foo() is closed, so I can set label's text as what I input earlier in `Foo`
    self.label.setText(str(foo.edit.text()))

我希望函数暂停直到Foo()被销毁,所以我可以将标签的文本设置为我之前在Foo中输入的内容。但该应用只是继续运行,这使得self.label的文字完全空白(因为foo.edit.text()在启动None时为Foo()。我尝试像这样添加QEventLoop

def startFoo(self):
    foo = Foo()

    loop = QEventLoop()
    foo.destroyed.connect(loop.quit)
    loop.exec_()

    self.label.setText(str(foo.edit.text()))

它也不起作用。那么如何做到这一点?

1 个答案:

答案 0 :(得分:5)

您需要使用exec_代替show来显示Foo对话框。不同之处在于,show只显示对话框窗口,exec_会将其作为模态执行,因此在UI线程暂停时,您只能与该对话框进行交互,直到对话框关闭。

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Main(QWidget):

    def __init__(self):
        super(Main, self).__init__()
        self.setupUI()

    def setupUI(self):
        self.label = QLabel('0')

        okBtn = QPushButton('Start Foo')
        okBtn.clicked.connect(self.startFoo)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.label)
        mainLayout.addWidget(okBtn)
        self.setLayout(mainLayout)

        self.setWindowTitle('Main')

    def startFoo(self):
        foo = Foo()
        foo.exec_()
        self.label.setText(str(foo.edit.text()))


class Foo(QDialog):

    def __init__(self):
        super(Foo, self).__init__()
        self.setupUI()
        self.var = 0

    def setupUI(self):

        # QLineEdit
        self.edit = QLineEdit()

        # QPushButton
        okBtn = QPushButton('OK')
        okBtn.clicked.connect(self.setVar)

        # main layout
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.edit)
        mainLayout.addWidget(okBtn)
        self.setLayout(mainLayout)

        self.setWindowTitle('Foo')

    def setVar(self):
        self.var = self.edit.text()
        self.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Main()
    ex.show()
    app.exec_()

此外,这主要是个人建议,而不是一般规则,最好从实现小部件的类外部调用showexec_。通过这种方式,您可以区分对话窗口的显示方式(例如,您可以创建一个按钮来执行show,另一个按钮可以通过调用exec_来显示模态。