该示例有两个窗口,Main和Foo。Main应该在关闭Foo后更早地显示输入的值Foo。
代码如下:
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_()
Run Code Online (Sandbox Code Playgroud)
注意这一部分:
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()))
Run Code Online (Sandbox Code Playgroud)
我希望函数在Foo()被销毁之前一直挂起,因此我可以将label的文本设置为之前在中输入的内容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()))
Run Code Online (Sandbox Code Playgroud)
也不行。那么该怎么做呢?
You need to use exec_ instead of show to display the Foo dialog. The difference is that while show simply display the dialog window, exec_ will execute it as modal, so you can interact only with that dialog while the UI thread is suspended until the dialog is closed.
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_()
Run Code Online (Sandbox Code Playgroud)
Also, but this is mostly a personal advice and not a general rule, it's better to call show and exec_ from outside the class implementing the widget. In this way you can differentiate the way a dialog window is shown (for example you can create a button to execute show and another one to display it modal by calling exec_.
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |