• linux系统Qt实现简单的任务管理器


    继续上次的操作系统课设,这次需要设计一个简单的任务管理器,大部分人选择GTK来实现,我剑走偏锋,使用Qt来完成这个任务。

    用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。

    我们要显示系统信息,只需进行相应的文件操作就行了。

    首先需要下载一份Qt的SDK,这是Qt的英文官网:http://qt.nokia.com/,当然也有中文版的:http://qt.nokia.com/title-cn/

    别问我为什么有个nokia,那是因为Qt是诺基亚开发的一个跨平台的C++图形用户界面应用程序框架。

    Qt商业版只能试用30天,不过有GPL版的,可以免费使用。官网上还有一个非常不错的免费Qt集成开发环境Qt Creator IDE。我使用的就是这个软件:

    打开相应的文件,读取所需要的信息,将其显示在控件上就可以了。

    我采用的是Qt来实现图形界面。

     

    工程文件夹:

      

    编译完成后的实现效果:

     

    这个实验总的来讲还是比较简单的,源码如下:

    main.cpp

    1. #include <QtGui/QApplication> 
    2. #include "mainwindow.h" 
    3.  
    4. int main(int argc, char *argv[]) 
    5.     QApplication a(argc, argv); //应用程序类,每个应用程序有且只有一个 
    6.     MainWindow w; //实例化MainWindow类 
    7.     w.show(); //显示界面 
    8.     return a.exec(); //进入应用程序的循环中,直到程序退出 

    mainwindow.h

    1. #ifndef MAINWINDOW_H 
    2. #define MAINWINDOW_H 
    3.  
    4. #include <QMainWindow> 
    5.  
    6. namespace Ui { 
    7.     class MainWindow; 
    8.  
    9. class MainWindow : public QMainWindow 
    10.     Q_OBJECT 
    11. public: 
    12.     explicit MainWindow(QWidget *parent = 0); 
    13.     ~MainWindow(); 
    14. private: 
    15.     Ui::MainWindow *ui; //界面资源类,所有的界面元素都是通过该类来调用 
    16.     QTimer *timer; //计时器 
    17.  
    18. private slots: 
    19.     void on_pushButton_pkill_clicked(); 
    20.     void on_pushButton_prefresh_clicked(); 
    21.     void on_pushButton_Model_install_clicked(); 
    22.     void on_pushButton_Model_remove_clicked(); 
    23.     void on_pushButton_Model_refresh_clicked(); 
    24.     void on_pushButton_reboot_clicked(); 
    25.     void on_pushButton_halt_clicked(); 
    26.     void on_tabWidget_INFO_currentChanged(int index); 
    27.     void timer_update_currentTabInfo(); 
    28.     //显示tab中的内容 
    29.     void show_tabWidgetInfo(int index); 
    30. }; 
    31.  
    32. #endif // MAINWINDOW_H 

    mainwindow.cpp

    1. #include "mainwindow.h" 
    2. #include "ui_mainwindow.h" 
    3.  
    4. #include <QFile> 
    5. #include <QMessageBox> 
    6. #include <QDir> 
    7. #include <QListWidget> 
    8. #include <QListWidgetItem> 
    9. #include <QStringList> 
    10. #include <QTimer> 
    11.  
    12. int a0 = 0, a1 = 0, b0 = 0, b1 = 0; 
    13.  
    14. MainWindow::MainWindow(QWidget *parent) : //构造函数,初始化ui,计时器 
    15.     QMainWindow(parent), 
    16.     ui(new Ui::MainWindow) 
    17.     ui->setupUi(this); 
    18.     timer = new QTimer(this); 
    19.     QWidget::connect( timer, SIGNAL( timeout() ), this, SLOT( timer_update_currentTabInfo() ) ); 
    20.     QWidget::connect( ui->tabWidget_INFO, SIGNAL( currentChanged() ), 
    21.                       this, SLOT( on_tabWidget_currentChanged() ) ); 
    22.     timer->start(1000); 
    23.  
    24. MainWindow::~MainWindow() 
    25.     delete ui; 
    26.     delete timer; 
    27.  
    28. void MainWindow::timer_update_currentTabInfo() 
    29.     int index = ui->tabWidget_INFO->currentIndex(); 
    30.     //定时器只刷新内存tab页面,用于进度条动态显示 
    31.     if (index == 0) 
    32.     { 
    33.         show_tabWidgetInfo(index); 
    34.     } 
    35.  
    36. void MainWindow::show_tabWidgetInfo(int index) 
    37.     QString tempStr; //读取文件信息字符串 
    38.     QFile tempFile; //用于打开系统文件 
    39.     int pos; //读取文件的位置 
    40.  
    41.     if (index == 0) //内存資源 
    42.     { 
    43.         tempFile.setFileName("/proc/meminfo"); //打开内存信息文件 
    44.         if ( !tempFile.open(QIODevice::ReadOnly) ) 
    45.         { 
    46.             QMessageBox::warning(this, tr("warning"), tr("The meminfo file can not open!"), QMessageBox::Yes); 
    47.             return ; 
    48.         } 
    49.         QString memTotal; 
    50.         QString memFree; 
    51.         QString memUsed; 
    52.         QString swapTotal; 
    53.         QString swapFree; 
    54.         QString swapUsed; 
    55.         int nMemTotal, nMemFree, nMemUsed, nSwapTotal, nSwapFree, nSwapUsed; 
    56.  
    57.         while (1) 
    58.         { 
    59.             tempStr = tempFile.readLine(); 
    60.             pos = tempStr.indexOf("MemTotal"); 
    61.             if (pos != -1) 
    62.             { 
    63.                 memTotal = tempStr.mid(pos+10, tempStr.length()-13); 
    64.                 memTotal = memTotal.trimmed(); 
    65.                 nMemTotal = memTotal.toInt()/1024; 
    66.             } 
    67.             else if (pos = tempStr.indexOf("MemFree"), pos != -1) 
    68.             { 
    69.                 memFree = tempStr.mid(pos+9, tempStr.length()-12); 
    70.                 memFree = memFree.trimmed(); 
    71.                 nMemFree = memFree.toInt()/1024; 
    72.             } 
    73.             else if (pos = tempStr.indexOf("SwapTotal"), pos != -1) 
    74.             { 
    75.                 swapTotal = tempStr.mid(pos+11, tempStr.length()-14); 
    76.                 swapTotal = swapTotal.trimmed(); 
    77.                 nSwapTotal = swapTotal.toInt()/1024; 
    78.             } 
    79.             else if (pos = tempStr.indexOf("SwapFree"), pos != -1) 
    80.             { 
    81.                 swapFree = tempStr.mid(pos+10,tempStr.length()-13); 
    82.                 swapFree = swapFree.trimmed(); 
    83.                 nSwapFree = swapFree.toInt()/1024; 
    84.                 break; 
    85.             } 
    86.         } 
    87.  
    88.         nMemUsed = nMemTotal - nMemFree; 
    89.         nSwapUsed = nSwapTotal - nSwapFree; 
    90.  
    91.         memUsed = QString::number(nMemUsed, 10); 
    92.         swapUsed = QString::number(nSwapUsed, 10); 
    93.         memFree = QString::number(nMemFree, 10); 
    94.         memTotal = QString::number(nMemTotal, 10); 
    95.         swapFree = QString::number(nSwapFree, 10); 
    96.         swapTotal = QString::number(nSwapTotal, 10); 
    97.  
    98.         ui->label_RAM_Used->setText(memUsed+" MB"); 
    99.         ui->label_RAM_Left->setText(memFree+" MB"); 
    100.         ui->label_RAM_Total->setText(memTotal+" MB"); 
    101.         ui->label_SWAP_Used->setText(swapUsed+" MB"); 
    102.         ui->label_SWAP_Left->setText(swapFree+" MB"); 
    103.         ui->label_SWAP_Total->setText(swapTotal+" MB"); 
    104.  
    105.         ui->progressBar_RAM->setValue(nMemUsed*100/nMemTotal); 
    106.         ui->progressBar_SWAP->setValue(nSwapUsed*100/nSwapTotal); 
    107.  
    108.         tempFile.close(); //关闭内存信息文件 
    109.  
    110.   //wsj这段计算cpu使用率的方法有问题,使用另一篇中的方法:https://www.cnblogs.com/liushui-sky/p/9258101.html
    111.         int tt = 2; //取2个点采样计算cpu当前利用律 
    112.         int cpuInfo[2][7]; 
    113.         int cpuTotal[2][2]; 
    114.         while (tt) 
    115.         { 
    116.             tempFile.setFileName("/proc/stat"); //打开CPU使用状态信息 
    117.             if ( !tempFile.open(QIODevice::ReadOnly) ) 
    118.             { 
    119.                 QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes); 
    120.                 return; 
    121.             } 
    122.             tempStr = tempFile.readLine(); 
    123.             for (int i = 0; i < 7; i++) 
    124.             { 
    125.                 cpuInfo[2-tt][i] = tempStr.section(" ", i+1, i+1).toInt(); 
    126.                 cpuTotal[1][2-tt] += cpuInfo[2-tt][i]; 
    127.                 if (i == 3) 
    128.                 { 
    129.                     cpuTotal[0][2-tt] += cpuInfo[2-tt][i]; 
    130.                 } 
    131.             } 
    132.             tt--; 
    133.             tempFile.close(); //关闭stat文件 
    134.         } 
    135.  
    136.         int a = cpuTotal[0][1] - cpuTotal[0][0]; 
    137.         int b = cpuTotal[1][1] - cpuTotal[1][0]; 
    138.         if (a < 0) 
    139.         { 
    140.             a = -a; 
    141.         } 
    142.         if (b < 0) 
    143.         { 
    144.             b = -b; 
    145.         } 
    146.         ui->progressBar_CPU->setValue(a*100/b); 
    147.  
    148.         tempFile.setFileName("/proc/stat"); 
    149.         if ( !tempFile.open(QIODevice::ReadOnly) ) 
    150.         { 
    151.             QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes); 
    152.             return; 
    153.         } 
    154.  
    155.         tempStr = tempFile.readLine(); 
    156.         a0 = a1; 
    157.         b0 = b1; 
    158.         a1 = b1 = 0; 
    159.         int gg; 
    160.         for (int i = 0; i < 7; i++) 
    161.         { 
    162.             b1 += tempStr.section(" ", i+2, i+2).toInt(); 
    163.             gg = b1; 
    164.             if (i == 3) 
    165.             { 
    166.                 a1 += tempStr.section(" ", i+2, i+2).toInt(); 
    167.             } 
    168.         } 
    169.         int m, n; 
    170.         m = a1 - a0; 
    171.         n = b1 - b0; 
    172.         if (m < 0) 
    173.         { 
    174.             m = -m; 
    175.         } 
    176.         if (n < 0) 
    177.         { 
    178.             n = -n; 
    179.         } 
    180.         ui->progressBar_CPU->setValue( (n-m)*100/n ); 
    181.         tempFile.close(); //关闭stat文件 
    182.     } 
    183.  
    184.     else if (index == 1) //进程信息 
    185.     { 
    186.         ui->listWidget_process->clear(); 
    187.         QDir qd("/proc"); 
    188.         QStringList qsList = qd.entryList(); 
    189.         QString qs = qsList.join(" "); 
    190.         QString id_of_pro; 
    191.         bool ok; 
    192.         int find_start = 3; 
    193.         int a, b; 
    194.         int nProPid; //进程PID 
    195.         int number_of_sleep = 0, number_of_run = 0, number_of_zombie = 0; 
    196.         int totalProNum = 0; //进程总数 
    197.         QString proName; //进程名 
    198.         QString proState; //进程状态 
    199.         QString proPri; //进程优先级 
    200.         QString proMem; //进程占用内存 
    201.         QListWidgetItem *title = new QListWidgetItem("PID " + QString::fromUtf8("名称") + " " + 
    202.                                                      QString::fromUtf8("状态") + " " + 
    203.                                                      QString::fromUtf8("优先级") + " " + 
    204.                                                      QString::fromUtf8("占用内存"), ui->listWidget_process); 
    205.         //循环读取进程 
    206.         while (1) 
    207.         { 
    208.             //获取进程PID 
    209.             a = qs.indexOf(" ", find_start); 
    210.             b = qs.indexOf(" ", a+1); 
    211.             find_start = b; 
    212.             id_of_pro = qs.mid(a+1, b-a-1); 
    213.             totalProNum++; 
    214.             nProPid = id_of_pro.toInt(&ok, 10); 
    215.             if(!ok) 
    216.             { 
    217.                 break; 
    218.             } 
    219.  
    220.             //打开PID所对应的进程状态文件 
    221.             tempFile.setFileName("/proc/" + id_of_pro + "/stat"); 
    222.             if ( !tempFile.open(QIODevice::ReadOnly) ) 
    223.             { 
    224.                 QMessageBox::warning(this, tr("warning"), tr("The pid stat file can not open!"), QMessageBox::Yes); 
    225.                 return; 
    226.             } 
    227.             tempStr = tempFile.readLine(); 
    228.             if (tempStr.length() == 0) 
    229.             { 
    230.                 break; 
    231.             } 
    232.             a = tempStr.indexOf("("); 
    233.             b = tempStr.indexOf(")"); 
    234.             proName = tempStr.mid(a+1, b-a-1); 
    235.             proName.trimmed(); //删除两端的空格 
    236.             proState = tempStr.section(" ", 2, 2); 
    237.             proPri = tempStr.section(" ", 17, 17); 
    238.             proMem = tempStr.section(" ", 22, 22); 
    239.  
    240.             switch ( proState.at(0).toLatin1() ) 
    241.             { 
    242.                 case 'S':   number_of_sleep++; break; //Sleep 
    243.                 case 'R':   number_of_run++; break; //Running 
    244.                 case 'Z':   number_of_zombie++; break; //Zombie 
    245.                 default :   break; 
    246.             } 
    247.  
    248.             if (proName.length() >= 12) 
    249.             { 
    250.                 QListWidgetItem *item = new QListWidgetItem(id_of_pro + " " + 
    251.                                                             proName + " " + 
    252.                                                             proState + " " + 
    253.                                                             proPri + " " + 
    254.                                                             proMem, ui->listWidget_process); 
    255.             } 
    256.             else 
    257.             { 
    258.                 QListWidgetItem *item = new QListWidgetItem(id_of_pro + " " + 
    259.                                                             proName + " " + 
    260.                                                             proState + " " + 
    261.                                                             proPri + " " + 
    262.                                                             proMem, ui->listWidget_process); 
    263.             } 
    264.         } 
    265.         QString temp; 
    266.         temp = QString::number(totalProNum, 10); 
    267.         ui->label_pNum->setText(temp); 
    268.         temp = QString::number(number_of_run, 10); 
    269.         ui->label_pRun->setText(temp); 
    270.         temp = QString::number(number_of_sleep, 10); 
    271.         ui->label_pSleep->setText(temp); 
    272.         temp = QString::number(number_of_zombie, 10); 
    273.         ui->label_pZombie->setText(temp); 
    274.  
    275.         tempFile.close(); //关闭该PID进程的状态文件 
    276.     } 
    277.  
    278.     else if (index == 2) //模块信息 
    279.     { 
    280.         ui->listWidget_model->clear(); 
    281.         tempFile.setFileName("/proc/modules"); //打开模块信息文件 
    282.         if ( !tempFile.open(QIODevice::ReadOnly) ) 
    283.         { 
    284.             QMessageBox::warning(this, tr("warning"), tr("The modules file can not open!"), QMessageBox::Yes); 
    285.             return ; 
    286.         } 
    287.         //设置模块首行项目 
    288.         QListWidgetItem *title = new QListWidgetItem( QString::fromUtf8("名称") + " " + 
    289.                                                       QString::fromUtf8("使用内存数") + " " + 
    290.                                                       QString::fromUtf8("使用次數"), ui->listWidget_model); 
    291.  
    292.         QString mod_Name, mod_Mem, mod_Num; 
    293.         //循环读取文件内容,查找需要的信息 
    294.         while (1) 
    295.         { 
    296.             tempStr = tempFile.readLine(); 
    297.             if (tempStr.length() == 0) 
    298.             { 
    299.                 break; 
    300.             } 
    301.             mod_Name = tempStr.section(" ", 0, 0); 
    302.             mod_Mem = tempStr.section(" ", 1, 1); 
    303.             mod_Num = tempStr.section(" ", 2, 2); 
    304.             if (mod_Name.length() > 10) 
    305.             { 
    306.                 QListWidgetItem *item = new QListWidgetItem(mod_Name + " " + 
    307.                                                             mod_Mem + " " + 
    308.                                                             mod_Num, ui->listWidget_model); 
    309.             } 
    310.             else 
    311.             { 
    312.                 QListWidgetItem *item = new QListWidgetItem(mod_Name + " " + 
    313.                                                             mod_Mem + " " + 
    314.                                                             mod_Num, ui->listWidget_model); 
    315.             } 
    316.         } 
    317.         tempFile.close(); //关闭模块信息文件 
    318.     } 
    319.  
    320.     else if (index == 3) //系统信息 
    321.     { 
    322.         //int ok; 
    323.         tempFile.setFileName("/proc/cpuinfo"); //打开CPU信息文件 
    324.         if ( !tempFile.open(QIODevice::ReadOnly) ) 
    325.         { 
    326.             QMessageBox::warning(this, tr("warning"), tr("The cpuinfo file can not open!"), QMessageBox::Yes); 
    327.             return; 
    328.         } 
    329.  
    330.         //循环读取文件内容,查找需要的信息 
    331.         while (1) 
    332.         { 
    333.             tempStr = tempFile.readLine(); 
    334.             pos = tempStr.indexOf("model name"); 
    335.             if (pos != -1) 
    336.             { 
    337.                 pos += 13; //跳过前面的"model name:"所占用的字符 
    338.                 QString *cpu_name = new QString( tempStr.mid(pos, tempStr.length()-13) ); 
    339.                 ui->label_CPUName->setText(*cpu_name); 
    340.             } 
    341.             else if (pos = tempStr.indexOf("vendor_id"), pos != -1) 
    342.             { 
    343.                 pos += 12; //跳过前面的"vendor_id:"所占用的字符 
    344.                 QString *cpu_type = new QString( tempStr.mid(pos, tempStr.length()-12) ); 
    345.                 ui->label_CPUType->setText(*cpu_type); 
    346.             } 
    347.             else if (pos = tempStr.indexOf("cpu MHz"), pos != -1) 
    348.             { 
    349.                 pos += 11; //跳过前面的"cpu MHz:"所占用的字符 
    350.                 QString *cpu_frq = new QString( tempStr.mid(pos, tempStr.length()-11) ); 
    351.                 double cpufrq = cpu_frq->toDouble(); //4核CPU 
    352.                 cpu_frq->setNum(cpufrq*4); 
    353.                 ui->label_CPUFrequency->setText(*cpu_frq + " HZ"); 
    354.             } 
    355.             else if (pos = tempStr.indexOf("cache size"), pos!=-1) 
    356.             { 
    357.                 pos += 13; //跳过前面的"cache size:"所占用的字符 
    358.                 QString *cache_size = new QString( tempStr.mid(pos, tempStr.length()-16) ); 
    359.                 int cachesize = cache_size->toInt(); //4核CPU 
    360.                 cache_size->setNum(cachesize*4); 
    361.                 ui->label_CatheCapacity->setText(*cache_size + " KB"); 
    362.             } 
    363.             else //跳过其他的内容 
    364.             { 
    365.             } 
    366.         } 
    367.         tempFile.close(); //关闭CPU信息文件 
    368.  
    369.         //打开操作系统信息文件 
    370.         tempFile.setFileName("/proc/version"); 
    371.         if ( !tempFile.open(QIODevice::ReadOnly) ) 
    372.         { 
    373.             QMessageBox::warning(this, tr("warning"), tr("The version file can not open!"), QMessageBox::Yes); 
    374.             return ; 
    375.         } 
    376.         tempStr = tempFile.readLine(); 
    377.         pos = tempStr.indexOf("version"); 
    378.         QString *os_version = new QString( tempStr.mid(0, pos-1) ); 
    379.         ui->label_SystemType->setText(*os_version); 
    380.  
    381.         int pos1 = tempStr.indexOf("("); 
    382.         QString *os_type = new QString( tempStr.mid(pos, pos1-pos-1) ); 
    383.         ui->label_SystemVersion->setText(*os_type); 
    384.  
    385.         pos = tempStr.indexOf("gcc version"); 
    386.         pos1 = tempStr.indexOf("#"); 
    387.         QString *gcc_info = new QString( tempStr.mid(pos+12, pos1-pos-14) ); 
    388.         ui->label_GCCVersion->setText(*gcc_info); 
    389.  
    390.         tempFile.close(); //关闭操作系统信息文件 
    391.     } 
    392.  
    393.     else //说明 
    394.     { 
    395.     } 
    396.     return; 
    397.  
    398. void MainWindow::on_pushButton_halt_clicked() 
    399.     system("halt"); 
    400.  
    401. void MainWindow::on_pushButton_reboot_clicked() 
    402.     system("reboot"); 
    403.  
    404.  
    405. void MainWindow::on_tabWidget_INFO_currentChanged(int index) 
    406.     show_tabWidgetInfo(index); //显示tab中的内容 
    407.     return ; 
    408.  
    409. void MainWindow::on_pushButton_pkill_clicked() 
    410.     //获得进程号 
    411.     QListWidgetItem *item = ui->listWidget_process->currentItem(); 
    412.     QString pro = item->text(); 
    413.     pro = pro.section(" ", 0, 0); 
    414.     system("kill " + pro.toLatin1()); 
    415.     QMessageBox::warning(this, tr("kill"), QString::fromUtf8("该进程已被杀死!"), QMessageBox::Yes); 
    416.     //回到进程信息tab表 
    417.     show_tabWidgetInfo(1); 
    418.  
    419. void MainWindow::on_pushButton_prefresh_clicked() 
    420.     show_tabWidgetInfo(1); 
    421.  
    422. void MainWindow::on_pushButton_Model_install_clicked() 
    423.     show_tabWidgetInfo(2); //安装模块还不知道如何实现 
    424.  
    425. void MainWindow::on_pushButton_Model_remove_clicked() 
    426.     show_tabWidgetInfo(2); //卸载模块还不知道如何实现 
    427.  
    428. void MainWindow::on_pushButton_Model_refresh_clicked() 
    429.     show_tabWidgetInfo(2); 

    转自http://blog.51cto.com/rangercyh/521262

  • 相关阅读:
    QT设置窗口屏幕居中
    屏蔽ubuntu桌面鼠标右键以及Ctrl Alt F*
    ubuntu12.04 U盘自动挂载配置
    最受欢迎的15个Python开源框架
    异步非阻塞IO的Python Web框架--Tornado
    RabbitMQ RPC问题
    petapoco模板修改
    事件&表达式
    .net core2 单元测试
    检查邮箱IP是否在国际反垃圾邮件组织的黑名单中
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/9241158.html
Copyright © 2020-2023  润新知