【问题标题】:Keep PyQt UI Responsive With Threads保持 PyQt UI 对线程的响应
【发布时间】:2016-09-23 21:06:26
【问题描述】:

我已经创建了一个相对复杂的 PyQt 程序,并且正在尝试实现线程,以便当程序遇到特别占用 CPU 的程序部分时,GUI 将始终保持刷新和响应。但遗憾的是,我在线程方面遇到了一些困难。

我使用 Python 2.7 的原因我认为不相关。

无论如何,整个程序在一个类中运行并调用 PyQt 设计器 .ui 文件以显示实际的 GUI。当按下特定按钮时,为了切碎文件,它会调用该类中的一个函数,然后使用“线程”模块启动一个线程,是的,过时了,我知道。然后从这里调用的粉碎函数开始粉碎文件。在整个文件的粉碎过程中,实际的粉碎功能会与 GUI 交互并向 GUI 添加位,以便让用户及时了解正在发生的事情。

在函数执行期间,GUI 会继续刷新,但它确实变得有点滞后,我可以应付。然而,当该功能完成时,程序并没有顺利继续并允许用户继续使用该程序,而是完全停止工作并不得不关闭。

希望有人可以在这里帮助我。我非常感谢尽可能多的细节,因为我已经寻找了好几个星期来解决这个问题的方法。

我正在使用 PyQt4。

【问题讨论】:

  • 欢迎来到 Stackoverflow!请提供Minimal, Complete and Working 代码示例,以便我们更好地帮助您!
  • 您是否尝试过在主线程中添加打印语句来显示有关程序状态的信息——即它到底在尝试做什么、正在使用多少内存、正在使用多少 CPU等?
  • 您可以考虑使用这些替代方案来使用线程来处理大量 CPU 使用。 1. 将 CPU 工作划分为 0.01 秒的块,并在安排下一个块后将控制权交还给 GUI。在 tkinter 中,人们会使用 root.after。在 3.4+ asyncio 中,loop.soon。 2. 使用多处理而不是线程。在多核机器上,它可以在另一个核上运行。如果“粉碎文件”的意思是我的想法,那么您的实际问题可能是磁盘 i/o 阻塞,而不是 CPU 使用。

标签: python multithreading user-interface crash python-multithreading


【解决方案1】:

这是一个简单的 pyqt5 线程演示。 Qt 有自己的线程类,效果很好。

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal
import sys
import time

class TheBoss(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(TheBoss, self).__init__(parent)
        self.resize(300,200)
        self.VL = QtWidgets.QVBoxLayout(self)
        self.label = QtWidgets.QLabel()
        self.VL.addWidget(self.label)
        self.logger = Logger()
        self.logger.sec_signal.connect(self.label.setText)
        self.logger.start()

    def closeEvent(self,event):
        self.logger.terminate()

class Logger(QtCore.QThread):
    sec_signal = pyqtSignal(str)
    def __init__(self, parent=None):
        super(Logger, self).__init__(parent)
        self.current_time = 0
        self.go = True
    def run(self):
        #this is a special fxn that's called with the start() fxn
        while self.go:
            time.sleep(1)
            self.sec_signal.emit(str(self.current_time))
            self.current_time += 1

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setApplicationName("Thread Example")
    window = TheBoss()
    window.show()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多