QtApplets-SystemInfo

news2024/12/29 13:09:35
头图

QtApplets-SystemInfo

​ 今天是2024年1月3日09:18:44,这也是2024年的第一篇博客,今天我们主要两件事,第一件,获取系统CPU使用率,第二件,获取系统内存使用情况。

​ 这里因为写博客的这个本本的环境配置不是全的,没有VS编译套件,也没有对应的环境,我尝试在Windows下查找对应的pdh.lib没有找到,所以不能跑起来截图了,我今天分享的代码如果是基于Vs的编译环境,那可以直接跑起来,如果是基于mingW的环境,那需要手动指定一下pdh.lib的路径,并且吧dll拷贝到运行根目录。


文章目录

  • QtApplets-SystemInfo
    • Windows 平台获取 CPU 使用率
      • 关于 PDH库
    • Qt 开发
      • 引入 pdh 库
      • 抄代码
      • QString 转 LPCWSTR
    • Windows 平台下获取内存使用情况
      • 关于 psapi库
    • Qt 实现
    • mingW环境使用 PDH库
    • 程序运行效果
    • ☞ 源码

关键字: pdhpsapicpumemoryqt

Windows 平台获取 CPU 使用率

在Windows平台上,Qt没有提供直接的API来获取CPU使用率。不过,我们可以使用Windows API来获取这些信息。这里需要使用一个win的库,PDH库

关于 PDH库

PDH(Performance Data Helper)库是Windows操作系统提供的一个编程接口,用于访问计算机性能数据。这个库允许开发者收集和使用性能监视数据,这些数据是由Windows系统提供的性能计数器所采集的。

性能计数器可以提供有关系统或应用程序状态的各种指标,如CPU使用率、磁盘I/O、网络流量和内存使用情况等。PDH库提供了一系列的函数,使得开发者能够:

  • 枚举系统上可用的性能计数器和它们的实例。
  • 收集一次或定期收集性能数据。
  • 从本地或远程计算机上的实时数据或日志文件中检索性能数据。
  • 计算和格式化性能数据的计数器值。

使用PDH库的常见步骤包括:

  1. 打开一个查询: 创建一个查询句柄,以便开始收集性能数据。
  2. 添加计数器: 为你想要监控的性能指标添加一个或多个计数器。
  3. 收集数据: 定期收集性能数据,这可以是实时的,也可以是从性能日志中提取的。
  4. 获取计数器值: 提取特定计数器的当前值。
  5. 关闭查询: 收集完成后关闭和销毁查询。

PDH库是通过动态链接库pdh.dll实现的,开发者可以在C、C++等编程语言中使用这个库。在Visual Studio等开发环境中,通常可以直接包含Pdh.h头文件并链接Pdh.lib库文件以调用PDH函数。

例如,以下是一个使用PDH库获取CPU使用率的简单例子:

#include <windows.h>
#include <pdh.h>

#pragma comment(lib, "pdh.lib")

PDH_HQUERY cpuQuery;
PDH_HCOUNTER cpuTotal;

void init() {
    PdhOpenQuery(NULL, NULL, &cpuQuery);
    // 这里的计数器路径可能因系统的语言和版本而异
    PdhAddEnglishCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
    PdhCollectQueryData(cpuQuery);
}

double getCurrentCpuUsage() {
    PDH_FMT_COUNTERVALUE counterVal;

    PdhCollectQueryData(cpuQuery);
    PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
    return counterVal.doubleValue;
}

void cleanup() {
    PdhCloseQuery(cpuQuery);
}

在这个例子中,init函数初始化了一个查询,并添加了一个计数器来监控整个处理器时间的百分比。getCurrentCpuUsage函数收集并提供了当前的CPU使用率。最后,cleanup函数关闭了查询。

PDH库是系统监控和性能分析工具中常用的组件,它提供了一种相对简易的方法来获取和使用Windows系统的性能数据。

Qt 开发

引入 pdh 库

首先,我们需要在.pro文件中添加pdh.lib库:

LIBS += -lpdh

抄代码

然后把上面的代码放到Qt里面调试同就可以

代码片段如下:

void Widget::initCpuUsage()
{
    PdhOpenQuery(NULL, NULL, &cpuQuery);
    // 这里使用了反斜杠转义
    QString str = "\\Processor(_Total)\\% Processor Time";
    PdhAddEnglishCounter(cpuQuery, (LPCWSTR)str.utf16(), NULL, &cpuTotal);
    PdhCollectQueryData(cpuQuery);
}

void Widget::getCurrentCpuUsage()
{
    PDH_FMT_COUNTERVALUE counterVal;

    PdhCollectQueryData(cpuQuery);
    PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);

    ui->label_cpu->setText(QString::number( counterVal.doubleValue) + "%");
}

QString 转 LPCWSTR

在抄代码的时候,会发现遇到类型不匹配问题。这里就需要问下我的贴心小秘了。

在Qt中,可以使用QString的方法来将字符串转换为Windows平台特定的LPCWSTR类型。以下是如何进行转换的步骤:

  1. QString转换为QWchar数组。
  2. 使用QWchar数组来初始化LPCWSTR

下面是一个简单的示例:

#include <QString>
#include <QDebug>

// 假设我们有以下QString
QString qString = "Hello World";

// 将QString转换为宽字符串(UTF-16)
QByteArray utf16Array = qString.toUtf8();
LPCWSTR lpcwstr = reinterpret_cast<LPCWSTR>(utf16Array.constData());

// 现在可以使用lpcwstr作为LPCWSTR类型

但是,需要注意的是,QByteArray的生命周期必须覆盖LPCWSTR的使用范围,因为LPCWSTR是指向QByteArray数据的指针。如果QByteArray被销毁或者超出作用域,LPCWSTR指针将指向无效的内存。

在实际使用中,最常见的是将QString转换为LPCWSTR以便于Windows API调用,这通常需要UTF-16编码。Qt内部使用UTF-16编码存储QString,因此可以更简单地转换,如下所示:

QString qString = "Hello World";

#ifdef Q_OS_WIN
// 使用QString::utf16()转换为LPCWSTR
LPCWSTR lpcwstr = (LPCWSTR)qString.utf16();
#endif

// 现在lpcwstr可以用在需要LPCWSTR类型的Windows API调用中

请注意,上述代码中的#ifdef Q_OS_WIN是为了确保只在Windows平台上执行转换,以保持代码的跨平台特性。

当你需要将QString传递给接受LPCWSTR参数的Windows API时,确保QString在调用该API期间保持未被修改和有效。

Windows 平台下获取内存使用情况

在Windows 10上获取内存使用大小可以通过多种方式完成,同样,今天我们将使用Windows 的API 来获取,需要使用一个psapi 的库。

关于 psapi库

PSAPI(Process Status API)是Windows操作系统中用于管理应用程序和服务的一个API集合。这个库主要用于检索与系统进程、运行的程序以及它们使用的内存相关的信息。它是系统资源监测和管理工具开发过程中的关键部分。

PSAPI提供了以下功能:

  1. 枚举进程: 列出当前系统上运行的所有进程。
  2. 查询进程信息: 获取进程的详细信息,比如它的执行映像、占用的内存量、句柄等。
  3. 枚举模块: 列出特定进程加载的所有DLL和内存映射文件。
  4. 获取模块信息: 提供模块的详细信息,如文件路径、模块的内存使用情况。
  5. 工作集信息: 获取特定进程的工作集信息,即进程当前使用的物理内存集。

这些功能可以帮助开发者诊断程序的内存问题,或者构建显示系统资源使用情况的应用程序。

使用PSAPI库时,通常需要包含psapi.h头文件,并且在项目中链接psapi.lib库。在Windows编程中,PSAPI函数通常用于配合其他系统API,如进程和线程函数,以收集并操作系统资源使用数据。

以下是一个使用PSAPI函数EnumProcesses列出所有进程ID的简单示例:

#include <windows.h>
#include <psapi.h>
#include <stdio.h>

