繁体   English   中英

我如何在不影响其他事件的情况下实时更新文本(pyqt)

[英]how can i real time update the text without affecting other event(pyqt)

在我的程序中,我想不断地将文本设置到文本浏览器中,但是当我单击另一个按钮时似乎有延迟。 有我的代码:

class Ui_MainWindow(QWidget):
  def __init__(self):
    QWidget.__init__(self)
    self.setupUi(self)
    self.th0 = TestThread()
    self.pushButton.clicked.connect(self.runthread)

  def runthread(self):
    self.th0.start()
    self.chilWid.Consumer()
    QtGui.qApp.processEvents()

  def setupUi(self, Widget):             
    self.gridLayout = QtGui.QGridLayout()
    self.pushButton = QtGui.QPushButton()
    self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
    self.chilWid = ChildWid()
    self.gridLayout.addWidget(self.chilWid, 1, 0, 1, 1)

    self.setLayout(self.gridLayout)

manager = Manager()
manager2 = Manager()
q = manager.Queue()
q2 =manager2.Queue()
l = manager.Lock()
l2 =manager2.Lock()

此类是将控制生产者的线程

class TestThread(QThread):
 def __init__(self):
    QThread.__init__(self)
    self.t = ChildWid()
 def run(self):
    while (not self.stopped):
        ps0 = Process(target=Producer, args=(q, l, 'eth0', q2, l2))        
        #### Producer is another program that will generate 
             text continually and save into q
        ps0.start()    

此类仅包含文本浏览器,并将由MainWindow类插入。 它还从队列中收集数据并在文本浏览器中显示

class ChildWid(QWidget):
 def __init__(self):
    QWidget.__init__(self)
    self.text = QTextEdit()
    self.lay = QHBoxLayout(self)
    self.lay.addWidget(self.text)

 def Consumer(self):
    global q, q2, q3,l,l2,l3
    while True:
        try:
            task = q.get(block=False)
            QtGui.qApp.processEvents()
            self.text.setText(str(task))
        except:
            pass

当我单击pushButton ,文本浏览器将正常显示Producer生成的文本。 但是另一个按钮,例如pushbutton或整个用户界面响应却非常慢。 对我有什么建议吗? 谢谢

**********新更新

class TestThread(QThread,QObject):
testsinal = pyqtSignal(str)

def __init__(self):
     . . .
    self.t = ChildWid()

def TestSignal(self):
    self.testsinal.emit('some text message')
    self.testsinal.connect(self.handle)
@QtCore.pyqtSlot(str)
def handle(self,str):
    print str
    self.t.text.setText(str)

def run(self):
    print"Thread run normally"
    while (self.stopped):
        ps0 = Process(target=L2PS_v1a4.main, args=(q, l, 'eth0', q2, l2, q3))
        ps0.start()

        self.TestSignal()

带有while循环阻塞的Consumer方法看起来真的很讨厌。 它试图像某种伪造的事件循环一样工作,但它无法像真实事物一样高效地运行。 摆脱它。

正确的方法是在TestThread类上定义一个自定义信号,然后使用它从run()方法内发出文本消息。 跨线程信号是线程安全的,并被发布到接收线程的事件队列中。 这意味着它们是异步处理的,因此不会阻塞GUI:

class TestThread(QThread):
    testSignal = QtCore.pyqtSignal(str)
    ...

    def run(self):
        while (not self.stopped):
            ps0 = Process(target=Producer, args=(q, l, 'eth0', q2, l2))        
            ps0.start()
            self.testSignal.emit('some text message')


class ChildWid(QWidget):
    ...

    QtCore.pyqtSlot(str)
    def handleTestSignal(self, message):
        print(message)
        self.text.setText(message)


class Ui_MainWindow(QWidget):
    def __init__(self):
        ...
        self.th0.testSignal.connect(self.chilWid.handleTestSignal)

暂无
暂无

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

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