deepin(深度linux)dde-dock系统监控小插件(网速CPU内存)

转载自deepin(深度linux)dde-dock系统监控小插件(网速CPU内存),仅用作个人学习备份,Mark一下

花了一周时间,研究了dde-dock官方插件开发文档和sonichy大神的项目,自己弄出来一个插件,记录一下QT开发的心得和体会
deepin(深度linux)dde-dock系统监控小插件(网速CPU内存)_第1张图片

鼠标悬停和单击弹出气泡
deepin(深度linux)dde-dock系统监控小插件(网速CPU内存)_第2张图片

右键可以打开深度系统监视器

dde-dock插件开发环境配置
根据官方开发文档
https://github.com/linuxdeepin/dde-dock/blob/master/plugins/plugin-guide/plugins-developer-guide.md
讲得不全,还缺少qt、qwidget和dtkwidget环境

sudo apt-get install dde-dock-dev 
sudo apt-get install qtbase5-dev-tools
sudo apt-get install libdtkwidget-dev 
deepin Linux获取CPU使用率
juju@juju-PC:/usr/lib/dde-dock/plugins$ cat /proc/stat
cpu  139728 269 58284 2075575 1658 0 2539 0 0 0
cpu0 33996 72 14180 521112 162 0 518 0 0 0
cpu1 35148 73 14226 519866 169 0 504 0 0 0
cpu2 34289 50 14140 520076 880 0 559 0 0 0
cpu3 36294 72 15737 514519 446 0 957 0 0 0


第一行的数字分别代表:
user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice
时间
CPU工作时间为前3项:
worktime = user + nice + system
CPU总时间为前8项:
totaltime = user + nice + system + idle + iowait + irq + softirq + steal

计算某一时间段的CPU使用要保存上次的worktime和totaltime,用这次的减去上次的才是这个时间段的cpu使用量

具体解释可查看man stat

我的代码:

//获得cpu信息
fp = fopen("/proc/stat", "r");
if (fp == NULL) {perror("Could not open stat file");return;}
user = 0, nice = 0, system = 0, idle = 0;
iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guestnice = 0;
char* ret = fgets(buffer, sizeof(buffer) - 1, fp);
if (ret == NULL) {perror("Could not read stat file");fclose(fp);return;}
fclose(fp);
sscanf(buffer,"cpu  %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu",&user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, &guestnice);
worktime = user + nice + system;
totaltime = user + nice + system + idle + iowait + irq + softirq + steal;
// 得到百分比
cpuPercent = qRound((worktime-oldworktime)*100.0/(totaltime-oldtotaltime));
oldtotaltime=totaltime;
oldworktime=worktime;
if(cpuPercent<=9)strcpu=QString(" %1\%").arg(cpuPercent);
else strcpu=QString("%1\%").arg(cpuPercent);

deepin Linux获取内存和交换分区使用率

juju@juju-PC:/usr/lib/dde-dock/plugins$ cat /proc/meminfo 
MemTotal:        3920432 kB
MemFree:          222156 kB
MemAvailable:    1985120 kB
Buffers:           79440 kB
Cached:          2348916 kB
SwapCached:            4 kB
Active:          1863552 kB
Inactive:        1578660 kB
Active(anon):    1024840 kB
Inactive(anon):   487144 kB
Active(file):     838712 kB
Inactive(file):  1091516 kB
Unevictable:          64 kB
Mlocked:              64 kB
SwapTotal:       4194300 kB
SwapFree:        4194044 kB
......

MemTotal:就是总内存
MemAvailable:可用内存
已用内存=可用内存-总内存,不能直接读取MemFree,因为它没有计入操作系统占用的内存
SwapTotal: 总交换分区
SwapFree:空闲交换分区
已用交换分区=总交换分区-空闲交换分区
同样的用c库函数fopoen打开/proc/meminfo虚拟磁盘文件,为了输出美观,还添加了空格占位符

//获得内存信息

