转载自deepin(深度linux)dde-dock系统监控小插件(网速CPU内存),仅用作个人学习备份,Mark一下
花了一周时间,研究了dde-dock官方插件开发文档和sonichy大神的项目,自己弄出来一个插件,记录一下QT开发的心得和体会
右键可以打开深度系统监视器
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地址