繼續上次的操作系統課設,這次需要設計一個簡單的任務管理器,大部分人選擇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
mainwindow.h
mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QFile>
- #include <QMessageBox>
- #include <QDir>
- #include <QListWidget>
- #include <QListWidgetItem>
- #include <QStringList>
- #include <QTimer>
- int a0 = 0, a1 = 0, b0 = 0, b1 = 0;
- MainWindow::MainWindow(QWidget *parent) : //構造函數,初始化ui,計時器
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- timer = new QTimer(this);
- QWidget::connect( timer, SIGNAL( timeout() ), this, SLOT( timer_update_currentTabInfo() ) );
- QWidget::connect( ui->tabWidget_INFO, SIGNAL( currentChanged() ),
- this, SLOT( on_tabWidget_currentChanged() ) );
- timer->start(1000);
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- delete timer;
- }
- void MainWindow::timer_update_currentTabInfo()
- {
- int index = ui->tabWidget_INFO->currentIndex();
- //定時器只刷新內存tab頁面,用於進度條動態顯示
- if (index == 0)
- {
- show_tabWidgetInfo(index);
- }
- }
- void MainWindow::show_tabWidgetInfo(int index)
- {
- QString tempStr; //讀取文件信息字元串
- QFile tempFile; //用於打開系統文件
- int pos; //讀取文件的位置
- if (index == 0) //內存資源
- {
- tempFile.setFileName("/proc/meminfo"); //打開內存信息文件
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The meminfo file can not open!"), QMessageBox::Yes);
- return ;
- }
- QString memTotal;
- QString memFree;
- QString memUsed;
- QString swapTotal;
- QString swapFree;
- QString swapUsed;
- int nMemTotal, nMemFree, nMemUsed, nSwapTotal, nSwapFree, nSwapUsed;
- while (1)
- {
- tempStr = tempFile.readLine();
- pos = tempStr.indexOf("MemTotal");
- if (pos != -1)
- {
- memTotal = tempStr.mid(pos 10, tempStr.length()-13);
- memTotal = memTotal.trimmed();
- nMemTotal = memTotal.toInt()/1024;
- }
- else if (pos = tempStr.indexOf("MemFree" ), pos != -1)
- {
- memFree = tempStr.mid(pos 9, tempStr.length()-12);
- memFree = memFree.trimmed();
- nMemFree = memFree.toInt()/1024;
- }
- else if (pos = tempStr.indexOf("SwapTotal"), pos != -1)
- {
- swapTotal = tempStr.mid(pos 11, tempStr.length()-14);
- swapTotal = swapTotal.trimmed();
- nSwapTotal = swapTotal.toInt()/1024;
- }
- else if (pos = tempStr.indexOf("SwapFree"), pos != -1)
- {
- swapFree = tempStr.mid(pos 10,tempStr.length()-13);
- swapFree = swapFree.trimmed();
- nSwapFree = swapFree.toInt()/1024;
- break;
- }
- }
- nMemUsed = nMemTotal - nMemFree;
- nSwapUsed = nSwapTotal - nSwapFree;
- memUsed = QString::number(nMemUsed, 10);
- swapUsed = QString::number(nSwapUsed, 10);
- memFree = QString::number(nMemFree, 10);
- memTotal = QString::number(nMemTotal, 10);
- swapFree = QString::number(nSwapFree, 10);
- swapTotal = QString::number(nSwapTotal, 10);
- ui->label_RAM_Used->setText(memUsed " MB");
- ui->label_RAM_Left->setText(memFree " MB");
- ui->label_RAM_Total->setText(memTotal " MB");
- ui->label_SWAP_Used->setText(swapUsed " MB");
- ui->label_SWAP_Left->setText(swapFree " MB");
- ui->label_SWAP_Total->setText(swapTotal " MB");
- ui->progressBar_RAM->setValue(nMemUsed*100/nMemTotal);
- ui->progressBar_SWAP->setValue(nSwapUsed*100/nSwapTotal);
- tempFile.close(); //關閉內存信息文件
- int tt = 2; //取2個點採樣計算cpu當前利用律
- int cpuInfo[2][7];
- int cpuTotal[2][2];
- while (tt)
- {
- tempFile.setFileName("/proc/stat"); //打開CPU使用狀態信息
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes);
- return;
- }
- tempStr = tempFile.readLine();
- for (int i = 0; i < 7; i )
- {
- cpuInfo[2-tt][i] = tempStr.section(" ", i 1, i 1).toInt();
- cpuTotal[1][2-tt] = cpuInfo[2-tt][i];
- if (i == 3)
- {
- cpuTotal[0][2-tt] = cpuInfo[2-tt][i];
- }
- }
- tt--;
- tempFile.close(); //關閉stat文件
- }
- int a = cpuTotal[0][1] - cpuTotal[0][0];
- int b = cpuTotal[1][1] - cpuTotal[1][0];
- if (a < 0)
- {
- a = -a;
- }
- if (b < 0)
- {
- b = -b;
- }
- ui->progressBar_CPU->setValue(a*100/b);
- tempFile.setFileName("/proc/stat");
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The stat file can not open!"), QMessageBox::Yes);
- return;
- }
- tempStr = tempFile.readLine();
- a0 = a1;
- b0 = b1;
- a1 = b1 = 0;
- int gg;
- for (int i = 0; i < 7; i )
- {
- b1 = tempStr.section(" ", i 2, i 2).toInt();
- gg = b1;
- if (i == 3)
- {
- a1 = tempStr.section(" ", i 2, i 2).toInt();
- }
- }
- int m, n;
- m = a1 - a0;
- n = b1 - b0;
- if (m < 0)
- {
- m = -m;
- }
- if (n < 0)
- {
- n = -n;
- }
- ui->progressBar_CPU->setValue( (n-m)*100/n );
- tempFile.close(); //關閉stat文件
- }
- else if (index == 1) //進程信息
- {
- ui->listWidget_process->clear();
- QDir qd("/proc");
- QStringList qsList = qd.entryList();
- QString qs = qsList.join("n");
- QString id_of_pro;
- bool ok;
- int find_start = 3;
- int a, b;
- int nProPid; //進程PID
- int number_of_sleep = 0, number_of_run = 0, number_of_zombie = 0;
- int totalProNum = 0; //進程總數
- QString proName; //進程名
- QString proState; //進程狀態
- QString proPri; //進程優先順序
- QString proMem; //進程佔用內存
- QListWidgetItem *title = new QListWidgetItem("PIDt" QString::fromUtf8("名稱") "tt"
- QString::fromUtf8("狀態") "t"
- QString::fromUtf8( "優先順序") "t"
- QString::fromUtf8("佔用內存"), ui->listWidget_process);
- //循環讀取進程
- while (1)
- {
- //獲取進程PID
- a = qs.indexOf("n", find_start);
- b = qs.indexOf("n", a 1);
- find_start = b;
- id_of_pro = qs.mid(a 1, b-a-1);
- totalProNum ;
- nProPid = id_of_pro.toInt(&ok, 10);
- if(!ok)
- {
- break;
- }
- //打開PID所對應的進程狀態文件
- tempFile.setFileName("/proc/" id_of_pro "/stat");
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning( this, tr("warning"), tr("The pid stat file can not open!"), QMessageBox::Yes);
- return;
- }
- tempStr = tempFile.readLine();
- if (tempStr.length() == 0)
- {
- break;
- }
- a = tempStr.indexOf("(");
- b = tempStr.indexOf(")");
- proName = tempStr.mid(a 1, b-a-1);
- proName.trimmed(); //刪除兩端的空格
- proState = tempStr.section(" ", 2, 2);
- proPri = tempStr.section(" ", 17, 17);
- proMem = tempStr.section(" ", 22, 22);
- switch ( proState.at(0).toLatin1() )
- {
- case 'S': number_of_sleep ; break; //Sleep
- case 'R': number_of_run ; break; //Running
- case 'Z': number_of_zombie ; break; //Zombie
- default : break;
- }
- if (proName.length() >= 12)
- {
- QListWidgetItem *item = new QListWidgetItem(id_of_pro "t"
- proName "t"
- proState "t"
- proPri "t"
- proMem, ui->listWidget_process);
- }
- else
- {
- QListWidgetItem *item = new QListWidgetItem(id_of_pro "t"
- proName "tt"
- proState "t"
- proPri "t"
- proMem, ui->listWidget_process);
- }
- }
- QString temp;
- temp = QString::number(totalProNum, 10);
- ui->label_pNum->setText(temp);
- temp = QString::number(number_of_run, 10);
- ui->label_pRun->setText(temp);
- temp = QString::number(number_of_sleep, 10);
- ui->label_pSleep->setText(temp);
- temp = QString::number(number_of_zombie, 10);
- ui->label_pZombie->setText(temp);
- tempFile.close(); //關閉該PID進程的狀態文件
- }
- else if (index == 2) //模塊信息
- {
- ui->listWidget_model->clear();
- tempFile.setFileName("/proc/modules"); //打開模塊信息文件
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The modules file can not open!"), QMessageBox::Yes);
- return ;
- }
- //設置模塊首行項目
- QListWidgetItem *title = new QListWidgetItem( QString::fromUtf8("名稱") "ttt"
- QString::fromUtf8("使用內存數") "tt"
- QString::fromUtf8("使用次數"), ui->listWidget_model);
- QString mod_Name, mod_Mem, mod_Num;
- //循環讀取文件內容,查找需要的信息
- while (1)
- {
- tempStr = tempFile.readLine();
- if (tempStr.length() == 0)
- {
- break;
- }
- mod_Name = tempStr.section(" ", 0, 0);
- mod_Mem = tempStr.section(" ", 1, 1);
- mod_Num = tempStr.section(" ", 2, 2);
- if (mod_Name.length() > 10)
- {
- QListWidgetItem *item = new QListWidgetItem(mod_Name "tt"
- mod_Mem "tt"
- mod_Num, ui->listWidget_model);
- }
- else
- {
- QListWidgetItem *item = new QListWidgetItem(mod_Name "ttt"
- mod_Mem "tt"
- mod_Num, ui->listWidget_model);
- }
- }
- tempFile.close(); //關閉模塊信息文件
- }
- else if (index == 3) //系統信息
- {
- //int ok;
- tempFile.setFileName("/proc/cpuinfo"); //打開CPU信息文件
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The cpuinfo file can not open!"), QMessageBox::Yes);
- return;
- }
- //循環讀取文件內容,查找需要的信息
- while (1)
- {
- tempStr = tempFile.readLine();
- pos = tempStr.indexOf("model name");
- if (pos != -1)
- {
- pos = 13; //跳過前面的"model name:"所佔用的字元
- QString *cpu_name = new QString( tempStr.mid(pos, tempStr.length()-13) );
- ui->label_CPUName->setText(*cpu_name);
- }
- else if (pos = tempStr.indexOf("vendor_id"), pos != -1)
- {
- pos = 12; //跳過前面的"vendor_id:"所佔用的字元
- QString *cpu_type = new QString( tempStr.mid(pos, tempStr.length()-12) );
- ui->label_CPUType->setText(*cpu_type);
- }
- else if (pos = tempStr.indexOf("cpu MHz"), pos != -1)
- {
- pos = 11; //跳過前面的"cpu MHz:"所佔用的字元
- QString *cpu_frq = new QString( tempStr.mid(pos, tempStr.length()-11) );
- double cpufrq = cpu_frq->toDouble(); //4核CPU
- cpu_frq->setNum(cpufrq*4);
- ui->label_CPUFrequency->setText(*cpu_frq " HZ");
- }
- else if (pos = tempStr.indexOf("cache size"), pos!=-1)
- {
- pos = 13; //跳過前面的"cache size:"所佔用的字元
- QString *cache_size = new QString( tempStr.mid(pos, tempStr.length()-16) );
- int cachesize = cache_size->toInt(); //4核CPU
- cache_size->setNum(cachesize*4);
- ui->label_CatheCapacity->setText(*cache_size " KB");
- }
- else //跳過其他的內容
- {
- }
- }
- tempFile.close(); //關閉CPU信息文件
- //打開操作系統信息文件
- tempFile.setFileName("/proc/version");
- if ( !tempFile.open(QIODevice::ReadOnly) )
- {
- QMessageBox::warning(this, tr("warning"), tr("The version file can not open!"), QMessageBox::Yes);
- return ;
- }
- tempStr = tempFile.readLine();
- pos = tempStr.indexOf("version");
- QString *os_version = new QString( tempStr.mid(0, pos-1) );
- ui->label_SystemType->setText(*os_version);
- int pos1 = tempStr.indexOf("(");
- QString *os_type = new QString( tempStr.mid(pos, pos1-pos-1) );
- ui->label_SystemVersion->setText(*os_type);
- pos = tempStr.indexOf("gcc version");
- pos1 = tempStr.indexOf("#");
- QString *gcc_info = new QString( tempStr.mid(pos 12, pos1-pos-14) );
- ui->label_GCCVersion->setText(*gcc_info);
- tempFile.close(); //關閉操作系統信息文件
- }
- else //說明
- {
- }
- return;
- }
- void MainWindow::on_pushButton_halt_clicked()
- {
- system("halt");
- }
- void MainWindow::on_pushButton_reboot_clicked()
- {
- system("reboot");
- }
- void MainWindow::on_tabWidget_INFO_currentChanged(int index)
- {
- show_tabWidgetInfo(index); //顯示tab中的內容
- return ;
- }
- void MainWindow::on_pushButton_pkill_clicked()
- {
- //獲得進程號
- QListWidgetItem *item = ui->listWidget_process->currentItem();
- QString pro = item->text();
- pro = pro.section("t", 0, 0);
- system("kill " pro.toLatin1());
- QMessageBox::warning(this, tr("kill"), QString::fromUtf8("該進程已被殺死!"), QMessageBox::Yes);
- //回到進程信息tab表
- show_tabWidgetInfo(1);
- }
- void MainWindow::on_pushButton_prefresh_clicked()
- {
- show_tabWidgetInfo(1);
- }
- void MainWindow::on_pushButton_Model_install_clicked()
- {
- show_tabWidgetInfo(2); //安裝模塊還不知道如何實現
- }
- void MainWindow::on_pushButton_Model_remove_clicked()
- {
- show_tabWidgetInfo(2); //卸載模塊還不知道如何實現
- }
- void MainWindow::on_pushButton_Model_refresh_clicked()
- {
- show_tabWidgetInfo(2);
- }
本文出自 「rangercyh的分享空間」 博客,請務必保留此出處http://rangercyh.blog.51cto.com/1444712/521262
[火星人 ] linux系統Qt實現簡單的任務管理器已經有868次圍觀