QT实现Linux下系统监控CPU、内存、进程信息小工具

QT实现Linux下系统监控小工具

QT实现Linux下系统监控小工具

前段时间在做linux操作系统的实验,其中有一个实验要求读取linux系统/proc文件目录下的cpu、内存、和进程的相关信息。并计算CPU使用率,内存使用率。
例如在终端输入 #cat /proc/stat 获得的信息。
在这里插入图片描述#cat /proc/meminfo
在这里插入图片描述

需要访问文件夹/proc/stat , /proc/meminfo , /proc/[进程号]/stat;

配置和环境

Ubuntu 18.04操作系统;
VMware Workstation Pro;

–虚拟机配置------设置两个CPU
(注意CPU设置个数,如果不同的话可能需要对代码进行修改)

运行结果展示

图片: QT程序运行结果
在这里插入图片描述
在这里插入图片描述表格中的信息每秒刷新一次(实时刷新);

代码片段

以下展示部分核心代码

头文件.

// An highlighted block
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QDateTime>
#include <QMessageBox>
#include <QDateTime>
#include <QListWidget>
#include <QDebug>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void SystemTime();//显示当前系统时间
    void Updata_table();
    /************设置表格**************/
    void Set_table_cpu();//设置表格
    void Set_Table_mem(int mem_row,int mem_line);
    void Set_table_pro(int pro_row,int pro_line);

    QStringList Get_cpuinfo(QString path ="/proc/stat");//获得cpu信息
    QStringList Get_meminfo(QString path ="/proc/meminfo");//获得mem信息
    void Get_proinfo(QString path ="/proc");//获得process信息

    void Printf_cpu(QStringList cpulist);//打印CPU表格
    void Printf_mem(QStringList memlist);//打印memory表格
    void Printf_pro(QString proname,QStringList prolist,int count_pro);//打印process表格
    
private:
    Ui::MainWindow *ui;
    time_t system_time;
    struct tm *time_now;
    QTimer *timer;

    QString cpufile="/proc/stat";
    QString memfile="/proc/meminfo";
    QString profile="/proc";

    float cpu_usage;
    float mem_usage;

public:
    int showfile=0;
    int count_pro=0;

    int cpu_row=15;//行数
    int cpu_line=11;//列数
    int mem_row=40;//行数
    int mem_line=3;//列数
    int pro_row=300;//行数,缺省值
    int pro_line=14;//列数

    QStringList cpulist;
    QStringList memlist;
    QStringList prolist;
};

#endif // MAINWINDOW_H

其实只有一个MainWindow.h文件,所以结构成员设置为private或者public都无所谓

核心文件.

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("linux系统监控");
    //Set_Table();
    timer=new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(SystemTime()));
    connect(timer,SIGNAL(timeout()),this,SLOT(Updata_table()));

    timer->start(1000);
}

