使用PyQt和Qthreads时GUI非常 sluggish

3 投票
2 回答
5238 浏览
提问于 2025-04-16 21:06

我在用PyQt和Qthreads做图形界面(GUI)时遇到了一个问题,想让界面保持流畅。我的做法是从GUI中启动一个工作线程,这个线程会进行一些计算,比较耗CPU。这个工作线程会在每个循环中发送一个信号,里面包含一个数字。在GUI中,这个信号连接到一个更新函数,这个函数会拿到这个数字,然后重新绘制界面。我用的是Qt的标准信号/槽机制。

从我在网上找到的关于PyQt、GUI和Qthreads的文档来看,这一切都很正常。但问题是,工作线程发送信号的频率太高,导致GUI变得很卡顿。一个解决办法是让工作线程发送信号的频率降低,但我希望能快速更新进度。

这一切看起来都很标准,但我就是找不到合适的解决方案。也许我需要改变一下设计?

任何帮助都非常感谢。

代码:

import calculator as ca

class GUI(QMainWindow):

    def __init__(self, config):
        QMainWindow.__init__(self)
        self.w_thread = WorkerThread()
        self.connect(self.w_thread, SIGNAL("update(PyQt_PyObject)"), self.update_gui)

    def start_calc(self):
        self.w_thread.start()

    def update_gui(self, progress_value):
        self.progress_value = progress_value
        self.repaint()

    def paintEvent(self, event):
        paint = QPainter()
        paint.begin(self)
        paint.drawText(300, 300, "progress: " + str(self.progress_value))
        paint.end()


class WorkerThread(QThread):

    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.wait()

    def run(self):
        ca.run_calculations(self)



*************** calculator.py ***************

def run_calculations(thread=None):

    while current_cycle < total_cycles:
        do_calculations()
        if current_cycle % 100 == 0:
            thread.emit(SIGNAL("update(PyQt_PyObject)"), current_progress_value)
        qApp.processEvents()
        current_cycle += 1

2 个回答

2

一个解决办法是让工作线程发出信号的频率降低,但我希望能快速更新进度。

因为人类的反应速度远远慢于计算机的处理速度,所以这是最好的解决方案,或者说是最简单的解决办法。即使图形界面每隔大约1/10到1/30秒才更新一次,你仍然可以得到“快速更新进度”的效果。

2

在工作线程的主循环中加入 qApp.processEvents() 似乎能解决这个问题。

撰写回答