Pyqt5 线程、计时器、UI卡顿

在Pyqt5程序中经常出现耗时的操作,这个时候一般使用Qthread或者Qtimer将耗时操作交给新的线程。

今天发现了一个导致UI卡顿的情形,代码如下:

from PyQt5 import QtWidgets
import sys
from PyQt5.QtCore import *
import time

class UI_(object):
    def __init__(self, parent=None):
        self.textEdit = QtWidgets.QListWidget(parent=parent)
        self.textEdit.setGeometry(QRect(0, 0, 100, 100))

        self.bn = QtWidgets.QPushButton(text='点击', parent=parent)
        self.bn.setGeometry(QRect(100, 250, 40, 20))

        self.tex = QtWidgets.QPlainTextEdit(parent=parent)
        self.tex.setGeometry(QRect(300, 300, 100, 100))
        self.bn.clicked.connect(self.act)
    def act(self):
        self.timer = QTimer()
        self.timer.timeout.connect(self.pp)
        self.timer.start(1000)

    def pp(self):
    	# 发送报文
        time.sleep(0.4)
        # 接收报文
        print(str(1))

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()
    window.setGeometry(QRect(500, 500, 400, 400))
    ui = UI_(window)
    window.show()
    app.exec_()

这段代码模拟端口每隔1秒向服务器发送报文,在发送报文0.4秒后读取服务器返回内容。这个时候会出现UI界面卡顿的情况。这是因为time库是由python写的,Qt是由cpp写的,在sleep等待时,Qt程序被迫阻塞。

解决方法:将timer.sleep()放在QThread中。

from PyQt5 import QtWidgets
import sys
from PyQt5.QtCore import *
import time

class UI_(object):
    def __init__(self, parent=None):
        self.textEdit = QtWidgets.QListWidget(parent=parent)
        self.textEdit.setGeometry(QRect(0, 0, 100, 100))

        self.bn = QtWidgets.QPushButton(parent=parent)
        self.bn.setGeometry(QRect(100, 250, 20, 20))

        self.tex = QtWidgets.QPlainTextEdit(parent=parent)
        self.tex.setGeometry(QRect(300, 300, 100, 100))

        self.work = WorkThread()
        self.bn.clicked.connect(self.act)
    def act(self):
        self.work.start()
        self.work.sig.connect(self.display)

    def display(self, str):
        self.textEdit.addItem(str)

class WorkThread(QThread):
    # 自定义信号对象,参数str表示这个信号可以传递一个字符串
    sig = pyqtSignal(str)
    def __init__(self):
        super().__init__()

    # 重写线程执行的run函数触发自定义信号
    def run(self):
        while True:
            time.sleep(1)
            # 通过自定义信号把待显示的字符串传递给槽函数
            self.sig.emit(str(1))
            
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()
    window.setGeometry(QRect(500, 500, 400, 400))
    ui = UI_(window)
    window.show()
    app.exec_()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值