MainWindow::~MainWindow()
{
    delete ui;
}
/***************系统时间刷新*****************/
void MainWindow::SystemTime()
{
    //qDebug()<<"刷新系统时间";
    ui->timelabel->setText(QDateTime::currentDateTime().toString("hh:mm:ss"));
    ui->datelabel->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd"));
}
/***************信息表格刷新*****************/
void MainWindow::Updata_table()
{
    //qDebug()<<"刷新表格信息";
    cpulist=Get_cpuinfo(cpufile);
    if(!cpulist.empty())
    {
        Printf_cpu(cpulist);
    }
    memlist=Get_meminfo(memfile);
    if(!cpulist.empty())
    {
        Printf_mem(memlist);
    }
    Get_proinfo(profile);
}
/***************获得CPU信息****************/
QStringList MainWindow::Get_cpuinfo(QString path)
{
    //获取文件路径及名称
    QStringList cpulist;
    QByteArray array;
    if(path.isEmpty() == false)//判断路径是否为空
    {
        QFile file(path);//指定文件路径
        bool isOk = file.open(QIODevice::ReadOnly);//检查文件打开情况
        if(isOk == true)
        {
            array = file.readAll();//读文件 内容放到字节组
            cpulist = QString(array).split('\n');       //通过“\n”将整个文件内容按字符串进行存储
        }
        else
        {
            qDebug()<<"文件打开错误"<<"\n"<<path;
            return {};
        }
        file.close();//文件关闭
    }
    if(showfile==1){
    QFileInfo  info(path);
    qDebug()<<"获取CPU信息"<<"\n"<<cpulist;
    qDebug()<<"文件创建时间:"<<info.created().toString("yyyy-MM-dd hh:mm:ss");//2019-01-01 11:11:00的格式
    }
    return cpulist;
}
/***************获得内存信息*****************/
QStringList MainWindow::Get_meminfo(QString path)
{
    //QString path = QFileDialog::getOpenFileName(this,"打开文件","/proc/meminfo");//获取文件路径及名称
    //QString path ="/proc/meminfo";
    QStringList memlist;
    QByteArray array;
    if(path.isEmpty() == false)//判断路径是否为空
    {
        QFile file(path);//指定文件路径
        bool isOk = file.open(QIODevice::ReadOnly);//检查文件打开情况
        if(isOk == true)
        {
            array = file.readAll();//读文件 内容放到字节组
            memlist = QString(array).split('\n');        //通过“\n”将整个文件内容按字符串进行存储
        }
        file.close();//文件关闭
    }
    //qDebug()<<path<<"memlist"<<memlist;
    return memlist;
}
/***************process信息显示*****************/
void MainWindow::Get_proinfo(QString path)
{
    QString statfile;//暂时文件名
    QStringList prolist;
    QString proname,proinfo;
    QByteArray array;
    ui->tableWidget_pro->clearContents();//每次刷新内容
    count_pro=0;
    QDir *dir=new QDir(path);
    QStringList filter;//文件名表单
    QList<QFileInfo> *fileInfo=new QList<QFileInfo>(dir->entryInfoList(filter));//获取文件夹下所有文件数目及名字
    //设置表格
    for(int i = 0,pro_row=0;i<fileInfo->count(); i++)
    {
        statfile=fileInfo->at(i).filePath()+"/stat";
        //qDebug()<<pro_row<<statfile;
        QFile file(statfile);//指定文件路径
        bool isOk = file.open(QIODevice::ReadOnly);
        if(isOk && statfile.isEmpty()== false && statfile!="/proc/./stat")//判断路径是否为空
            pro_row++;
        if(i==fileInfo->count()-1)
            Set_table_pro(pro_row,pro_line);
    }

    for(int i = 0;i<fileInfo->count(); i++)
    {
        statfile=fileInfo->at(i).filePath()+"/stat";
        //qDebug()<<statfile+"   "<<fileInfo->at(i).path();//路径
        if(statfile.isEmpty() == false&&statfile!="/proc/./stat")//判断路径是否为空
        {
            QFile file(statfile);//指定文件路径
            bool isOk = file.open(QIODevice::ReadOnly);//检查文件打开情况
            if(isOk == true)
            {
                array = file.readAll();//读文件 内容放到字节组
                proinfo=QString(array);
                int start = proinfo.indexOf("(", 0);
                int end = proinfo.lastIndexOf(")");
                QString proname = proinfo.mid(start, end-start+1);//提取进程名字
                proinfo.remove(proname);//提取进程其他信息
                prolist = proinfo.split(QRegExp("\\s+"), QString::SkipEmptyParts);        //通过将整个文件内容按字符串进行存储
                //qDebug()<<count_pro++<<proname<<proinfo;
                if(count_pro<fileInfo->count())
                    Printf_pro(proname,prolist,count_pro++);
            }
            file.close();//文件关闭
        }
    }
}
void MainWindow::Printf_cpu(QStringList cpulist)
{
    //qDebug()<<"获取CPU信息\n"<<cpulist;
    ui->tableWidget_cpu->clearContents();//每次刷新内容
    Set_table_cpu();
    QStringList temlist;
    for(int i=0;i<3;i++)
        {
          temlist = cpulist.at(i).split(QRegExp("\\s+"), QString::SkipEmptyParts);//按一个或多个空格分割
          if(i==0)//计算CPU使用率
          {
            cpu_usage=100*(temlist.at(0).toFloat()+temlist.at(1).toFloat()+temlist.at(2).toFloat())/(temlist.at(0).toFloat()+temlist.at(1).toFloat()+temlist.at(2).toFloat()+temlist.at(3).toFloat());
            //qDebug()<<cpu_usage<<"cpu使用率\n";
            ui->cpu_usage->setText(QString("%1").arg(cpu_usage)+"%");
          }
            for(int j=0;j<cpu_line;j++)
            {
               ui->tableWidget_cpu->setItem(i,j,new QTableWidgetItem(temlist.at(j)));
            }
        }
    ui->tableWidget_cpu->setItem(3,0,new QTableWidgetItem("# 这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数\n# 然后每个数对应一个特定的中断自系统启动以来所发生的次数。"));
    ui->tableWidget_cpu->setItem(4,0,new QTableWidgetItem(cpulist.at(3)));
    for(int i=5;i<10;i++)
        {
        temlist = cpulist.at(i).split(QRegExp("\\s+"), QString::SkipEmptyParts);//按一个或多个空格分割
        //qDebug()<<"获取CPU信息\n"<<temlist;
        for(int j=0;j<2;j++)
            {
            ui->tableWidget_cpu->setItem(i+3,j,new QTableWidgetItem(temlist.at(j)));
            }
        }

    temlist = cpulist.at(9).split(QRegExp("\\s+"), QString::SkipEmptyParts);//按一个或多个空格分割
    for(int j=0;j<cpu_line;j++)//最后一行
        {
        ui->tableWidget_cpu->setItem(12,j,new QTableWidgetItem(temlist.at(j)));
        }
}

