在 Python 中使用 PyQT 应用程序的主线程中的回调方法启动一个新线程

Posted

技术标签:

【中文标题】在 Python 中使用 PyQT 应用程序的主线程中的回调方法启动一个新线程【英文标题】:Start a new thread in Python with a callback method in Main Thread for PyQT application 【发布时间】:2013-11-04 14:20:08 【问题描述】:

情况:

我是 C#/JS 开发人员,我是 Python 新手。 我正在使用 Python 2.7 和 PyQT 4 开发应用程序

在我的主窗口中,我正在调用一个至少需要 15 秒才能执行的方法。

这个方法阻塞了我的主线程,这对我来说是个问题,因为我想要用户 即使程序正在运行计算,也能够移动窗口。

所以我考虑过使用线程,但我希望能够在线程有时收到通知 完成了刷新窗口数据的工作。

如果我在创建的线程中调用一个新函数,它将创建一个新线程并且它 不允许从不同于主线程的线程修改 QT GUI。

问题:

有没有办法启动一个新的线程(不是进程),它会运行一个方法并调用另一个方法 进程结束后的主线程?

显然,我希望能够与 javascript.jQuery.ajax() 在 Python 环境。

【问题讨论】:

由于 Python 的Global Interpreter Lock,您可能会收到很多建议使用单独的进程而不是线程。你的函数做什么,请求数据或执行计算? 我的功能是一个网络扫描程序,它运行 MSDOS 命令net view 并返回计算机列表(主机名和 IP 地址 (socket.gethostbyname(hostname))。我尝试使用池,但我使用的池创建了一个新进程和一个新的“主窗口” 【参考方案1】:

您需要使用QThread 以及信号和插槽。 QThread 继承自 QObject,允许发出信号。

任务完成后,QThread 会发出一个finished() 信号

编辑

如果你像这样定义一个自定义线程:

class CustomThread(QtCore.QThread):
    def __init__(self, target, slotOnFinished=None):
        super(CustomThread, self).__init__()
        self.target = target
        if slotOnFinished:
            self.finished.connect(slotOnFinished)

    def run(self, *args, **kwargs):
        self.target(*args, **kwargs)

你将能够做到:

class MyCustomWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyCustomWidget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)
        button = QtGui.QPushButton("Start", self)
        layout.addWidget(button)    
        button.clicked.connect(self.onStart)
        self.actionthread = CustomThread(target=self.longAction, self.onFinished)

    def onFinished(self):
        # Do Something

    def longAction(self):
        time.sleep(3)

    def onStart(self): 
        self.actionthread.start()

【讨论】:

今晚我将对其进行测试,如果它有效,请将您的 anwser 标记为好的。是否可以为该“自定义线程”创建一个装饰器以便能够传递它 2 个参数:要调用的方法,在处理结束时要回调的方法? 我刚刚编辑了我的答案。重写 CustomThread 类比使用装饰器更简单 CustomThread(target=self.longAction, self.onFinished) 行出现错误,因此不得不将其稍微更改为 CustomThread(self.longAction, self.onFinished)

以上是关于在 Python 中使用 PyQT 应用程序的主线程中的回调方法启动一个新线程的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中使用 PyQt5 创建后退按钮

在PyQt中构建 Python 菜单栏菜单和工具栏

如何在 PyQt4 中使用 QtGui 来收集 Python 程序的输入变量?

在PyQt中构建 Python 菜单栏菜单和工具栏

如何使 Python PyQT 程序无法在 Windows 中打开命令行

如何在Python PyQt中中断QThread上的脚本执行?