从线程监控更新进度条CPUactivity
Update progress bar from thread monitoring CPU activity
我的代码出现此错误:
RuntimeWarning: MetaObjectBuilder::addMethod: Invalid method signature provided for "CPU_VALUE"
self.threadclass.CPU_VALUE.connect(SIGNAL('CPU_VALUE'), self.UpdateProgressBar)
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import SIGNAL, Signal
import main
import sysinfo
class MainUiClass(main.Ui_MainWindow, QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainUiClass, self).__init__(parent)
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.threadclass.CPU_VALUE.connect(SIGNAL('CPU_VALUE'), self.UpdateProgressBar)
# self.UpdateProgressBar()
def UpdateProgressBar(self):
val = sysinfo.getCPU()
self.progressBar.setValue(val)
class CpuClass(QtCore.QObject):
cpu = Signal()
class ThreadClass(QtCore.QThread):
CPU_VALUE = CpuClass()
cpu = Signal()
def __init__(self, parent=None):
super(ThreadClass, self).__init__(parent)
def run(self):
while 1:
# val = sysinfo.getCPU()
self.CPU_VALUE.emit(SIGNAL('CPU_VALUE'), sysinfo.getCPU())
# print(val)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
a = MainUiClass()
a.show()
app.exec_()
系统信息文件:
import psutil
def getCPU():
return psutil.cpu_percent(interval=1)
你的例子有几个问题。首先,您混合了 old-style 和 new-style 信号,这很混乱且没有必要。 Old-style 永远不要在新的应用程序中使用信号。其次,您正在使用信号对象 (CpuSignal
),这是不必要的,因为信号可以直接在 QThread
class 上定义。第三,您没有在信号中发出 cpu 百分比的值,因此进度条将永远不会更新。最后,您还没有提供彻底关闭线程的机制。
在下面的演示脚本中,上述所有问题都已修复,我还添加了一个 Simulator
class 来生成 cpu-activity 以供测试。单击“测试”按钮将产生大约二十秒的 activity,然后 progress-bar 将相应更新:
import psutil
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Signal
class MainUiClass(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.progress = QtWidgets.QProgressBar()
self.button = QtWidgets.QPushButton('Test')
self.button.clicked.connect(self.handleButton)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.progress)
layout.addWidget(self.button)
self.monitor = CpuMonitor()
self.monitor.cpuPercent.connect(self.progress.setValue)
self.monitor.start()
self.simulator = Simulator()
def handleButton(self):
if not self.simulator.isRunning():
self.simulator.start()
def closeEvent(self, event):
for thread in self.simulator, self.monitor:
thread.stop()
thread.quit()
thread.wait()
class CpuMonitor(QtCore.QThread):
cpuPercent = Signal(int)
def run(self):
self._stopped = False
while not self._stopped:
value = int(psutil.cpu_percent(interval=1))
self.cpuPercent.emit(value)
def stop(self):
self._stopped = True
class Simulator(QtCore.QThread):
def run(self):
self._stopped = False
random = QtCore.QRandomGenerator.system()
timer1 = QtCore.QDeadlineTimer(20000)
while not self._stopped and not timer1.hasExpired():
duration = random.bounded(400, 800)
self.msleep(duration)
timer2 = QtCore.QDeadlineTimer(duration)
while not self._stopped and not timer2.hasExpired():
pass
def stop(self):
self._stopped = True
if __name__ == '__main__':
app = QtWidgets.QApplication(['CPU Monitor'])
a = MainUiClass()
a.show()
app.exec_()
我的代码出现此错误:
RuntimeWarning: MetaObjectBuilder::addMethod: Invalid method signature provided for "CPU_VALUE"
self.threadclass.CPU_VALUE.connect(SIGNAL('CPU_VALUE'), self.UpdateProgressBar)
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import SIGNAL, Signal
import main
import sysinfo
class MainUiClass(main.Ui_MainWindow, QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainUiClass, self).__init__(parent)
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.threadclass.CPU_VALUE.connect(SIGNAL('CPU_VALUE'), self.UpdateProgressBar)
# self.UpdateProgressBar()
def UpdateProgressBar(self):
val = sysinfo.getCPU()
self.progressBar.setValue(val)
class CpuClass(QtCore.QObject):
cpu = Signal()
class ThreadClass(QtCore.QThread):
CPU_VALUE = CpuClass()
cpu = Signal()
def __init__(self, parent=None):
super(ThreadClass, self).__init__(parent)
def run(self):
while 1:
# val = sysinfo.getCPU()
self.CPU_VALUE.emit(SIGNAL('CPU_VALUE'), sysinfo.getCPU())
# print(val)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
a = MainUiClass()
a.show()
app.exec_()
系统信息文件:
import psutil
def getCPU():
return psutil.cpu_percent(interval=1)
你的例子有几个问题。首先,您混合了 old-style 和 new-style 信号,这很混乱且没有必要。 Old-style 永远不要在新的应用程序中使用信号。其次,您正在使用信号对象 (CpuSignal
),这是不必要的,因为信号可以直接在 QThread
class 上定义。第三,您没有在信号中发出 cpu 百分比的值,因此进度条将永远不会更新。最后,您还没有提供彻底关闭线程的机制。
在下面的演示脚本中,上述所有问题都已修复,我还添加了一个 Simulator
class 来生成 cpu-activity 以供测试。单击“测试”按钮将产生大约二十秒的 activity,然后 progress-bar 将相应更新:
import psutil
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Signal
class MainUiClass(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.progress = QtWidgets.QProgressBar()
self.button = QtWidgets.QPushButton('Test')
self.button.clicked.connect(self.handleButton)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.progress)
layout.addWidget(self.button)
self.monitor = CpuMonitor()
self.monitor.cpuPercent.connect(self.progress.setValue)
self.monitor.start()
self.simulator = Simulator()
def handleButton(self):
if not self.simulator.isRunning():
self.simulator.start()
def closeEvent(self, event):
for thread in self.simulator, self.monitor:
thread.stop()
thread.quit()
thread.wait()
class CpuMonitor(QtCore.QThread):
cpuPercent = Signal(int)
def run(self):
self._stopped = False
while not self._stopped:
value = int(psutil.cpu_percent(interval=1))
self.cpuPercent.emit(value)
def stop(self):
self._stopped = True
class Simulator(QtCore.QThread):
def run(self):
self._stopped = False
random = QtCore.QRandomGenerator.system()
timer1 = QtCore.QDeadlineTimer(20000)
while not self._stopped and not timer1.hasExpired():
duration = random.bounded(400, 800)
self.msleep(duration)
timer2 = QtCore.QDeadlineTimer(duration)
while not self._stopped and not timer2.hasExpired():
pass
def stop(self):
self._stopped = True
if __name__ == '__main__':
app = QtWidgets.QApplication(['CPU Monitor'])
a = MainUiClass()
a.show()
app.exec_()