#pragma comment(lib, "psapi.lib")

void PrintProcessNamesAndIDs() {
    DWORD aProcesses[1024], cbNeeded, cProcesses;

    // 获取进程ID列表
    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
        return;
    }

    // 计算返回的进程数量
    cProcesses = cbNeeded / sizeof(DWORD);

    // 打印每个进程的名称和ID
    for (unsigned int i = 0; i < cProcesses; i++) {
        if (aProcesses[i] != 0) {
            TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

            // 获取进程句柄
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
                                          PROCESS_VM_READ,
                                          FALSE, aProcesses[i]);

            // 获取进程的可执行文件名称
            if (hProcess) {
                HMODULE hMod;
                DWORD cbNeeded;

                if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
                    GetModuleBaseName(hProcess, hMod, szProcessName,
                                      sizeof(szProcessName) / sizeof(TCHAR));
                }
            }

            // 打印进程名称和ID
            printf("%s (PID: %u)\n", szProcessName, aProcesses[i]);

            // 关闭进程句柄
            CloseHandle(hProcess);
        }
    }
}

int main() {
    PrintProcessNamesAndIDs();
    return 0;
}

请注意,对系统资源的查询可能需要特定的权限,因此你可能需要以管理员权限运行你的程序才能获取所有进程的信息。

随着Windows版本的更新,PSAPI的一些功能可能会在其他库(如Kernel32.dll和NtDll.dll)中得到增强或替代。因此,在使用时,可能需要参考最新的官方文档以获取最佳实践。

Qt 实现

首先,你需要包含必要的头文件和库。在你的Qt项目中,需要在.pro文件中添加psapi.lib

LIBS += -lpsapi

代码片段如下:

void Widget::getMemory()
{
// 初始化MEMORYSTATUSEX结构
    MEMORYSTATUSEX memStatus;
    memStatus.dwLength = sizeof(memStatus);

    // 获取内存状态
    if (GlobalMemoryStatusEx(&memStatus)) {

        ui->label_memory_total->setText(QString::number((memStatus.ullTotalPhys / (1024 * 1024))));
        ui->label_memory_ava->setText(QString::number((memStatus.ullAvailPhys / (1024 * 1024))));
        ui->label_memory->setText(QString::number(memStatus.dwMemoryLoad)+"%");

    }
}

mingW环境使用 PDH库

在MinGW环境中使用PDH库可能会比较困难,因为MinGW可能没有包含全部的Windows平台SDK。然而,你可以尝试以下几种方法来使用PDH库:

  1. 手动链接PDH库:

    尽管MinGW的标准库中可能不包含PdhAddEnglishCounter,但PDH库(pdh.dll)通常是安装在Windows系统中的。你可以尝试手动链接这个库。在Qt项目文件(.pro)中添加以下行来链接PDH库:

    LIBS += -L"C:/Path/To/Pdh/Lib" -lpdh
    

    需要把"C:/Path/To/Pdh/Lib"替换为实际的库文件路径,如果pdh.lib文件在标准的库路径中,那么你只需要添加-lpdh

  2. 动态加载PDH库:

    你可以在运行时动态加载pdh.dll,使用QLibrary或者Windows API函数LoadLibraryGetProcAddress来加载库并获取函数指针。

    QLibrary pdhLib("pdh");
    if (pdhLib.load()) {
        auto PdhAddEnglishCounterW =
            (PDH_STATUS(WINAPI*)(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER*))pdhLib.resolve("PdhAddEnglishCounterW");
        if (PdhAddEnglishCounterW) {
            // 使用 PdhAddEnglishCounterW
        }
    }
    

    在这个例子中,QLibrary用于加载pdh.dll,然后使用resolve方法查找PdhAddEnglishCounter函数。

  3. 使用LoadLibrary和GetProcAddress:

    如果你不想使用Qt的QLibrary,你可以直接使用Windows API。

    HMODULE hPdh = LoadLibrary(TEXT("pdh.dll"));
    if (hPdh) {
        auto PdhAddEnglishCounter = (PDH_STATUS(WINAPI*)(PDH_HQUERY, LPCSTR, DWORD_PTR, PDH_HCOUNTER*))GetProcAddress(hPdh, "PdhAddEnglishCounterA");
        if (PdhAddEnglishCounter) {
            // 使用 PdhAddEnglishCounter
        }
        FreeLibrary(hPdh);
    }
    

    使用LoadLibrary加载pdh.dll并使用GetProcAddress获取PdhAddEnglishCounterA函数的指针。

  4. 使用MSYS2或Cygwin:

    如果你使用的是MSYS2或Cygwin,它们可能会有自己的PDH封装或者更好的对Windows API的支持。你可能需要在这些环境中查找是否有PDH的封装。

如果以上方法都不可行,你可能需要考虑更换到支持完整Windows API的编译环境,例如Microsoft Visual Studio。或者,如果你需要的PDH功能比较简单,你可能可以通过直接读取系统文件或使用其他系统命令来代替PDH库的功能。

程序运行效果

☞ 源码

源码链接:GitHub仓库自取

使用方法:☟☟☟


博客签名2021

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

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

相关文章

C++学习day--25 俄罗斯方块游戏图像化开发

项目分析 项目演示、项目分析 启动页面 启动页面&#xff1a; 分析&#xff1a; 开发环境搭建 1&#xff09;安装vc2010, 或其他vs版本 2&#xff09;安装easyX图形库 代码实现: # include <stdio.h> # include <graphics.h> void welcome(void) { initgraph(55…

【MySQL】MySQL如何查询和筛选存储的JSON数据?

MySQL如何查询和筛选存储的JSON数据&#xff1f; 一、背景介绍二、支持的JSON数据类型三、基础数据3.1 创建表3.2 插入 JSON 数据3.3 查询 JSON 数据 四、操作函数4.1 JSON_OBJECT4.2 JSON_ARRAY4.3 JSON_EXTRACT 一、背景介绍 JSON(JavaScript Object Notation)是一种轻量级的…

如何通过内网穿透实现无公网IP远程访问内网的Linux宝塔面板

文章目录 一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

dubbo的基础知识

dubbo是什么 Dubbo是一个分布式服务框架&#xff0c;是一种高性能的远程通讯框架。它提供了基于Java的RPC&#xff08;远程过程调用&#xff09;通信机制&#xff0c;使得应用之间可以方便地进行远程调用&#xff0c;实现分布式服务的调用和管理。Dubbo提供了服务注册、发现、负…

轻松获取CHATGPT API:免费、无验证、带实例

免费获取和使用ChatGPT API的方法 快速开始&#xff1a;视频教程 章节一&#xff1a;GPT-API-Free开源项目介绍 GPT-API-Free 是一个开源项目&#xff0c;它提供了一个中转API KEY&#xff0c;使用户能够调用多个GPT模型&#xff0c;包括gpt-3.5-turbo、embedding和gpt-4。这…

cesium键盘控制模型

效果&#xff1a; 由于对添加模型和更新位置api进行二次了封装&#xff0c;下面提供思路 1.添加模型 const person reactive({modelTimer: null,position: {lon: 104.07274,lat: 30.57899,alt: 1200,heading: 0,pitch: 0,roll: 0,}, }); window.swpcesium.addEntity.addMo…

8.1分发饼干(LC455-E)

算法&#xff1a; 局部最优&#xff1a;大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子&#xff0c;那么就应该优先满足胃口大的。局部最优就是大饼干喂给胃口大的&#xff0c;充分利用饼干尺寸喂饱一个。 全局最优&#xff1a;喂饱尽可能多的小孩。 为什么局部…

C++开发小技巧

C开发一些小技巧 积累一些能用得到的C开发小技巧。 错误码/状态码 错误码/状态码在项目很常见&#xff0c;用于提示错误类型、状态&#xff0c;通常还会附带一些相关描述。通常错误码是统一管理的&#xff0c;例如使用宏或者枚举定义。 平时我的做法 使用宏或者枚举定义错…

Redis缓存保卫战:拒绝缓存击穿的进攻【redis问题 三】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Redis缓存保卫战&#xff1a;拒绝缓存击穿的进攻 前言缓存击穿的定义和原理为何会发生缓存击穿缓存击穿的危害防范缓存击穿结语: 前言 你是否曾经遇到过系统在高并发情况下出现严重性能问题&#xff…

【ASP.NET Core 基础知识】--环境设置

一、简介 1.1 .NET Core SDK 概述 .NET Core SDK&#xff08;Software Development Kit&#xff09;是Microsoft推出的一个开源跨平台框架&#xff0c;用于开发和部署.NET应用程序。它是.NET Core平台的核心组件之一&#xff0c;为开发者提供了在多个操作系统上构建高性能、可…

ssm基于VUE的图书馆管理系统的设计与实现论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#x…

imazing破解版百度云2.17.3(附激活许可证下载)

iMazing是一款强大的 iOS 设备管理软件&#xff0c;不管是 iPhone、iPad 或 iPod Touch 设备&#xff0c;只要将 iOS 设备连接到计算机&#xff0c;就可以处理不同类型的数据。 iPhone 和 iPad 备份 借助 iMazing 的独有 iOS 备份技术&#xff08;无线、隐私和自动&#xff09…

CarRacing DQN: 深度 Q 学习训练自驾车

OpenAI GYM CarRacing DQN: 深度 Q 学习训练自驾车 引言DQN 算法原理Q 值和 Bellman 方程DQN 结构 训练过程设计经验回放&#xff08;Experience Replay&#xff09;目标网络&#xff08;Target Network&#xff09;训练循环 训练结果和模型演变400 轮训练后500 轮训练后600 轮…

tomcat session cookie值设置逻辑

tomcat session cookie 值设置&#xff0c;tomcat jsessionid设置 ##调用request.getSession() Controller RequestMapping("/cookie") public class CookieController {RequestMapping("/tomcatRequest")ResponseBodypublic String tomcatRequest(HttpS…

buuctf-Misc 题目解答分解109-111

109.[CFI-CTF 2018]webLogon capture 流量包分析&#xff0c; wireshark 打开 就这几个数据包&#xff0c;追踪http 进行url 解码 URL网址解码器 - 在线网址解码 得到flag CFI{1ns3cur3_l0g0n} 110.[GKCTF 2021]excel 骚操作 下载 excel 文件 &#xff0c;打开 发现点击其他地…

编程语言的发展趋势和未来方向

1、编程语言的未来&#xff1f; 随着科技的飞速发展&#xff0c;编程语言在计算机领域中扮演着至关重要的角色。它们是软件开发的核心&#xff0c;为程序员提供了与机器沟通的桥梁。那么&#xff0c;在技术不断进步的未来&#xff0c;编程语言的走向又将如何呢&#xff1f; 方…

通信原理期末复习——计算大题(一)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

金和OA C6 MailTemplates.aspx sql注入漏洞

产品介绍 金和网络是专业信息化服务商,为城市监管部门提供了互联网监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。 漏洞概述 金和 OA C6 MailTemplates.aspx接口处存在SQL注入漏洞&#xff0c;攻击者除了可以利用 SQL 注入漏…

计算机毕业设计选题分享-SSM律师事务所业务管理系统01664(赠送源码数据库)JAVA、PHP,node.js,C++、python,大屏数据可视化等

SSM律师事务所业务管理系统 摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;律师事务所业务管理系统当然也不能排除在外。律师事务所业务管理系统是以实际运用为开发背景…

牛客网BC12-字符圣诞树

字符圣诞树 解题思路&#xff1a; 确定行数&#xff0c;一共5行&#xff0c;循环5次确定每行答应的内容&#xff0c;分成两部分&#xff0c;空格和字符 打印空格的个数依次递减打印字符的个数依次递增 找出打印空格和字符的个数与行数之间的关系 int main() {char ch 0;scanf(…