Qt/C++开源作品45-CPU内存显示控件/和任务管理器一致

news2025/3/14 20:49:25

一、前言

在很多软件上,会在某个部位显示一个部件,专门显示当前的CPU使用率以及内存占用,方便用户判断当前程序或者当前环境中是否还有剩余的CPU和内存留给程序使用,在不用打开任务管理器或者资源查看器的时候直接得知当前系统的运行情况。尤其是视频监控系统,如果64路全开,肯定很占用CPU和内存情况,这样直接在软件上直观的查看到当前占用率,用户更方便判断当前电脑环境是否适合打开多少路通道。

采集本地系统的实时CPU使用率,如果使用的GetSystemTimes函数,会发现和本地任务管理器中的不一致(主要集中在win10系统/win7和XP系统貌似正常),那是因为计数统计的方式不一样,采用GetSystemTimes函数获取到的值相对来说是系统底层的数据。为了能够和任务管理器中展示的一致,试验过各种办法后决定采用命令行获取的形式处理,这样获取到的值是一致的,在win10以下的系统执行 typeperf \Processor(_Total)% Processor Time,在win10及以上的系统执行 typeperf \Processor Information(_Total)% Processor Utility。执行命令采用QProcess类,执行结果有信号通知,直接读取解析即可。同理在linux系统上也是采用执行命令行的形式获取,比如linux上获取CPU占用命令是 cat /proc/stat,获取内存相关命令是 cat /proc/meminfo。在windows上获取内存相关使用函数 GlobalMemoryStatusEx。

二、主要功能

  1. 实时显示当前CPU占用率。
  2. 实时显示内存使用情况。
  3. 包括共多少内存、已使用多少内存。
  4. 全平台通用,包括windows、linux、ARM。
  5. 发出信号通知占用率和内存使用情况等,以便自行显示到其他地方。

三、效果图

在这里插入图片描述

四、开源主页

  • 以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。
  • 本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。
  • Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!
  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 开源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
  4. 个人主页:https://qtchina.blog.csdn.net/
  5. 视频主页:https://space.bilibili.com/687803542

五、核心代码

#pragma execution_character_set("utf-8")

#include "cpumemorylabel.h"
#include "qtimer.h"
#include "qprocess.h"
#include "qdebug.h"

#ifdef Q_OS_WIN
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x502
#endif
#include "windows.h"
#endif

#define MB (1024 * 1024)
#define KB (1024)

CpuMemoryLabel::CpuMemoryLabel(QWidget *parent) : QLabel(parent)
{
    totalNew = idleNew = totalOld = idleOld = 0;

    cpuPercent = 0;
    memoryPercent = 0;
    memoryAll = 0;
    memoryUse = 0;

    //获取CPU占用情况定时器
    timerCPU = new QTimer(this);
    connect(timerCPU, SIGNAL(timeout()), this, SLOT(getCPU()));

    //获取内存占用情况定时器
    timerMemory = new QTimer(this);
    connect(timerMemory, SIGNAL(timeout()), this, SLOT(getMemory()));

    //执行命令获取
    process = new QProcess(this);
    connect(process, SIGNAL(readyRead()), this, SLOT(readData()));

    showText = true;
}

CpuMemoryLabel::~CpuMemoryLabel()
{
    this->stop();
}

void CpuMemoryLabel::start(int interval)
{
    this->getCPU();
    this->getMemory();

    if (!timerCPU->isActive()) {
        timerCPU->start(interval);
    }
    if (!timerMemory->isActive()) {
        timerMemory->start(interval + 1000);
    }
}

void CpuMemoryLabel::stop()
{
    process->close();
    if (timerCPU->isActive()) {
        timerCPU->stop();
    }
    if (timerMemory->isActive()) {
        timerMemory->stop();
    }
}

