首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyQt5动态运行同一线程

PyQt5动态运行同一线程
EN

Stack Overflow用户
提问于 2020-10-13 20:01:48
回答 1查看 175关注 0票数 1

我使用的是Python3.7和pyqt5

我想做的是用不同的线程多次运行相同的QObject。

以下是我的主要内容

代码语言:javascript
复制
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对象

代码语言:javascript
复制
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不适合自定义信号。

EN

回答 1

Stack Overflow用户

发布于 2020-10-13 21:08:23

问题是,您不断地通过覆盖现有线程来创建新线程,这会导致前一个线程在完成之前被垃圾收集,从而导致崩溃。

如果你想并发执行相同的"worker“函数,你不能为多个线程使用一个对象,因为你应该每次都使用moveToThread,而这是不可能的。

解决方案是改用QRunnable,在其run()方法中实现该函数,然后调用QThreadPool来运行它。

代码语言:javascript
复制
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:

代码语言:javascript
复制
        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()装饰器通常只在特殊情况下和高级实现时才需要,因此您应该删除它。还要注意,只有类和常量的名称应该是大写的,而函数、变量和属性应该是小写的(优先使用startstop,而不是StartStop)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64334862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档