为什么我的 QThread class 会大大降低 PyQT5 应用程序的速度?

Why my QThread class drastically slows PyQT5 app?

我遇到了线程问题。我正在显示当前 CPU 使用进度条,它似乎运行良好,但整个 window 的性能很糟糕。没有滞后行为甚至无法单击按钮。有什么简单的解决办法可以解决吗?

这是我的主要代码

from PyQt5 import QtCore, QtGui,  QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal


import progressBarUI
import sys
import sysnfo


class MainWindow(QtWidgets.QMainWindow, progressBarUI.Ui_MainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.threadclass = ThreadClass()
        self.threadclass.start()
        self.threadclass.signal.connect(self.updateProgressBar)

    def updateProgressBar(self):
        current_percentage = sysnfo.getCpuPercentage()
        self.progressBar.setValue(current_percentage)


class ThreadClass(QThread):
    signal = pyqtSignal(int)

    def __init__(self, parent=None):
        super(ThreadClass, self).__init__(parent)

    def run(self):
        while True:
            current_percentage = sysnfo.getCpuPercentage()
            self.signal.emit(current_percentage)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainAppWin = MainWindow()
    mainAppWin.show()
    app.exec_()

这里是 sysnfo 模块:

import psutil as ps

def getCpuPercentage():
    return ps.cpu_percent(interval=1)

和UI文件(转换为.py文件):


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(787, 203)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(370, 20, 381, 111))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")


        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(20, 50, 151, 41))
        self.pushButton.setObjectName("pushButton")

        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 787, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Click me"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

当您使用 "interval" 参数时,您表示它会测量该时间段内的信息并计算导致该函数执行花费 "interval" 秒的平均值,正确的是在另一个线程中执行它,但你也错误地在主线程中阻塞它的 updateProgressBar 方法中执行它,而是使用向你发送信号的信息:

@QtCore.pyqtSlot(int)
def updateProgressBar(self, percentage):
    self.progressBar.setValue(percentage)