Files
JSwitchDisplayApplet/graphicsdriverapplet.h
T
Jokul 2570a028ea feat: 添加GPU频率/功耗/风扇监控、温度告警、趋势图、右键菜单、进程列表、GPU切换
第二、三阶段功能:

数据增强(第一阶段):
- GPU频率: NVIDIA nvidia-smi clocks.gr, Intel gt/gt0/rps_act_freq_mhz
- 显存频率: NVIDIA nvidia-smi clocks.mem
- 功耗: NVIDIA nvidia-smi power.draw, AMD hwmon power1_average
- 风扇转速: NVIDIA nvidia-smi fan.speed, AMD hwmon fan1_input
- 任务栏图标根据最高温度变色(≥80°C红/≥60°C橙)
- readGpuStats 每次刷新前重置统计字段,避免残留旧值

交互提升(第二阶段):
- 温度告警: GPU温度≥80°C时通过D-Bus发送桌面通知,30秒冷却
- 右键菜单: 使用Qt.labs.platform原生菜单+MenuHelper,支持刷新和GPU切换
- 迷你趋势图: Canvas绘制近60秒温度走势折线
- 英文翻译: 新增en.ts,23条全部翻译

高级功能(第三阶段):
- NVIDIA进程列表: nvidia-smi --query-compute-apps查询,弹框中显示进程名和显存占用
- GPU切换: pkexec prime-select set <mode>,弹框按钮+右键菜单,仅PRIME模式显示

其他改进:
- 自定义深色主题tooltip替代系统默认白色tooltip
- 第一张卡片tooltip显示在下方避免被裁剪
- CMakeLists.txt lupdate添加C++源文件提取tr()翻译
- gpuStats格式扩展为9字段: temp|gpuUsage|memUsage|memUsed|memTotal|gpuClock|memClock|powerDraw|fanSpeed
2026-07-14 17:32:46 +08:00

111 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <applet.h>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QVariantList>
DS_BEGIN_NAMESPACE
struct GpuInfo {
QString name; // 显卡名称,如 "NVIDIA GeForce RTX 3060"
QString driver; // 驱动模块名,如 "nvidia"
QString driverVersion; // 驱动版本
QString pciId; // PCI ID,如 "01:00.0"
int drmCard; // DRM 卡号,如 0, 1(-1 表示未找到)
bool isPrimary; // 是否为主显卡(boot_vga=1
// 实时统计
int temperature; // 温度 (°C),-1 表示不可用
int gpuUsage; // GPU 使用率 (%)-1 表示不可用
int memUsage; // 显存使用率 (%),-1 表示不可用
int memTotal; // 显存总量 (MB),-1 表示不可用
int memUsed; // 显存已用 (MB),-1 表示不可用
int gpuClock; // GPU 频率 (MHz)-1 表示不可用
int memClock; // 显存频率 (MHz),-1 表示不可用
double powerDraw; // 功耗 (W)-1 表示不可用
int fanSpeed; // 风扇转速 (%),-1 表示不可用
};
class GraphicsDriverApplet : public DApplet
{
Q_OBJECT
Q_PROPERTY(QString deviceInfo READ deviceInfo NOTIFY deviceInfoChanged)
Q_PROPERTY(QString currentDriver READ currentDriver NOTIFY currentDriverChanged)
Q_PROPERTY(QString gpuSummary READ gpuSummary NOTIFY gpuSummaryChanged)
Q_PROPERTY(QStringList gpuStats READ gpuStats NOTIFY gpuStatsChanged)
Q_PROPERTY(QString gpuMode READ gpuMode NOTIFY gpuModeChanged)
Q_PROPERTY(QStringList gpuPrimary READ gpuPrimary NOTIFY gpuPrimaryChanged)
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
Q_PROPERTY(QVariantList tempHistory READ tempHistory NOTIFY tempHistoryChanged)
Q_PROPERTY(QStringList gpuProcesses READ gpuProcesses NOTIFY gpuProcessesChanged)
public:
explicit GraphicsDriverApplet(QObject *parent = nullptr);
~GraphicsDriverApplet();
virtual bool load() override;
virtual bool init() override;
QString deviceInfo() const;
QString currentDriver() const;
QString gpuSummary() const;
QStringList gpuStats() const;
QString gpuMode() const;
QStringList gpuPrimary() const;
bool ready() const;
QVariantList tempHistory() const;
QStringList gpuProcesses() const;
Q_INVOKABLE void refreshDeviceInfo();
Q_INVOKABLE void refreshStats();
Q_INVOKABLE bool switchGpu(const QString &mode);
signals:
void deviceInfoChanged();
void currentDriverChanged();
void gpuSummaryChanged();
void gpuStatsChanged();
void gpuModeChanged();
void gpuPrimaryChanged();
void readyChanged();
void tempHistoryChanged();
void gpuProcessesChanged();
private:
void detectGpus();
void readGpuStats();
void readGpuProcesses();
void detectGpuMode();
void checkTempAlert();
void sendNotification(const QString &summary, const QString &body);
static int findDrmCard(const QString &pciId);
static QStringList runCommand(const QString &cmd, const QStringList &args);
static QString parseGpuName(const QString &line);
static QString readDriverVersion(const QString &driverName);
QList<GpuInfo> m_gpus;
QString m_deviceInfo;
QString m_currentDriver;
QString m_gpuSummary;
QStringList m_gpuStats;
QString m_gpuMode;
QStringList m_gpuPrimary;
bool m_ready;
// 温度历史:每个 GPU 保留最近 60 个温度采样
QVector<QList<int>> m_tempHistory;
// NVIDIA 进程列表:每行 "pid|name|usedMemory"
QStringList m_gpuProcesses;
// 温度告警冷却时间戳
qint64 m_lastAlertTime;
};
DS_END_NAMESPACE