如何在 Python 函数中创建简单的 PyQt 弹出窗口并在其末尾关闭?
Posted
技术标签:
【中文标题】如何在 Python 函数中创建简单的 PyQt 弹出窗口并在其末尾关闭?【英文标题】:How to create simple PyQt popup in Python function and close at the end of it? 【发布时间】:2017-11-06 22:42:55 【问题描述】:我正在运行一个函数,我想在其中打开一个 PyQt 弹出窗口,上面写着“Waiting...”之类的内容,只要函数完成,它就会持续。之后我想将文本更改为“完成”,休眠一两秒钟,然后关闭弹出窗口。我已经尝试了很多方法来做到这一点,但到目前为止都没有成功。看起来每当我调用app.exec_()
时,该函数都会暂停该函数,直到我关闭弹出窗口。我想在 PyQt 的主事件循环的上下文之外执行此操作(我尝试异步运行此事件循环但无济于事)。如果我不打电话给exec_()
,我根本看不到弹出窗口。基本上我想要这样的东西:
# this is the function that is being run
def run():
create_popup() # show popup
wait_for_some_messages() # do some stuff
close_popup() # close popup
def create_popup():
app = QApplication([])
popup = Popup()
popup.show()
class Popup(QDialog):
super().__init__()
self.label = QLabel(self)
非常感谢任何帮助。谢谢!
【问题讨论】:
【参考方案1】:我认为您要执行的任务很繁重,因此您可以阻止GUI循环,因此建议实现QRunnable
并使用QThreadPool
启动它,在run方法中将调用繁重的函数,在最后这个任务会通过QMetaObject::invokeMethod
更新数据,然后我们用QEventLoop
等待2秒,调用close方法。
class Runnable(QRunnable):
def __init__(self, popup, func):
QRunnable.__init__(self)
self.popUp = popup
self.func = func
def run(self):
# execute hard function
self.func()
# Update the text shown in the popup
QMetaObject.invokeMethod(self.popUp, "setText",
Qt.QueuedConnection,
Q_ARG(str, "Complete"))
# wait 2 seconds
loop = QEventLoop()
QTimer.singleShot(2000, loop.quit)
loop.exec_()
# call the close method of the popup
QMetaObject.invokeMethod(self.popUp, "close",
Qt.QueuedConnection)
class PopUp(QDialog):
def __init__(self, *args, **kwargs):
QDialog.__init__(self, *args, **kwargs)
self.setLayout(QVBoxLayout())
self.label = QLabel(self)
self.layout().addWidget(self.label)
@pyqtSlot(str)
def setText(self, text):
self.label.setText(text)
# emulate the heavy task
def func():
for i in range(10000):
print(i)
QThread.msleep(1)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = PopUp()
w.show()
w.setText("Waiting...")
runnable = Runnable(w, func)
QThreadPool.globalInstance().start(runnable)
w.exec_()
加:
如果您想调用另一个函数,只需更改:
runnable = Runnable(w, func)
到:
runnable = Runnable(w, name_of_your_function)
【讨论】:
有没有办法在 PyQt 的范围之外调用fun()
?在我的应用程序中,我有一个进程正在运行,我认为将所有逻辑移动到 PyQt 应用程序中,这样我才能得到一个弹出窗口,这有点难看。使用您的示例让我们假设 fun()
已经被调用,并且在其中我想在第一行创建/显示一个弹出窗口并在最后一行关闭它。你知道这是否可能。
@Stefan 检查我修改后的答案,您只需调用它传递函数的名称。
谢谢 eyllanesc,我终于用你的解决方案搞定了。以上是关于如何在 Python 函数中创建简单的 PyQt 弹出窗口并在其末尾关闭?的主要内容,如果未能解决你的问题,请参考以下文章