直接从QThread更改GUI的方法 PyQt 5

3

您好,我已向我的线程工作程序发送了 GUI 链接,并直接从 QThread 更新 GUI 信息。就像这样:

class Worker(QThread):
  def __init__(self, ui):
    QThread.__init__(self)
    self.running = False
    self.ui = ui

  def run(self):
    self.running = True
    while self.running:
        info = self.check_info()
        rows = len(info)
        self.ui.tableWidget.setRowCount(rows)
        self.ui.tableWidget.setColumnCount(6) 
        ...

在主要的QMainWindow中,我只是添加了以下内容。
def __init__(self, parent=None):
    .......
    self.myworker = Worker(self.ui)
    .....

这个解决方案在PyQt5中很糟糕吗?我是PyQt的新手。谢谢。如果我的解决方案不好,请帮我修复它。

1
你不应该在除了主线程之外的其他线程中更新GUI,必须使用信号和槽将信息从辅助线程发送到主线程。 - eyllanesc
info的类型是什么? - eyllanesc
我可以通过信号发送任何信息吗?例如,我通过执行线程收到的字典列表。 - Hellbea
info 是字典列表。 - Hellbea
check_info- 必须是无限循环,直到用户按下停止按钮。 - Hellbea
显示剩余6条评论
1个回答

3

在次要线程中,您不能直接更新GUI,必须通过信号和槽实现:

为此,我们将通过类pyqtSignal()创建一个信号,并指定参数类型,然后将其连接到所需的槽上,如下所示:

线程:

class Worker(QThread):
    list_of_dict_signals = pyqtSignal(list)
    str_signal = pyqtSignal(str)
    def __init__(self,  parent=None):
        QThread.__init__(self, parent)
        self.running = False

    def run(self):
        self.running = True
        while self.running:
            info = self.check_info()
            self.list_of_dict_signals.emit(info)
            self.str_signal.emit("Requesting info")

GUI:

def __init__(self, parent=None):
    .......
    self.myworker = Worker(self)
    self.myworker.list_of_dict_signals.connect(self.onDataFromThread)
    self.myworker.str_signal.connect(self.ui.statusbar.showMessage)
    self.myworker.start()

def onDataFromThread(self, info):
    rows = len(info)
    self.ui.tableWidget.setRowCount(rows)
    ...

谢谢你提供的解决方案,我们是用 def onDataFromThread 做什么的? - Hellbea
在这个函数中,你将会收到一个字典列表,也就是说,每当你发送信号,该信号会携带字典列表并调用该函数,在这里你必须更新ui.tableWidget。 - eyllanesc
非常感谢您的回答,现在我明白了信号槽是如何工作的。我已经标记了。 - Hellbea
我建议您学习信号、槽和事件。它们是Qt和PyQt的重要组成部分。 - eyllanesc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接