【发布时间】:2021-01-27 18:30:04
【问题描述】:
我正在使用 python 3.7 和 pyqt5
我想要做的是多次使用不同的线程运行相同的 QObject。
这是我的主要内容
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import threading
import sys
from Worker_Starting import Worker_Starting
class Main(QMainWindow):
def __init__(self) :
super().__init__()
self.setupUI()
self.initSignal()
def setupUI(self):
self.resize(400, 400)
self.pushButton = QPushButton("Start", self)
self.pushButton_2 = QPushButton("Stop", self)
self.pushButton.move(0,0)
self.pushButton_2.move(120,0)
def initSignal(self) :
self.pushButton.clicked.connect(self.Start)
self.pushButton_2.clicked.connect(self.Stop)
@pyqtSlot()
def Start(self) :
for i in range(3) :
print('main', threading.get_ident())
input = ["userID", "userNAME"]
self.my_thread = QThread()
self.my_worker = Worker_Starting(passing_list=input)
self.my_worker.moveToThread(self.my_thread)
self.my_thread.started.connect(self.my_worker.my_fn)
self.my_thread.start()
time.sleep(3)
@pyqtSlot()
def Stop(self) :
pass
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Main()
window.show()
app.exec_()
还有我的 Qobject
from PyQt5 import QtCore
from PyQt5.QtCore import *
import time
import threading
class Worker_Starting(QObject):
def __init__(self, passing_list, parent=None):
QtCore.QThread.__init__(self, parent=parent)
self.userid = passing_list[0]
self.username = passing_list[1]
def my_fn(self):
print(self.username, threading.get_ident())
for i in range(10) :
Now = time.strftime("%Y/%m/%d %H:%M:%S")
print(str(i) + " : " + self.username + " running" + " : " + Now)
time.sleep(0.5)
我把for i in range(3):放在def start(self):下面
因为在我的实际主脚本中,其他线程多次向def start(self): 发出输入。
如果我只发出一次,def start(self): 可以正常工作。
但是当我发射几次时,它就会崩溃。
因为我必须多次发射,我需要my_thread 才能同时连续工作
有没有办法将相同的 Qobject 设置到不同的线程?
以及如何知道或设置线程ID。
以及如何通过线程 id 停止线程。
*我已经尝试过 QRunnable,我现在可以使用多线程了。但我必须不断地向我的主发出信号。据我所知 QRunnable 不适合自定义信号。
【问题讨论】:
-
请注意,
Worker_Starting的声明继承自 QObject,但您改为调用QtCore.QThread.__init__。此外,没有必要创建一个新线程并将 QObject 移动到它,因为您通常可以只将 QThread 子类化。此外,你不应该在主线程中使用像time.sleep这样的阻塞函数(就像你在Start()中所做的那样)。 -
@musicamante 所以,如果我使用 QThread 而不是 QObject,那会解决我的问题吗? time.sleep 和 for i in range(3) 只是注意到我有几个 eimt 信号持续地启动()。
-
1.不,因为(正如我的回答中所解释的)问题是您不能在另一个线程上移动 QObject 而它仍在另一个线程上处理;我的反对意见是您(通常)不需要创建 QObject 子类并使用
moveToThread,因为从 QThread 子类化通常就足够了(只要按顺序调用每个“工作”函数,也就是没有并发来电)。 2. 没关系:no 阻塞函数应该永远发生在主 GUI 线程中,因为它们应该 总是 尽快返回;使用time.sleep不是。
标签: python multithreading pyqt qthread