PyQt5 - 使用QThread更新Qtablewidget

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyQt5 - 使用QThread更新Qtablewidget相关的知识,希望对你有一定的参考价值。

有人可以帮助我,应用只是崩溃。

我做了研究,发现this,下面是我的代码:

from PyQt5.QtCore import QThread, pyqtSignal
import threading
import time

class Job(QThread):
    data_downloaded = pyqtSignal(str)

    def __init__(self, url):
        QThread.__init__(self)
        # self.__flag = threading.Event()
        # self.__flag.set()
        # self.__running = threading.Event()
        # self.__running.set()


    def run(self):
        for i in range(100):
            self.data_downloaded.emit("B")  # 朝connect的函数发射一个进度信号
            time.sleep(1)

    # def pause(self):
    #     self.__flag.clear()     # 设置为False, 让线程阻塞
    #
    # def resume(self):
    #     self.__flag.set()    # 设置为True, 让线程停止阻塞
    #
    # def stop(self):
    #     self.__flag.set()       # 将线程从暂停状态恢复, 如何已经暂停的话
    #     self.__running.clear()        # 设置为False

主窗口:

from xxx import Job 
class SearchWindow(QWidget):
    ......
    ...... # There's a QTableWidget on main window, after right clicked "Start Download", Job will be created 
    ......

    def right_click_from_download_list_context(self):
        row_num = []
        for i in self.download_list.selectionModel().selection().indexes():
            row_num.append(i.row())
        popMenu = QMenu(self)
        self.start_download_action = QAction('Start Download', self)
        self.remove_task_action = QAction('删除此任务', self)
        self.start_download_action.triggered.connect(self.start_download)
        self.remove_task_action.triggered.connect(partial(self.remove_task, row_num))
        popMenu.addAction(self.start_download_action)
        popMenu.addAction(self.remove_task_action)
        popMenu.exec_(QCursor.pos())

    def start_download(self):
        print("AAAA")
        downloader = Job("http://www.baidu.com")
        print("BBB")
        downloader.data_downloaded.connect(self.update_download_process)
        print("ccc")
        downloader.start()
        print("ddd")

    @pyqtSlot(str)
    def update_download_process(self, data_process):
        print(data_process)

我做了一些调试,“AAAA”,“BBB”,“ccc”,“ddd”可以成功打印出来,所以我猜错误是在我的Job QThread中。

有人帮我一个忙,我就是找不到错误的地方。提前致谢 :)

答案

问题是因为只要函数执行,函数内创建的变量只存在,并且downloader的消除也将消除该线程。为此,有两种解决方案:

  • 成为班级的downloader成员:

def start_download(self):
    print("AAAA")
    self.downloader = Job("http://www.baidu.com")
    print("BBB")
    self.downloader.data_downloaded.connect(self.update_download_process)
    print("ccc")
    self.downloader.start()
    print("ddd")
  • 将父母传递给工作:

class Job(QThread):
    data_downloaded = pyqtSignal(str)

    def __init__(self, url, parent=None):
        QThread.__init__(self, parent)

    [...]


class SearchWindow(QWidget):
    [...]
    def start_download(self):
        print("AAAA")
        downloader = Job("http://www.baidu.com", self)
        print("BBB")
        downloader.data_downloaded.connect(self.update_download_process)
        print("ccc")
        downloader.start()
        print("ddd")

以上是关于PyQt5 - 使用QThread更新Qtablewidget的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5:使用 QObject 和 QThread 时出现 AttributeError

PyQt5 OpenCV 网络摄像头使用 QThread

PyQt5 - 即使使用 QThread,MainWindow 中的 QMovie 也无法播放

使用 concurrent.futures.ThreadPoolExecutor() 时的 PyQt5 小部件 Qthread 问题

PyQt5:如何在 QThread 和某些子类之间“通信”?

PyQt5 UI 制作一个豆瓣电影信息查看器,初识QThread多线程...