void CpuMemoryLabel::getCPU()
{
#ifdef Q_OS_WIN
#if 0
    static FILETIME lastIdleTime;
    static FILETIME lastKernelTime;
    static FILETIME lastUserTime;

    FILETIME newIdleTime;
    FILETIME newKernelTime;
    FILETIME newUserTime;

    //采用GetSystemTimes获取的CPU占用和任务管理器的不一致
    GetSystemTimes(&newIdleTime, &newKernelTime, &newUserTime);

    int offset = 31;
    quint64 a, b;
    quint64 idle, kernel, user;

    a = (lastIdleTime.dwHighDateTime << offset) | lastIdleTime.dwLowDateTime;
    b = (newIdleTime.dwHighDateTime << offset) | newIdleTime.dwLowDateTime;
    idle = b - a;

    a = (lastKernelTime.dwHighDateTime << offset) | lastKernelTime.dwLowDateTime;
    b = (newKernelTime.dwHighDateTime << offset) | newKernelTime.dwLowDateTime;
    kernel = b - a;

    a = (lastUserTime.dwHighDateTime << offset) | lastUserTime.dwLowDateTime;
    b = (newUserTime.dwHighDateTime << offset) | newUserTime.dwLowDateTime;
    user = b - a;

    cpuPercent = float(kernel + user - idle) * 100 / float(kernel + user);

    lastIdleTime = newIdleTime;
    lastKernelTime = newKernelTime;
    lastUserTime = newUserTime;
    this->setData();
#else
    //获取系统版本区分win10
    bool win10 = false;
#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0))
    win10 = (QSysInfo::productVersion().mid(0, 2).toInt() >= 10);
#else
    win10 = (QSysInfo::WindowsVersion >= 192);
#endif

    QString cmd = "\\Processor(_Total)\\% Processor Time";
    if (win10) {
        cmd = "\\Processor Information(_Total)\\% Processor Utility";
    }

    if (process->state() == QProcess::NotRunning) {
        process->start("typeperf", QStringList() << cmd);
    }
#endif

#elif defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
    if (process->state() == QProcess::NotRunning) {
        totalNew = idleNew = 0;
        process->start("cat", QStringList() << "/proc/stat");
    }
#endif
}

void CpuMemoryLabel::getMemory()
{
#ifdef Q_OS_WIN
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    GlobalMemoryStatusEx(&statex);
    memoryPercent = statex.dwMemoryLoad;
    memoryAll = statex.ullTotalPhys / MB;
    memoryFree = statex.ullAvailPhys / MB;
    memoryUse = memoryAll - memoryFree;
    this->setData();

#elif defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
    if (process->state() == QProcess::NotRunning) {
        process->start("cat", QStringList() << "/proc/meminfo");
    }
#endif
}

void CpuMemoryLabel::readData()
{
#ifdef Q_OS_WIN
    while (!process->atEnd()) {
        QString s = QLatin1String(process->readLine());
        s = s.split(",").last();
        s.replace("\r", "");
        s.replace("\n", "");
        s.replace("\"", "");
        if (!s.isEmpty() && s.length() < 10) {
            cpuPercent = qRound(s.toFloat());
        }
    }
#elif defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
    while (!process->atEnd()) {
        QString s = QLatin1String(process->readLine());
        if (s.startsWith("cpu")) {
            QStringList list = s.split(" ");
            idleNew = list.at(5).toUInt();
            foreach (QString value, list) {
                totalNew += value.toUInt();
            }

            quint64 total = totalNew - totalOld;
            quint64 idle = idleNew - idleOld;
            cpuPercent = 100 * (total - idle) / total;
            totalOld = totalNew;
            idleOld = idleNew;
            break;
        } else if (s.startsWith("MemTotal")) {
            s.replace(" ", "");
            s = s.split(":").at(1);
            memoryAll = s.left(s.length() - 3).toUInt() / KB;
        } else if (s.startsWith("MemFree")) {
            s.replace(" ", "");
            s = s.split(":").at(1);
            memoryFree = s.left(s.length() - 3).toUInt() / KB;
        } else if (s.startsWith("Buffers")) {
            s.replace(" ", "");
            s = s.split(":").at(1);
            memoryFree += s.left(s.length() - 3).toUInt() / KB;
        } else if (s.startsWith("Cached")) {
            s.replace(" ", "");
            s = s.split(":").at(1);
            memoryFree += s.left(s.length() - 3).toUInt() / KB;
            memoryUse = memoryAll - memoryFree;
            memoryPercent = 100 * memoryUse / memoryAll;
            break;
        }
    }
#endif
    this->setData();
}

