windows环境下使用QT实现内存百分比显示小程序

前言

最近换了 windows11 系统,感觉 windows11 的安全做的比 windows10 好了很多,就没再使用其他的安全管理软件,但是我又想只查看内存的使用率,有没有一个好的软件,就尝试着使用 QT 自己写了一个,过程中查阅了很多资料,都没有完整的实现说明,所以写了这篇文章说说我是如何完成自己的内存显示小程序的。

环境介绍

我是用的是 QT-5.14.2
windows11 系统

准备资源

我们需要准备一张图片用作背景,我这里准备了两张图片,一张是全白的正方形图片和一张半透明的正方形图片
一张图片用于退出菜单图标

这里我是希望在调试程序的时候能够看到背景,用于调整数字的位置,但是完成之后我又想要透明的效果,所以我的是两张图片,这里准备的图片最好是中间显示部分为白色,这样比较容易看清

创建项目

  1. 我这里创建了一个名为RAMshow 的应用程序
  2. DetailsBase class 选的 QWidget
  3. Kits 选的 MinGW 64bit

其他的选项默认即可

导入资源图片

依次点击 文件 -> 新建文件或项目 -> Qt -> Qt Resource File 名称我填的 res,下一步,点击完成。
添加路径,点击 Add Prefix, 修改前缀为 /res
添加文件,点击Add Files将之前的所有图片添加进来
点击build构建项目

需要注意,这里我的图片是放在项目里面的,我在项目中新建了一个 res 的文件夹,将图片放在了这里面,不然程序运行可能无法使用

目录结构如下:


Snipaste_2021-12-03_10-34-51.jpg

资源文件如下:


Snipaste_2021-12-03_11-16-24.jpg

显示托盘图标

参考文章 :
https://blog.csdn.net/u012952807/article/details/70670410?spm=1001.2014.3001.5501

我们需要使用以下头文件:

#include  // 操作托盘的类
#include 

widget.h中添加头文件,添加以下代码:

private:
    QSystemTrayIcon  *icon;   // 托盘图像
    QPixmap image;

在widget.cpp构造函数中初始化:

// :/res/res/ram_show_no_transparent.png 此路径在资源图片上右键,选择`Copy Path`即可复制
image.load(":/res/res/ram_show_no_transparent.png");
icon = new QSystemTrayIcon(this);
icon->setIcon(image);
icon->show()

此时可以在托盘中看见一个白色的正方形。

获取内存信息并显示在图标上

参考文章
https://blog.csdn.net/u012952807/article/details/70674034?spm=1001.2014.3001.5501

需要使用一下头文件:

#include 
#include 
#include 

widget.h中添加头文件,添加以下代码:

private:
    QPainter *painter; //画笔,将数字画到图片上
    QTimer *timer; // 添加定时器,用于刷新内存信息
    QFont font; // 设置数字的显示样式
private slots:
    void update(); // 用于刷新icon的数字

在widget.cpp构造函数中初始化:

painter = new QPainter();

font.setPointSize(65); //设置字体大小
font.setBold(true); // 是否加粗
timer = new QTimer(this); // 初始化定时器

添加 update() 函数的定义:

void Widget::update()
{
    // 获取内存使用率
    MEMORYSTATUSEX statusex;
    statusex.dwLength=sizeof(statusex);
    GlobalMemoryStatusEx(&statusex);
    long s = statusex.dwMemoryLoad;
    
    // 在原有的图片上添加数字
    QPixmap base = image;

    // 将长整型转为字符类型
    QString text = QString::number(s);
    painter->begin(&base);
    painter->setFont(font);

    // 前两个参数是坐标,根据自己的实际情况修改
    painter->drawText(2, 75, text);
    painter->end();

    // 修改托盘图标
    icon->setIcon(QIcon(base));
}

运行程序,可以看到右下角的图标上出现了数字。

添加右键菜单

参考文章 :
https://www.cxyzjd.com/article/weixin_42126427/106697190

之前的程序没有设置菜单用于退出,所以我们每次运行都有一个窗口,现在,我们将窗口显示注释掉。
main.cpp 中将 w.show() 注释掉。
接着我们给程序的托盘图标添加右键菜单
widget.cpp 中添加:

#include 

在初始化方法中添加代码:

