繁体   English   中英

如何在pyQt4中的不同线程中清除QTextEdit

[英]how to clear QTextEdit in different thread in pyQt4

我有一个QTextEdit组件在我的程序的“主”线程中创建然后我启动另一个线程,它将每隔x秒更新此QTextEdit,但后来我得到此错误:

QObject: Cannot create children for a parent that is in a different thread.

这就是我这样做的方式:

def initGui():
   #some gui components
   global txt_list

   txt_list = QtGui.QTextEdit(w)
   txt_list.resize(580,400)
   txt_list.move(50, 50)
   txt_list.setReadOnly(1)
   txt_list.setFont(font_consolas)
   #more gui components

def update_list():
   t_monitor = threading.Thread(target=monitor_vector)
   t_monitor.daemon = True
   t_monitor.setName('monitor')
   t_monitor.start()

def monitor_vector():
   #retrieve info...
   lock = threading.Lock
   lock = True
   txt_list.clear() #clear list, to set the new one
   txt_list.setText('updated list')
   lock = False

这最后两行代码给出了上面提到的错误。 有人能给我一个如何处理这个问题的线索吗?

谢谢!

关于Qt的一个主要问题是你不能从主GUI线程以外的任何线程调用任何QWidget方法。 所有的通信都必须通过从额外线程发出信号来完成,这些信号将转发到主gui。

首先,我看到你正在使用全局变量,并且缺少self关键字,所以我假设你没有使用类。 我的例子也将包含一个类示例。

这个例子很简单,就像你的一样,概述了你可能想要的方向:

from PyQt4 import QtGui, QtCore

class MyWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        ...
        self.txt_list = QtGui.QTextEdit(self)
        self.txt_list.resize(580,400)
        self.txt_list.move(50, 50)
        self.txt_list.setReadOnly(1)
        self.txt_list.setFont(font_consolas)
        ...
        self.monitor = Monitor()
        self.monitor.updateText.connect(self._handleTextUpdate)
        self.monitor.update_list()

    def _handleTextUpdate(self, txt):
        self.txt_list.clear()
        self.txt_list.setText(txt)


class Monitor(QtCore.QObject):

    updateText = QtCore.pyqtSignal(str)

    def update_list(self):
        t_monitor = Thread(self.monitor_vector, parent=self)
        t_monitor.daemon = True
        t_monitor.setName('monitor')
        t_monitor.start()

    def monitor_vector(self):
        ...
        self.updateText.emit('updated list')


class Thread(QtCore.QThread):

    def __init__(self, fn, args, kwargs, parent=None):
        super(Thread, self).__init__(parent)
        self._fn = fn 
        self._args = args 
        self._kwargs = kwargs 

    def run(self):
        self._fn(*self._args, **self._kwargs)

需要注意的主要是线程中运行的函数是发出信号。 他们不了解其他课程中的QWidgets。 您的MyWidget类将信号连接到可以更新QLineEdit的插槽。 当线程发出信号时,它将排队到主线程并由接收槽执行。

我还创建了一个简单的QThread子类,它可以接受一个函数和args,复制标准的lib Thread类的工作方式。 您应该坚持使用QThread,因为它是一个QObject子类,并且支持信号并且可以运行事件循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM