我正在尝试学习Python和PyQt,虽然它的性能很好,但我在PyQt线程方面遇到了巨大的问题。我已经使用Python"线程"很好地工作了。模块,虽然我偶然发现了Seg Fault错误(没有附加信息)。
我想学习如何正确地使用PyQt进行线程化。我已经阅读了#34;你做错了#34;,"你没有这么做错#",Maya Posch的帖子,(跛脚)PyQt4和(稍微不那么蹩脚)PyQt5文档,以及大量有关如何操作的教程和示例(包括来自Stack-O的批量)和我只是变得越来越困惑。
我已经能够获得线程来启动Worker并执行其操作并返回数据。我可以毫无问题地退出,发射等,但是我无法将任何args传递给Worker。我是一个相当聪明的人,但这让我觉得自己像个完全白痴!每当我读到新的东西并尝试它时,我觉得我试图将一个方形钉子推入一个圆孔。
我正在使用" moveToThread"功能,而不是线程的子类,根据我读过的大多数帖子,这是正确的方法(虽然大多数例子显示为子类)。
我不是故意听起来像一个刺,但如果你可以帮助我,那么我需要的不仅仅是"只要你做什么就发送它" - 我需要一个真实的例子或明确的东西。我已经看到有人接近回答这个问题,但是他们非常模糊,Stack-O要求我有22个以上的声望点,以便我对其他人的帖子发表评论或提问...... ~~叹息
我有一个模拟我的大脚本的存根脚本。以下是存根中的相关代码:
def pre_Flight_Check():
#count = 0 # I want to pass THIS to the Worker at Worker's start
fire_Up_Thread(count)
#=====================
def butStop_click():
# Stop Loop/Thread:
flagQuit = flagQuit + 1
#=====================
# Worker:
class Worker(QObject):
finished = pyqtSignal()
intCount = pyqtSignal(int)
@pyqtSlot()
def looper(self):
flagQuit = 0
count = 0 # I'd like to pass this into the Worker, not define it here
while (count < 5):
self.intCount.emit(count)
time.sleep(1)
count = count + 1
if flagQuit != 0:
break
self.finished.emit()
#========================
objWorker = Worker()
thrWorker = QThread()
#========================
# Threading stuffs:
def fire_Up_Thread(count):
# NOTE: I CAN pass the "count" var into here, just not to the Worker
objWorker.moveToThread(thrWorker)
thrWorker.started.connect(objWorker.looper)
objWorker.intCount.connect(updateTextBox)
objWorker.finished.connect(thrWorker.quit)
objWorker.finished.connect(work_finished)
# Start the thread:
thrWorker.start()
仅供参考:这是使用Python线程的实现 - 它非常简单直接:
# Loop
def looper(count):
flagQuit = 0
while (count < 5):
print(count)
txtBox1.setText(str(count))
time.sleep(1)
count = count + 1
# User clicked "Stop" button
if flagQuit != 0:
break
work_finished()
#========================
def pre_Flight_Check():
# Var(s) to send to thread:
count = 0
# Start Loop/Thread
loopTest = threading.Thread(target=looper, args=(count,))
loopTest.setDaemon(True)
loopTest.start()
答案 0 :(得分:0)
初始化Worker
class Worker(QObject):
finished = pyqtSignal()
intCount = pyqtSignal(int)
def __init__(self, count):
super(Worker, self).__init__()
self.count = count
@pyqtSlot()
def looper(self):
flagQuit = 0
while (self.count < 5):
self.intCount.emit(self.count)
time.sleep(1)
self.count = self.count + 1
if flagQuit != 0:
break
self.finished.emit()
count = 0
objWorker = Worker(count)
答案 1 :(得分:0)
使用&#34;部分&#34;来自&#34; functools&#34; module允许变量被视为可调用的,然后可以使用该变量将args传递给Worker。这是原始行:
thrWorker.started.connect(objWorker.looper)
和修改后的行:
thrWorker.started.connect(partial(objWorker.looper,count,strIs))
现在重新编写整个存根以包含更改:
def pre_Flight_Check():
count = 0
strIs = "is: " # NOTE: this is only here to show that more than 1 variable can be included
fire_Up_Thread(count,strIs) # 2 vars to pass
#=====================
def butStop_click():
flagQuit = flagQuit + 1
#=====================
# Worker:
class Worker(QObject):
finished = pyqtSignal()
intCount = pyqtSignal(int)
@pyqtSlot()
def looper(self,count,strIs): # Both vars - "count" and "strIs"
flagQuit = 0
while (count < 5):
strCount = "The count " + strIs + str(count)
self.intCount.emit(count)
time.sleep(1)
count = count + 1
# User clicked "Stop" button
if flagQuit != 0:
break
self.finished.emit()
#========================
objWorker = Worker()
thrWorker = QThread()
#========================
# Threading stuffs:
def fire_Up_Thread(count,strIs): # Passed in from "pre_Flight_Check"
from functools import partial
objWorker.moveToThread(thrWorker)
thrWorker.started.connect(partial(objWorker.looper,count,strIs)) # All vars are appended to connected target
objWorker.intCount.connect(updateTextBox)
objWorker.finished.connect(thrWorker.quit)
objWorker.finished.connect(work_finished)
# Start the thread:
thrWorker.start()
这是有效的,它是线程安全的,它在处理方面很快且成本很低。