fp=fopen("/proc/meminfo","r");
if (fp == NULL) {perror("Could not open meminfo file");return;}
do
{
    ret = fgets(buffer, sizeof(buffer) - 1, fp);
    if (ret == NULL) {perror("Could not read meminfo file");fclose(fp);return;}
    sscanf(buffer,"%s %lu kB",devname,&tmp);
    if(!strcmp(devname,"MemTotal:"))totalmem=tmp;
    else if(!strcmp(devname,"MemAvailable:"))availablemem=tmp;
    else if(!strcmp(devname,"SwapTotal:"))totalswap=tmp;
    else if(!strcmp(devname,"SwapFree:"))freeswap=tmp;
}while(strcmp(devname,"SwapFree:"));
fclose(fp);
memPercent = qRound((totalmem - availablemem) * 100.0 / totalmem);
if(memPercent<=9)strmem=QString(" %1\%").arg(memPercent);
else strmem=QString("%1\%").arg(memPercent);

swapPercent = qRound((totalswap - freeswap) * 100.0 / totalswap);
if(swapPercent<=9)strswap=QString(" %1\%").arg(swapPercent);
else strswap=QString("%1\%").arg(swapPercent);

deepin Linux获取上传下载网速和上传下载总量

juju@juju-PC:/usr/lib/dde-dock/plugins$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:   29624     404    0    0    0     0          0         0    29624     404    0    0    0     0       0          0
wlp1s0: 36714669   40226    0    0    0     0          0         0  4323552   28514    0    0    0     0       0          0

编程读取/proc/net/dev,忽略前两行
每一行第一个字符串是网络设备名,第1个unsigned long是receive下载的总量bytes,第9个unsigned long是Transmit上传的总量bytes

和CPU一样,计算实时网速要保存上次的上传下载总量,相减才是实时网速,单位是byte,自己做一下单位变换

//获得net信息

    fp=fopen("/proc/net/dev","r");
    if (fp == NULL) {perror("Could not open netdev file");return;}
    ret = fgets(buffer, sizeof(buffer) - 1, fp);
    ret = fgets(buffer, sizeof(buffer) - 1, fp);
    if (ret == NULL) {perror("Could not read netdev file");fclose(fp);return;}
    tmpr=tmps=rbytes=sbytes=0;
    while(true)
    {
        ret = fgets(buffer, sizeof(buffer) - 1, fp);
        if (ret == NULL) break;
        sscanf(buffer,"%s %lu %*lu %*lu %*lu %*lu %*lu %*lu %*lu %lu",devname,&tmpr,&tmps);
        if(strcmp(devname,"lo:")==0)continue;
        rbytes+=tmpr;
        sbytes+=tmps;
    }
    fclose(fp);
    tmpr=(oldrbytes==0?0:rbytes-oldrbytes);
    tmps=(oldsbytes==0?0:sbytes-oldsbytes);
    oldrbytes=rbytes;
    oldsbytes=sbytes;

谈谈对QT插件的理解
class SysMonitorPlugin : public QObject, PluginsItemInterface
QT插件核心类是Plugin类,由dde-dock初始化一个Plugin类的实例
在*Plugin类的init函数中将自己的实例注册到dde-dock

void SysMonitorPlugin::init(PluginProxyInterface *proxyInter)
{
    m_proxyInter = proxyInter;
    m_pluginWidget = new InformationWidget;
    m_tipsWidget = new QLabel;
    m_appletWidget = new QLabel;
    // 如果插件没有被禁用则在初始化插件时才添加主控件到面板上
    if (!pluginIsDisable()) {
        m_proxyInter->itemAdded(this, pluginName());
    }
}

class InformationWidget : public QWidget
Widget类是负责显示GUI的类,由Plugin类初始化一个Widget类的实例
widget中加layout,layout中加qlabel,qlabel设置text

QLabel如何实现字符等宽
QLabel可以部分实现html的标记和css的语法,但是不完全,比如float就不支持
要是完全实现了那我这个前端狗不就笑呵呵了
QLabel实现字符等宽:设置等宽字体

font.setFamily("Noto Mono");
m_infoLabel->setFont(font);

这个字体应该是deepin自带的等宽字体,设置完就等宽对齐了,治好了我的强迫症

下载和github地址

你可能感兴趣的:(Linux)