简体   繁体   English

pyqt如何创建等待弹出窗口以运行长函数/计算

[英]pyqt how to create a wait popup for running a long function/calulation

I am trying to create a dialog window that pops up, runs a function and then automatically closes when the function is done. 我正在尝试创建一个对话框窗口,该窗口会弹出,运行一个函数,然后在函数完成后自动关闭。 In the code below, the function runs before popping up the dialog and I cannot automatically close otherwise the dialog window will pop up and not respond to clicking the "x" button. 在下面的代码中,该函数在弹出对话框之前运行,并且我无法自动关闭,否则对话框窗口将弹出并且对单击“ x”按钮没有响应。

How can I create a pop-up, run a function after the pop-up is visible, and then close the pop-up when the function is done running. 如何创建弹出窗口,在弹出窗口可见后运行一个函数,然后在该函数运行完毕后关闭该弹出窗口。

# from PyQt4 import QtGui
# QtWidgets = QtGui
from PyQt5 import QtWidgets, QtCore
import sys, time

app = QtWidgets.QApplication(sys.argv)


def print_every_3_seconds():
    print(0)
    for i in range(1, 4):
        time.sleep(1)
        print(i)


class RunFunctionDialog(QtWidgets.QDialog):

    def __init__(self, function, parent=None):
        super(RunFunctionDialog, self).__init__(parent)
        self.layout = QtWidgets.QVBoxLayout(self)
        self.textBrowser = QtWidgets.QTextBrowser()
        self.textBrowser.setText("Wait 3 seconds")
        self.layout.addWidget(self.textBrowser)
        self.function = function

    def showEvent(self, QShowEvent):
        self.function()
        # self.close()  # dialog freezes in an unresponsive state


def show_dialog():
    dialog = RunFunctionDialog(print_every_3_seconds)
    dialog.exec_()

widget = QtWidgets.QWidget(None)
button = QtWidgets.QPushButton("Show Dialog", widget)
button.clicked.connect(show_dialog)

widget.show()

app.exec_()

Create a worker thread and put your worker function in there. 创建一个工作线程并将您的工作程序函数放在其中。 This will prevent your main (gui) thread from getting blocked by the worker function. 这将防止您的主(gui)线程被辅助函数阻塞。 You can use the QThread class for this. 您可以为此使用QThread类。 This has the advantage of having a finished signal that you can use to close your dialog if work is finished. 这样做的优点是发出完成信号,如果工作完成,您可以使用该信号关闭对话框。

First you need to create a WorkerThread by simply subclassing QThread: 首先,您需要通过简单地继承QThread来创建WorkerThread:

class WorkerThread(QtCore.QThread):

    def run(self):
        print_every_3_seconds()

Then you create an instance of the Worker class in your RunFunctionDialog.__init__() , connect the finished signal to your close slot and start the thread. 然后,在RunFunctionDialog.__init__()创建Worker类的实例,将finished信号连接到您的close插槽并启动线程。

class RunFunctionDialog(QtWidgets.QDialog):

    def __init__(self, function, parent=None):
        super(RunFunctionDialog, self).__init__(parent)
        # ...

        self.function = function

        self.thread = WorkerThread()
        self.thread.finished.connect(self.close)
        self.thread.start()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM