我使用的是Python3.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_()和我的Q对象
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不适合自定义信号。
发布于 2020-10-13 21:08:23
问题是,您不断地通过覆盖现有线程来创建新线程,这会导致前一个线程在完成之前被垃圾收集,从而导致崩溃。
如果你想并发执行相同的"worker“函数,你不能为多个线程使用一个对象,因为你应该每次都使用moveToThread,而这是不可能的。
解决方案是改用QRunnable,在其run()方法中实现该函数,然后调用QThreadPool来运行它。
class Worker_Starting(QRunnable):
def __init__(self, passing_list):
QRunnable.__init__(self)
self.setAutoDelete(False)
self.userid = passing_list[0]
self.username = passing_list[1]
def run(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)
class Main(QMainWindow):
def __init__(self) :
super().__init__()
self.setupUI()
self.initSignal()
self.worker = None
# ...
def Start(self) :
if not self.worker:
input = ["userID", "userNAME"]
self.worker = Worker_Starting(passing_list=input)
for i in range(3):
print('main', threading.get_ident())
QThreadPool.globalInstance().start(self.worker)请记住,您不应该在主Qt线程中使用阻塞函数(这就是我从Start()中删除time.sleep(3)的原因)。如果您希望定期多次启动该函数,请使用QTimer:
interval = 3000 # interval is in milliseconds
for i in range(3):
print('main', threading.get_ident())
QTimer.singleShot(interval * i, lambda:
QThreadPool.globalInstance().start(self.worker))请注意,pyqtSlot()装饰器通常只在特殊情况下和高级实现时才需要,因此您应该删除它。还要注意,只有类和常量的名称应该是大写的,而函数、变量和属性应该是小写的(优先使用start和stop,而不是Start和Stop)。
https://stackoverflow.com/questions/64334862
复制相似问题