需要写到icon->setIcon(QIcon(image));的后面,icon->show(); 前面

    // 添加右键菜单
    QMenu *menu = new QMenu(this);

    QAction *quit = new QAction("退出", this);
    
    // 为菜单按钮添加图标
    quit->setIcon(QIcon(":/res/res/quit.png"));

    menu->addAction(quit);

    icon->setContextMenu(menu);

    // 绑定退出
    connect(quit, &QAction::triggered, qApp, &QApplication::quit);

运行项目,由于注释了main函数中的show()方法,运行是不会像之前一样弹出窗口,右键托盘图标,点击退出,功能正常就表示成功了。

添加开机自启

参考文章
https://www.i4k.xyz/article/thequitesunshine007/119605740

开机启动需要使用到两个类,在widget.h中添加:

#include 
#include 

public:
    //添加函数
    void setAutoRun();

添加自启动需要修改注册表,路径为
"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
widget.cpp中初始化函数:

// 在`include`后面添加一行
#define AUTO_RUN "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
// 定义函数
void Widget::setAutoRun()
{
    // 注册表是以 key-value 形式存储的,一般使用程序名称作为 key
    // 64 bit的系统使用 QSettings::Registry64Format, 32bit 使用 QSettings::Registry32Format
    QSettings *settings = new QSettings(AUTO_RUN, QSettings::Registry64Format);
    QString application_name = QApplication::applicationName();//获取应用名称

    QString path = settings->value(application_name).toString();
    QString appPath = QApplication::applicationFilePath();//找到应用的目录
    QString newPath = QDir::toNativeSeparators(appPath);
    if (path != newPath)
    {
        settings->setValue(application_name, newPath);
    }
}

在main函数中调用方法

w.setAutoRun();
//    w.show();

运行程序,查看注册表,可以看见一个以程序名称为key的值存在,表示成功。
最后修改icon为透明效果。
到这里就全部完工了。

源码

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    void setAutoRun();

private:
    Ui::Widget *ui;

    QSystemTrayIcon *icon;
    QPixmap image;
    QPainter *painter;
    QTimer *timer;
    QFont font;
    

private slots:
    void update();
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include 
#include 
#include 

#define AUTO_RUN "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    painter = new QPainter();

    font.setPointSize(65);
    font.setBold(true);
    timer = new QTimer(this);


    image.load(":/res/res/ram_show_no_transparent.png");
    icon = new QSystemTrayIcon(this);
    icon->setIcon(image);

    // 添加右键菜单
    QMenu *menu = new QMenu(this);

    QAction *quit = new QAction("退出", this);
    
    // 为菜单按钮添加图标
    quit->setIcon(QIcon(":/res/res/quit.png"));

    menu->addAction(quit);

    icon->setContextMenu(menu);

    // 绑定退出
    connect(quit, &QAction::triggered, qApp, &QApplication::quit);

    icon->show();

    // 刚启动时进行一次跟新
    update();

    // 设置定时器,每隔3s跟新一次
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));

    timer->start(3000);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::setAutoRun()
{
    QSettings *settings = new QSettings(AUTO_RUN, QSettings::Registry64Format);
    QString application_name = QApplication::applicationName();//获取应用名称

    QString path = settings->value(application_name).toString();
    QString appPath = QApplication::applicationFilePath();//找到应用的目录
    QString newPath = QDir::toNativeSeparators(appPath);
    if (path != newPath)
    {
        settings->setValue(application_name, newPath);
    }
}

void Widget::update()
{
    // 获取内存使用率
    MEMORYSTATUSEX statusex;
    statusex.dwLength=sizeof(statusex);
    GlobalMemoryStatusEx(&statusex);
    long s = statusex.dwMemoryLoad;

    // 在原有的图片上添加数字
    QPixmap base = image;

    // 将长整型转为字符类型
    QString text = QString::number(s);
    painter->begin(&base);
    painter->setFont(font);

    // 前两个参数是坐标,更具自己的实际情况修改
    painter->drawText(2, 75, text);
    painter->end();

    // 修改托盘图标
    icon->setIcon(QIcon(base));
}

main.cpp

#include "widget.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setAutoRun();
//    w.show();
    return a.exec();
}

你可能感兴趣的:(windows环境下使用QT实现内存百分比显示小程序)