void CpuMemoryLabel::setData()
{
    cpuPercent = (cpuPercent < 0 ? 0 : cpuPercent);
    cpuPercent = (cpuPercent > 100 ? 0 : cpuPercent);
    QString msg = QString("CPU %1%  Mem %2% ( 已用 %3 MB / 共 %4 MB )").arg(cpuPercent).arg(memoryPercent).arg(memoryUse).arg(memoryAll);
    if (showText) {
        this->setText(msg);
    }

    emit textChanged(msg);
    emit valueChanged(cpuPercent, memoryPercent, memoryAll, memoryUse, memoryFree);
}

QSize CpuMemoryLabel::sizeHint() const
{
    return QSize(300, 30);
}

QSize CpuMemoryLabel::minimumSizeHint() const
{
    return QSize(30, 10);
}

bool CpuMemoryLabel::getShowText() const
{
    return this->showText;
}

void CpuMemoryLabel::setShowText(bool showText)
{
    this->showText = showText;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1103837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型,重构自动驾驶

文&#xff5c;刘俊宏 编&#xff5c;王一粟 大模型如何重构自动驾驶&#xff1f;答案已经逐渐露出水面。 “在大数据、大模型为特征&#xff0c;以数据驱动为开发模式的自动驾驶3.0时代&#xff0c;自动驾驶大模型将在车端、云端上实现一个统一的端到端的平台管理。”毫末智…

【线性表的查找,线性表插入,线性表的删除,线性表的链式表示和实现】

文章目录 线性表的查找线性表插入线性表的删除线性表的链式表示和实现1.单链表&#xff0c;双链表&#xff0c;循环列表2.头指针&#xff0c;头结点和首元结点3.链表的存储结构特点 线性表的查找 int LocateElem(Sqlist L,ElemType e){ //在线性表L中查找值为e的数据元素&…

jmeter(三十三):阶梯线程组Stepping Thread Group,并发线程Concurrency Thread Group

Stepping Thread Group参数详解 this group will start:表示总共要启动的线程数;若设置为 100,表示总共会加载到 100 个线程first,wait for:从运行之后多长时间开始启动线程;若设置为 0 秒,表示运行之后立即启动线程then start:初次启动多少个线程;若设置为 0 个,表示…

实验室设备modbus小结

背景&#xff1a; 大概花1个月&#xff0c;后端代码量再1W行多点&#xff0c;不同厂商的指令不同需要定制化开发。参与了设备的数据采集工作&#xff0c;当然常规的设备管理、权限就不重点展开。 都是物联网相关&#xff0c;但是还是有所不同。 之前做过海尔的U home相关的项目…

京东AIGC实战项目复盘;第一门AI动画系统课程;百川智能启动2024校园招聘;Kaggle 2023 AI前沿报告 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 李彦宏宣布「文心大模型4.0」正式发布&#xff0c;并开启邀请测试 10月17日&#xff0c;李彦宏在百度世界2023上宣布「文心大模型4.0」…

微信小程序 —— 会议OA项目首页布局与Mock数据交互

14天阅读挑战赛如果世界上有奇迹&#xff0c;那一定是努力的另一个名字。 目录 一、小程序布局 1.1 Flex布局 1.2 Flex属性 二、OA会议首页搭建 2.1 首页底部菜单 2.2 创建后端结口 2.3 Mock模拟数据 2.4 首页轮播图搭建 2.5 首页内容搭建 一、小程序布局 1.1 Flex布…

SpringBoot+Mybatis实现多数据源+分页

1 主要依赖版本 &#xff08;1&#xff09;SpringBoot 2.7.8 &#xff08;2&#xff09;Mybatis 2.2.2 &#xff08;3&#xff09;Pagehelper 1.3.0 &#xff08;4&#xff09;MySQL 8.0.26 &#xff08;5&#xff09;Oracle 11.2.0.3 2 概述 &#xff08;1&#xff09;…

Linux内核8. 进程地址空间

进程地址空间也就是每个进程所使用的内存&#xff0c;内核对进程地址空间的管理&#xff0c;也就是对用户态程序的内存管理。 主要内容&#xff1a; 地址空间(mm_struct)虚拟内存区域(VMA)地址空间和页表 1. 地址空间(mm_struct) 地址空间就是每个进程所能访问的内存地址范围…

React高级特性之RenderProps

一、概念 renderProps是另外一个能实现类似于HOC这种多个组件抽离公共组件逻辑的方式。 二、例子 import React from react import PropTypes from prop-typesclass Mouse extends React.Component {constructor(props) {super(props)this.state { x: 0, y: 0 }}handleMouse…

日志技术快速入门

1、创建Maven项目 这里不再说如何创建Maven项目 2、导入相关依赖 <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.12</version></dependency>3、创建配置文件 在re…

Spring源码解析——事务增强器

正文 上一篇文章我们讲解了事务的Advisor是如何注册进Spring容器的&#xff0c;也讲解了Spring是如何将有配置事务的类配置上事务的&#xff0c;实际上也就是用了AOP那一套&#xff0c;也讲解了Advisor&#xff0c;pointcut验证流程&#xff0c;至此&#xff0c;事务的初始化工…

强化学习------Policy Gradient算法

目录 简介PG算法原理效果&#xff1a;参考 简介 之前的QLearning DQN Sarsa都是通过计算动作得分来决策的&#xff0c;我们是在确定了价值函数的基础上采用某种策略&#xff0c;即Value-Based&#xff0c;通过先算出价值函数&#xff0c;再去做决策。而Policy Gradient算法是一…

云计算:shell脚本

shell脚本&#xff0c;会极大减少重复性工作&#xff0c;缩短很大时间。 脚本每个人都可以不一样&#xff0c;只要实现就可以。 注意&#xff1a;要多思考&#xff0c;把思路锻炼好。以后就可以写各种程序。 shell语言 学完shell之后&#xff0c;对Linux理解更深刻&#xff…

在调试器下看微信[如何耗电]

在今天这样干什么都离不开手机的时代里&#xff0c;手机的待机时间太重要了。特别是对于我这个不喜欢带充电宝出门的人来说&#xff0c;一旦看到手机电量低于20%&#xff0c;立刻就精神紧张了&#xff0c;因为一切信息都在手机里&#xff0c;如果手机没电&#xff0c;那么就失联…

[SQL | MyBatis] MyBatis 简介

目录 一、MyBatis 简介 1、MyBatis 简介 2、工作流程 二、入门案例 1、准备工作 2、示例 三、Mapper 代理开发 1、问题简介 2、工作流程 3、注意事项 4、测试 四、核心配置文件 mybatis-config.xml 1、environment 2、typeAilases 五、基于 xml 的查询操作 1、…

通过stream对list集合中对象的多个字段进行去重

记录下通过stream流对list集合中对象的多个字段进行去重&#xff01; 举个栗子&#xff0c;对象book&#xff0c;我们要通过姓名和价格这两个字段的值进行去重&#xff0c;该这么做呢&#xff1f; distinct&#xff08;&#xff09;返回由该流的不同元素组成的流。distinct&am…

第五届芜湖机器人展,正运动助力智能装备“更快更准”更智能!

■展会名称&#xff1a; 第十一届中国(芜湖)科普产品博览交易会-第五届机器人展 ■展会日期 2023年10月21日-23日 ■展馆地点 中国ㆍ芜湖宜居国际博览中心B馆 ■展位号 B029 正运动技术&#xff0c;作为国内领先的运动控制企业&#xff0c;将于2023年10月21日参加芜湖机…

查看双翌视觉软件版本号

查看双翌视觉软件版本号 MasterAlign视觉对位软件 MasterAlign视觉对位软件的版本号在软件界面的右下角&#xff0c;如下图所示&#xff1a; 进入界面查看右下角编号尾号为O的代表旧协议版本 而编号尾号为N的则为新协议版本。 WiseAlign视觉对位软件 打开WiseAlign视觉对位软…

靶机 Chill_Hack

Chill_Hack 信息搜集 存活检测 arp-scan -l 详细扫描 扫描结果 显示允许 ftp 匿名链接 FTP 匿名登录 匿名登陆 ftp 下载文件并查看 anonymous10.4.7.139下载命令 get note.txt查看文件 译 Anurodh告诉我&#xff0c;在命令 Apaar 中有一些字符串过滤后台扫描 扫描结果…

【算法挨揍日记】day16——525. 连续数组、1314. 矩阵区域和

525. 连续数组 525. 连续数组 题目描述&#xff1a; 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组&#xff0c;并返回该子数组的长度。 解题思路&#xff1a; 本题的元素只有0和1&#xff0c;根据题目意思&#xff0c;我们可以把题目看成找一段最…