在使用Python中的线程来显示Qt窗口中发生变化的值时,窗口会冻结

2024-09-29 01:24:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我的主要目标是在Qt窗口textEdit上显示一个不断变化的值(此窗口仅包含checkBoxtextEdit)。 遗憾的是,我不能点击复选框,窗口被冻结,直到我关闭终端

import sys
from threading import Thread
from random import randint
import time
from PyQt4 import QtGui,uic


class MyThread(Thread):

    def __init__(self):
        Thread.__init__(self)

    #function to continually change the targeted value
    def run(self):
        for i in range(1, 20):
            self.a = randint (1, 10)
            secondsToSleep = 1
            time.sleep(secondsToSleep)


class MyWindow(QtGui.QMainWindow,Thread):
    def __init__(self):
        Thread.__init__(self)
        super(MyWindow,self).__init__()
        uic.loadUi('mywindow.ui',self)
        self.checkBox.stateChanged.connect(self.checkeven)
        self.show()

    #i show the value only if the checkbox is checked
    def checkeven(self):
        while self.checkBox.isChecked():
            self.textEdit.setText(str(myThreadOb1.a)) 



# Run following code when the program starts
if __name__ == '__main__':
   app = QtGui.QApplication(sys.argv)


   # Declare objects of MyThread class
   myThreadOb1 = MyThread()
   myThreadOb2 = MyWindow()

   # Start running the threads!
   myThreadOb1.start()
   myThreadOb2.start()

   sys.exit(app.exec_())

目前,我正在使用一个线程将随机值设置为a,但最后它应该更复杂一些,因为我将不得不从自动化中获取值

你知道为什么我的代码会这样吗? 非常感谢你的帮助


Tags: thefromimportselfinitdefsysthread
1条回答
网友
1楼 · 发布于 2024-09-29 01:24:37

问题是while self.checkBox.isChecked()被阻塞,阻止GUI处理其他事件

此外,您不应该在主线程之外的其他线程上运行PyQt GUI

如果您想将数据从一个线程发送到另一个线程,一个好的选择是使用信号

考虑到所有这些因素,我们有以下几点:

import sys
from threading import Thread
from random import randint
import time
from PyQt4 import QtGui, uic, QtCore


class MyThread(Thread, QtCore.QObject):
    aChanged = QtCore.pyqtSignal(int)

    def __init__(self):
        Thread.__init__(self)
        QtCore.QObject.__init__(self)
    #function to continually change the targeted value
    def run(self):
        for i in range(1, 20):
            self.aChanged.emit(randint(1, 10))
            secondsToSleep = 1
            time.sleep(secondsToSleep)


class MyWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        uic.loadUi('mywindow.ui',self)
        self.thread = MyThread()
        self.thread.aChanged.connect(self.on_a_changed, QtCore.Qt.QueuedConnection)
        self.thread.start()
        self.show()

    #i show the value only if the checkbox is checked
    @QtCore.pyqtSlot(int)
    def on_a_changed(self, a):
        if self.checkBox.isChecked():
            self.textEdit.setText(str(a)) 



# Run following code when the program starts
if __name__ == '__main__':
   app = QtGui.QApplication(sys.argv)


   # Declare objects of MyThread class
   w = MyWindow()

   sys.exit(app.exec_())

Qt样式的一个更好的选择是使用QThread,因为它是一个处理线程的类,也是一个QObject,所以它可以轻松地处理信号

import sys
from random import randint
from PyQt4 import QtGui, uic, QtCore


class MyThread(QtCore.QThread):
    aChanged = QtCore.pyqtSignal(int)
    def run(self):
        for i in range(1, 20):
            self.aChanged.emit(randint(1, 10))
            secondsToSleep = 1
            QtCore.QThread.sleep(secondsToSleep)


class MyWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        uic.loadUi('mywindow.ui',self)
        self.thread = MyThread()
        self.thread.aChanged.connect(self.on_a_changed, QtCore.Qt.QueuedConnection)
        self.thread.start()
        self.show()

    #i show the value only if the checkbox is checked
    @QtCore.pyqtSlot(int)
    def on_a_changed(self, a):
        if self.checkBox.isChecked():
            self.textEdit.setText(str(a)) 



# Run following code when the program starts
if __name__ == '__main__':
   app = QtGui.QApplication(sys.argv)


   # Declare objects of MyThread class
   w = MyWindow()

   sys.exit(app.exec_())

相关问题 更多 >