在 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 应用程序的主线程中的回调方法启动一个新线程的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PyQt4 中使用 QtGui 来收集 Python 程序的输入变量?