void MainWindow::Printf_mem(QStringList memlist)
{
    ui->tableWidget_mem->clearContents();//每次刷新内容
    mem_row=0;
    while(memlist.at(mem_row).isEmpty() == false)
        mem_row++;//获取内存信息行数
    Set_Table_mem(mem_row,mem_line);
    for(int i=0;i<mem_row;i++)
        {
        ui->tableWidget_mem->setItem(i,0,new QTableWidgetItem(memlist.at(i)));
        }
     /***************计算内存使用率*****************/
     QStringList tem1,tem2;
     tem1 = memlist.at(0).split(QRegExp("\\s+"), QString::SkipEmptyParts);//按一个或多个空格分割
     tem2 = memlist.at(1).split(QRegExp("\\s+"), QString::SkipEmptyParts);//按一个或多个空格分割
     mem_usage=(1-(tem2.at(1).toFloat()/tem1.at(1).toFloat()))*100;
     //qDebug()<<tem1<<"获取CPU信息\n"<<tem2<<"获取CPU信息\n"<<mem_usage;
     ui->mem_usage->setText(QString("%1").arg(mem_usage)+"%");
}

void MainWindow::Printf_pro(QString proname,QStringList prolist,int count_pro)
{
    //qDebug()<<count_pro<<"获取进程信息\n"<<prolist;
    for(int j=0;j<pro_line;j++)
     {
          //qDebug()<<prolist.at(j);
        if(j==0)
            ui->tableWidget_pro->setItem(count_pro,j,new QTableWidgetItem(proname));
        else
            ui->tableWidget_pro->setItem(count_pro,j,new QTableWidgetItem(prolist.at(j-1)));
      }
}

void MainWindow::Set_table_cpu()
{
    /**********设置CPU信息**********/
    ui->tableWidget_cpu->setRowCount(cpu_row); //设置行数为10
    ui->tableWidget_cpu->setColumnCount(cpu_line); //设置列数为5
    ui->tableWidget_cpu->setSpan(3, 0, 1, 11);
    ui->tableWidget_cpu->setSpan(4, 0, 3, 11);
    ui->tableWidget_cpu->setShowGrid(false);//显示表格线
    ui->tableWidget_cpu->verticalHeader()->setVisible(false);//隐藏列名
    ui->tableWidget_cpu->setColumnWidth(0,120);//设置第一列宽度

    QStringList headers1 = {"name", "user", "nice","system", "idle", "iowait","irrq", "softirq", "steal","guest" ,"guest_nice"};
    ui->tableWidget_cpu->setHorizontalHeaderLabels(headers1);
    //qDebug()<<"设置表格标题cpu"<<headers1;
}
void MainWindow::Set_Table_mem(int mem_row,int mem_line)
{
    /**********设置内存信息**********/
    ui->tableWidget_mem->setRowCount(mem_row);
    ui->tableWidget_mem->setColumnCount(mem_line);
    ui->tableWidget_mem->horizontalHeader()->setVisible(false);//隐藏行名
    ui->tableWidget_mem->setColumnWidth(0,800);
    ui->tableWidget_mem->setShowGrid(false);//显示表格线
}
void MainWindow::Set_table_pro(int pro_row,int pro_line)
{
    /**********设置进程信息**********/
    ui->tableWidget_pro->setRowCount(pro_row);
    ui->tableWidget_pro->setColumnCount(pro_line);
    //ui->tableWidget_pro->resizeColumnsToContents(); //行列宽度匹配
    //ui->tableWidget_pro->resizeRowsToContents();
    QStringList headers2 = {"进程名称", "进程号","状态", "父进程ID","线程组ID", "会话", "终端设备号","进程组号", "进程标志位", "累计缺页","子进程缺页" ,"主缺页数","用户态运行时间" ,"核心态运行时间"};
    ui->tableWidget_pro->setHorizontalHeaderLabels(headers2);
    //qDebug()<<"设置表格标题pro"<<headers2;
}

