python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > PyQt5界面无响应

PyQt5界面无响应的解决方案

作者:Lorin洛林

如果在主线程执行耗时操作,比如 循环、sleep、wait 异步线程执行 会导致 UI 界面进入无响应状态,我们可以采用以下两种方式异步处理:使用QThread 或 QTimer,本文给大家介绍了PyQt5界面无响应的解决方案,需要的朋友可以参考下

前言

版本

案例

import sys
import time

from PyQt5.QtWidgets import QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout


class MyWidget(QWidget):
    def __init__(self):
        super(MyWidget, self).__init__()
        self.currentValue = 0

        self.progressBar = QProgressBar(self)
        self.progressBar.resize(200, 50)
        self.progressBar.move(20, 20)
        self.progressBar.setValue(self.currentValue)

        # 创建一个按钮
        self.button = QPushButton('点击我', self)
        self.button.clicked.connect(self.on_clicked)

        # 创建一个垂直布局,并将按钮添加到布局中
        layout = QHBoxLayout()
        layout.addWidget(self.progressBar)
        layout.addWidget(self.button)

        # 设置窗口的主布局为垂直布局
        self.setLayout(layout)

    def on_clicked(self):
        while True:
            time.sleep(2)
            self.currentValue = (self.currentValue + 1) % 101
            self.progressBar.setValue(self.currentValue)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWidget()
    w.resize(500, 300)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    w.show()
    sys.exit(app.exec_())

解决方案

QThread

import sys
import time

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout


class MyWorker(QThread):
    timeout = pyqtSignal()

    def __init__(self):
        super(MyWorker, self).__init__()

    def run(self):
        while True:
            time.sleep(2)
            self.timeout.emit()


class MyWidget(QWidget):
    def __init__(self):
        super(MyWidget, self).__init__()
        self.worker = None
        self.currentValue = 0

        self.progressBar = QProgressBar(self)
        self.progressBar.resize(200, 50)
        self.progressBar.move(20, 20)
        self.progressBar.setValue(self.currentValue)

        # 创建一个按钮
        self.button = QPushButton('点击我', self)
        self.button.clicked.connect(self.on_clicked)

        # 创建一个垂直布局,并将按钮添加到布局中
        layout = QHBoxLayout()
        layout.addWidget(self.progressBar)
        layout.addWidget(self.button)

        # 设置窗口的主布局为垂直布局
        self.setLayout(layout)

    def on_clicked(self):
        self.worker = MyWorker()
        self.worker.timeout.connect(self.upgradeProgress)
        self.worker.start()

    def upgradeProgress(self):
        self.currentValue = (self.currentValue + 1) % 101
        self.progressBar.setValue(self.currentValue)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWidget()
    w.resize(500, 300)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    w.show()
    sys.exit(app.exec_())

运行效果:

QTimer

import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout


class MyWidget(QWidget):
    def __init__(self):
        super(MyWidget, self).__init__()
        self.currentValue = 0

        self.progressBar = QProgressBar(self)
        self.progressBar.resize(200, 50)
        self.progressBar.move(20, 20)
        self.progressBar.setValue(self.currentValue)

        # 创建一个按钮
        self.button = QPushButton('点击我', self)
        self.button.clicked.connect(self.on_clicked)

        # 创建一个垂直布局,并将按钮添加到布局中
        layout = QHBoxLayout()
        layout.addWidget(self.progressBar)
        layout.addWidget(self.button)

        # 设置窗口的主布局为垂直布局
        self.setLayout(layout)

    def on_clicked(self):
        # 定义一个定时器并启动定时器
        self.time = QTimer()
        self.time.timeout.connect(self.upgradeProgress)
        self.time.start(200)

    def upgradeProgress(self):
        self.currentValue = (self.currentValue + 1) % 101
        self.progressBar.setValue(self.currentValue)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWidget()
    w.resize(500, 300)
    w.move(300, 300)
    w.setWindowTitle('Simple')
    w.show()
    sys.exit(app.exec_())

局部变量创建异步线程导致 UI 未响应

    def on_clicked(self):
        worker = MyWorker()
        worker.timeout.connect(self.upgradeProgress)
        worker.start()

如果 QTimer 不使用 self.time 写法

到此这篇关于PyQt5界面无响应的解决方案的文章就介绍到这了,更多相关PyQt5界面无响应内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文