cursor+python轻松实现电脑监控

发布于:2025-09-05 ⋅ 阅读:(13) ⋅ 点赞:(0)

小伙伴们,今天我们利用cursor不写一行代码开发一个电脑的系统状态监控小应用!

下载安装cursor:

网址:https://www.cursor.com/cn

Image

下载后双击安装

Image

Image

Image

  

输入提示词:       

制作一个winswos应用,实现显示时间精确到秒,
显示cpu温度、cpu占用率,显示显卡GPU的温度和使用率,
内存的占用率,用户可自定义窗体界面大小,背景颜色,透明度,显示层级。
字体大小可调节。利用python pyqt5 实现

Image

自动生成代码,选择:accept all

Image

生成的代码 运行结果如下:

Image

我们来进行优化:

优化功能,添加大核小核占用率,cpu gpu 相关数据未能正常读取。 界面优化 参考苹果IOS风格

Image

Image

期间如果遇到问题直接用自然语言提问给cursor,cursor会自动解决更新代码,经过几轮问答最终成果如下:

Image

完整代码:

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_())


感谢大家的点赞和关注,我们下期见!


网站公告

今日签到

点亮在社区的每一天
去签到