小伙伴们,今天我们利用cursor不写一行代码开发一个电脑的系统状态监控小应用!
下载安装cursor:
网址:https://www.cursor.com/cn
下载后双击安装
输入提示词:
制作一个winswos应用,实现显示时间精确到秒,
显示cpu温度、cpu占用率,显示显卡GPU的温度和使用率,
内存的占用率,用户可自定义窗体界面大小,背景颜色,透明度,显示层级。
字体大小可调节。利用python pyqt5 实现
自动生成代码,选择:accept all
生成的代码 运行结果如下:
我们来进行优化:
优化功能,添加大核小核占用率,cpu gpu 相关数据未能正常读取。 界面优化 参考苹果IOS风格
期间如果遇到问题直接用自然语言提问给cursor,cursor会自动解决更新代码,经过几轮问答最终成果如下:
完整代码:
import sys
import psutil
import requests
import wmi
from datetime import datetime
from PyQt5.QtWidgets import (
QApplication, QWidget, QLabel, QVBoxLayout, QColorDialog, QSlider,
QPushButton, QFontDialog, QCheckBox, QFrame, QScrollArea
)
from PyQt5.QtCore import QTimer, Qt, QMutex
from PyQt5.QtGui import QColor, QFont
class HardwareMonitor:
@staticmethod
def get_data():
"""获取硬件数据,支持OpenHardwareMonitor和备用方案"""
try:
resp = requests.get("http://localhost:8085/data.json", timeout=1)
resp.raise_for_status()
return resp.json()
except Exception:
return HardwareMonitor.get_fallback_data()
@staticmethod
def get_cpu_temp_wmi():
w = wmi.WMI(namespace="root\\wmi")
try:
temps = w.MSAcpi_ThermalZoneTemperature()
if temps:
# 温度单位是 1/10 Kelvin
return [round(t.CurrentTemperature / 10.0 - 273.15, 1) for t in temps]
except Exception:
pass
return []
@staticmethod
def get_fallback_data():
"""当OpenHardwareMonitor不可用时使用的备用数据获取方案"""
cpu_percent = psutil.cpu_percent()
mem = psutil.virtual_memory()
cpu_freq = psutil.cpu_freq()
# 优先用wmi真实温度
cpu_temps = HardwareMonitor.get_cpu_temp_wmi()
if cpu_temps:
cpu_temp_value = cpu_temps[0]
else:
cpu_temp_value = HardwareMonitor.estimate_cpu_temp()
# 创建模拟的硬件数据结构
return {
"Children": [
{
"Text": "CPU",
"Children": [
{
"Text": "Temperatures",
"Children": [
{"Text": "CPU", "Value": cpu_temp_value}
]
},
{
"Text": "Load",
"Children": [
{"Text": "Total", "Value": cpu_percent}
]
},
{
"Text": "Clock",
"Children": [
{"Text": "CPU", "Value": cpu_freq.current if cpu_freq else None}
]
}
]
},
{
"Text": "Memory",
"Children": [
{
"Text": "Data",
"Children": [
{"Text": "Used", "Value": mem.percent}
]
}
]
}
]
}
@staticmethod
def estimate_cpu_temp():
"""根据CPU使用率估算温度(模拟值)"""
cpu_percent = psutil.cpu_percent()
# 基础温度 + 使用率影响
base_temp = 40.0
temp_increase = cpu_percent * 0.3
return min(base_temp + temp_increase, 95.0) # 限制最高温度
@staticmethod
def parse_temperatures(data):
cpu_temp = None
cpu_candidates = []
if not data or "Children" not in data:
return None, None
def traverse(node):
nonlocal cpu_candidates
if"Temperatures"in node.get("Text", ""):
for child in node.get("Children", []):
value = child.get("Value")
if value is not None:
name = child.get("Text", "").lower()
if"cpu"in name or "package"in name:
cpu_candidates.append(value)
for child in node.get("Children", []):
traverse(child)
for child in data["Children"]:
traverse(child)
if cpu_candidates:
cpu_temp = max(cpu_candidates)
return cpu_temp, None
@staticmethod
def parse_usage(data):
cpu_load = None
if not data or "Children" not in data:
return None, []
def traverse(node):
nonlocal cpu_load
if"Load"in node.get("Text", ""):
for child in node.get("Children", []):
value = child.get("Value")
if value is not None:
name = child.get("Text", "").lower()
if"cpu"in name or "total"in name:
cpu_load = value
for child in node.get("Children", []):
traverse(child)
for child in data["Children"]:
traverse(child)
return cpu_load, []
class CardFrame(QFrame):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet('''
QFrame {
background: rgba(255,255,255,0.85);
border-radius: 14px;
border: 1px solid #e0e0e0;
margin: 4px;
padding: 6px;
}
''')
class MonitorWidget(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("系统监控")
self.resize(380, 300)
self.setWindowOpacity(0.97)
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
self.setStyleSheet("background: #f6f7fa;")
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(8, 8, 8, 8)
main_layout.setSpacing(4)
# 时间卡片
self.card_time = CardFrame()
vbox_time = QVBoxLayout(self.card_time)
vbox_time.setContentsMargins(4, 2, 4, 2)
self.label_date = QLabel()
self.label_date.setFont(QFont("Arial", 12, QFont.Bold))
self.label_date.setStyleSheet("color: #555; margin-bottom: 0px;")
self.label_time = QLabel()
self.label_time.setFont(QFont("Arial", 18, QFont.Bold))
self.label_time.setStyleSheet("color: #222; margin-bottom: 0px;")
vbox_time.addWidget(self.label_date)
vbox_time.addWidget(self.label_time)
main_layout.addWidget(self.card_time)
# CPU卡片
self.card_cpu = CardFrame()
vbox_cpu = QVBoxLayout(self.card_cpu)
vbox_cpu.setContentsMargins(4, 2, 4, 2)
self.label_cpu_temp = QLabel("CPU温度: 初始化中...")
self.label_cpu_temp.setFont(QFont("Arial", 12))
self.label_cpu_temp.setStyleSheet("color: #444;")
self.label_cpu_load = QLabel("CPU总占用: 初始化中...")
self.label_cpu_load.setFont(QFont("Arial", 12))
self.label_cpu_load.setStyleSheet("color: #444;")
vbox_cpu.addWidget(self.label_cpu_temp)
vbox_cpu.addWidget(self.label_cpu_load)
main_layout.addWidget(self.card_cpu)
# 内存卡片
self.card_mem = CardFrame()
vbox_mem = QVBoxLayout(self.card_mem)
vbox_mem.setContentsMargins(4, 2, 4, 2)
self.label_mem = QLabel()
self.label_mem.setFont(QFont("Arial", 12))
self.label_mem.setStyleSheet("color: #444;")
vbox_mem.addWidget(self.label_mem)
main_layout.addWidget(self.card_mem)
# 控件卡片
self.card_ctrl = CardFrame()
vbox_ctrl = QVBoxLayout(self.card_ctrl)
vbox_ctrl.setContentsMargins(4, 2, 4, 2)
btn_color = QPushButton("背景颜色")
btn_color.setFont(QFont("Arial", 10))
btn_color.clicked.connect(self.choose_color)
vbox_ctrl.addWidget(btn_color)
slider_opacity = QSlider(Qt.Horizontal)
slider_opacity.setMinimum(50)
slider_opacity.setMaximum(100)
slider_opacity.setValue(97)
slider_opacity.valueChanged.connect(self.set_opacity)
vbox_ctrl.addWidget(slider_opacity)
btn_font = QPushButton("字体设置")
btn_font.setFont(QFont("Arial", 10))
btn_font.clicked.connect(self.choose_font)
vbox_ctrl.addWidget(btn_font)
self.cb_top = QCheckBox("窗口置顶")
self.cb_top.setFont(QFont("Arial", 10))
self.cb_top.setChecked(True)
self.cb_top.stateChanged.connect(self.set_topmost)
vbox_ctrl.addWidget(self.cb_top)
main_layout.addWidget(self.card_ctrl)
# 定时器与刷新锁
self.refresh_mutex = QMutex()
self.timer = QTimer(self)
self.timer.timeout.connect(self.safe_update_info)
self.timer.start(1500)
def safe_update_info(self):
if self.refresh_mutex.tryLock():
try:
self.update_info()
finally:
self.refresh_mutex.unlock()
else:
pass
def update_info(self):
now = datetime.now()
week_map = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日']
date_str = now.strftime("%Y-%m-%d ") + week_map[now.weekday()]
time_str = now.strftime("%H:%M:%S")
self.label_date.setText(date_str)
self.label_time.setText(time_str)
data = HardwareMonitor.get_data()
cpu_temp, _ = HardwareMonitor.parse_temperatures(data)
cpu_load, _ = HardwareMonitor.parse_usage(data)
mem = psutil.virtual_memory()
self.label_cpu_temp.setText(f"CPU温度: {cpu_temp if cpu_temp is not None else 'N/A'}")
self.label_cpu_load.setText(f"CPU总占用: {cpu_load if cpu_load is not None else 'N/A'}%")
self.label_mem.setText(f"内存占用: {mem.percent:.1f}%")
def choose_color(self):
color = QColorDialog.getColor()
if color.isValid():
self.setStyleSheet(f"background: {color.name()};")
def set_opacity(self, value):
self.setWindowOpacity(value / 100)
def choose_font(self):
font, ok = QFontDialog.getFont()
if ok:
for label in [
self.label_date, self.label_time,
self.label_cpu_temp, self.label_cpu_load,
self.label_mem
]:
label.setFont(font)
def set_topmost(self, state):
if state == Qt.Checked:
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
else:
self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MonitorWidget()
w.show()
sys.exit(app.exec_())
感谢大家的点赞和关注,我们下期见!