// SPDX-FileCopyrightText: 2024 MyCompany // // SPDX-License-Identifier: LGPL-3.0-or-later #pragma once #include #include #include #include #include #include #include #include #include #include #include DS_BEGIN_NAMESPACE struct NetworkInterface { QString name; // 接口名称,如 "eth0", "wlan0" qint64 rxBytes; // 接收字节数 qint64 txBytes; // 发送字节数 qint64 rxPackets; // 接收包数 qint64 txPackets; // 发送包数 qint64 rxErrors; // 接收错误数 qint64 txErrors; // 发送错误数 qint64 rxDropped; // 接收丢弃数 qint64 txDropped; // 发送丢弃数 }; // 单个速度采样点:用于趋势图的环形缓冲 // timestamp: 自 epoch 的秒级时间戳,作为 X 轴定位 // downloadSpeed / uploadSpeed: 当时的瞬时速度(字节/秒),作为两条折线的 Y 值 struct SpeedSample { qint64 timestamp; double downloadSpeed; double uploadSpeed; }; class NetworkMonitorApplet : public DApplet { Q_OBJECT Q_PROPERTY(double downloadSpeed READ downloadSpeed NOTIFY speedChanged) Q_PROPERTY(double uploadSpeed READ uploadSpeed NOTIFY speedChanged) Q_PROPERTY(double totalDownload READ totalDownload NOTIFY totalChanged) Q_PROPERTY(double totalUpload READ totalUpload NOTIFY totalChanged) Q_PROPERTY(QStringList networkInterfaces READ networkInterfaces NOTIFY interfacesChanged) Q_PROPERTY(QStringList interfaceStats READ interfaceStats NOTIFY statsChanged) Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) // 当前活动接口,用户在弹窗或设置窗口选择后持久化到 ~/.config/jnetapplet/settings.ini, // 下次启动自动恢复;若保存的接口已不存在则回退到自动选择 Q_PROPERTY(QString activeInterface READ activeInterface NOTIFY activeInterfaceChanged) // 活动接口的 IPv4 地址,供 QML 在弹出面板和 tooltip 中显示 Q_PROPERTY(QString ipAddress READ ipAddress NOTIFY ipAddressChanged) // 活动接口的 IPv6 全球地址(已过滤 link-local 和 loopback),供 QML 显示 Q_PROPERTY(QString ipv6Address READ ipv6Address NOTIFY ipv6AddressChanged) // 插件版本号,从 dde-shell 元数据读取,版本唯一源为 CMakeLists.txt project(VERSION) Q_PROPERTY(QString version READ version CONSTANT) // 任务栏网速数值字体颜色,空串表示跟随系统主题(由 QML 回退到 primaryText), // 用户在设置窗口选择后持久化到 ~/.config/jnetapplet/settings.ini Q_PROPERTY(QString textColor READ textColor WRITE setTextColor NOTIFY textColorChanged) // 当前活动接口的下行速度历史采样点(QPointF 列表:x=时间戳秒, y=速度 bytes/sec) // 用于趋势图绘制下载折线,每次 calculateSpeed 追加一个点并发射 speedHistoryChanged Q_PROPERTY(QVariantList speedHistoryDownload READ speedHistoryDownload NOTIFY speedHistoryChanged) // 当前活动接口的上行速度历史采样点,结构同 speedHistoryDownload Q_PROPERTY(QVariantList speedHistoryUpload READ speedHistoryUpload NOTIFY speedHistoryChanged) public: explicit NetworkMonitorApplet(QObject *parent = nullptr); ~NetworkMonitorApplet(); virtual bool load() override; virtual bool init() override; double downloadSpeed() const; double uploadSpeed() const; double totalDownload() const; double totalUpload() const; QStringList networkInterfaces() const; QStringList interfaceStats() const; bool ready() const; QString activeInterface() const; QString ipAddress() const; QString ipv6Address() const; // 返回当前活动接口的下行速度历史(QPointF 列表),供 QML 趋势图绘制 QVariantList speedHistoryDownload() const; // 返回当前活动接口的上行速度历史(QPointF 列表),供 QML 趋势图绘制 QVariantList speedHistoryUpload() const; // 返回插件版本号,从 dde-shell 插件元数据(metadata.json)读取 QString version() const; // 返回任务栏网速字体颜色,空串表示跟随系统主题 QString textColor() const; // 设置任务栏网速字体颜色,空串表示跟随系统主题 void setTextColor(const QString &color); Q_INVOKABLE void refresh(); Q_INVOKABLE void setActiveInterface(const QString &interface); signals: void speedChanged(); void totalChanged(); void interfacesChanged(); void statsChanged(); void readyChanged(); void activeInterfaceChanged(); void ipAddressChanged(); void ipv6AddressChanged(); void speedHistoryChanged(); // 任务栏网速字体颜色变化时通知 QML 更新 void textColorChanged(); private: void readNetworkStats(); void calculateSpeed(); void detectInterfaces(); // 检测活动接口的 IPv4 与 IPv6 地址,变化时分别发射对应信号 void detectIpAddress(); // 判断是否为物理网卡(无线 wlp/wlan,有线 enp/eth), // 用于自动选择时优先真实网卡而非虚拟代理接口(如 Meta/tun0) bool isPhysicalInterface(const QString &name) const; qint64 getActiveRxBytes() const; qint64 getActiveTxBytes() const; QTimer *m_refreshTimer; QMap m_interfaces; QStringList m_interfaceList; QString m_activeInterface; QString m_ipAddress; // 活动接口的 IPv4 地址 QString m_ipv6Address; // 活动接口的 IPv6 全球地址(过滤 link-local) // 速度计算 qint64 m_lastRxBytes; qint64 m_lastTxBytes; // 上次采样的毫秒时间戳,用于按真实间隔计算速度(避免定时器抖动失真) qint64 m_lastTimestampMs; // 当前瞬时速度(字节/秒),用 double 存储以保留按真实间隔除算的小数精度 double m_downloadSpeed; double m_uploadSpeed; // 每个接口的上次收发字节数,用于为所有接口(非仅活动接口)计算速度并采集历史 // 设计原因:原仅跟踪活动接口,切换到非活动接口时趋势图为空需等待数分钟才有数据 QHash m_lastRxBytesByIface; QHash m_lastTxBytesByIface; // 总量 qint64 m_totalDownload; qint64 m_totalUpload; bool m_ready; bool m_firstUpdate; // 任务栏网速字体颜色,空串表示跟随系统主题 // 设计原因:空串作为"跟随系统"的语义值,QML 层用 textColor ? textColor : primaryText // 做回退,避免后端硬编码系统色 QString m_textColor; // 速度历史环形缓冲:每个接口独立维护一份,key 为接口名 // 设计原因:接口切换时趋势图不出现跳变,切回时仍能看到该接口历史 QHash> m_speedHistory; // 每个接口最多保留的采样点数:5 分钟 × 60 秒 = 300 static constexpr int MAX_HISTORY_SAMPLES = 300; }; DS_END_NAMESPACE