总结

比较简单的linux系统监控;在学习过程中也学到了很多QT和C++使用知识。例如如何打开文件读取文件信息,如何设置表格,如何截取字符串,如何分类字符串等操作。

后期还可以添加其他功能,但我已经检查完毕,估计不会再改进。


有很久不关注csdn了,一个写得很水的项目。源码在这 https://github.com/ve-weiyi/linux_monitor.git

  • 9
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
可以使用Qt提供的QSystemTrayIcon类和QTimer类来实现系统资源监控。 首先,使用QSystemTrayIcon类创建一个系统托盘图标,并在其菜单中添加“退出”选项。然后,使用QTimer类定时获取CPU内存使用情况,并将其显示在托盘图标的提示消息中。 以下是一个简单的示例代码: ```cpp #include <QtWidgets> #include <QtCharts> class SystemMonitor : public QMainWindow { Q_OBJECT public: SystemMonitor(QWidget *parent = nullptr); private slots: void updateSystemInfo(); private: QSystemTrayIcon *m_trayIcon; QTimer *m_timer; QChartView *m_chartView; QLineSeries *m_cpuSeries; QLineSeries *m_memorySeries; }; SystemMonitor::SystemMonitor(QWidget *parent) : QMainWindow(parent) { m_trayIcon = new QSystemTrayIcon(this); m_trayIcon->setIcon(QIcon(":/icons/system-monitor.png")); m_trayIcon->show(); QMenu *trayMenu = new QMenu(this); trayMenu->addAction("退出", qApp, &QApplication::quit); m_trayIcon->setContextMenu(trayMenu); m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, &SystemMonitor::updateSystemInfo); m_timer->start(1000); m_cpuSeries = new QLineSeries(this); m_cpuSeries->setName("CPU"); m_memorySeries = new QLineSeries(this); m_memorySeries->setName("Memory"); QChart *chart = new QChart(); chart->addSeries(m_cpuSeries); chart->addSeries(m_memorySeries); chart->createDefaultAxes(); chart->setTitle("System Monitor"); m_chartView = new QChartView(chart, this); m_chartView->setRenderHint(QPainter::Antialiasing); setCentralWidget(m_chartView); } void SystemMonitor::updateSystemInfo() { // 获取CPU内存使用情况 qreal cpuUsage = 0; qreal memoryUsage = 0; // TODO: 获取CPU内存使用情况的代码 // 将使用情况添加到图表 m_cpuSeries->append(QDateTime::currentMSecsSinceEpoch(), cpuUsage); m_memorySeries->append(QDateTime::currentMSecsSinceEpoch(), memoryUsage); // 更新托盘图标的提示消息 QString tooltip = QString("CPU: %1%\nMemory: %2%").arg(cpuUsage).arg(memoryUsage); m_trayIcon->setToolTip(tooltip); } int main(int argc, char *argv[]) { QApplication app(argc, argv); SystemMonitor monitor; monitor.show(); return app.exec(); } ``` 注意:获取CPU内存使用情况的代码需要根据不同的操作系统进行调整。在Windows上,可以使用Qt提供的QProcess类执行"tasklist"和"wmic"命令获取进程列表和系统信息。在Linux上,可以使用"/proc"文件系统获取系统信息
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值