您的位置:首页 > 编程语言 > Qt开发

QT图形界面实现系统监控状态(未完成)

2009-06-01 15:44 573 查看
linux操作系统 QT4版本

转:http://wcrane.bokee.com/viewdiary.15932441.html

非常感谢这位仁兄,应为我们用到你的一部分。



/*主程序main.cpp*/
#include <QApplication>

#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MainWindow mainWindow; //创建主窗口类实例
mainWindow.resize(200, 100); //设置主窗口位置
mainWindow.show(); //显示主窗口

return app.exec();
}

/*主窗口程序mainwindow.cpp*/
#include "mainwindow.h"
/*主窗口类的实现*/
MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) //构造函数
: QMainWindow(parent, flags)
{
setFixedSize(350, 450); //固定窗口大小

//添加菜单选项并给每个菜单利用信号机制添加处理函数
QMenu *menuFile = menuBar()->addMenu("&File"); //添加菜单
QAction *action = menuFile->addAction("&Open"); //创建进程
connect(action, SIGNAL(triggered()), this, SLOT(createProcess()));
action = menuFile->addAction("&Exit"); //退出程序
connect(action, SIGNAL(triggered()), this, SLOT(close()));

QMenu *menuEdit = menuBar()->addMenu("Edit");
menuEdit->addAction("&Stop process"); //停止进程
connect(action, SIGNAL(triggered()), this, SLOT(stopProcess()));
menuEdit->addAction("&Continue process"); //继续进程
connect(action, SIGNAL(triggered()), this, SLOT(continueProcess()));
menuEdit->addSeparator(); //添加分隔符

menuEdit->addAction("&Kill process"); //杀死进程
connect(action, SIGNAL(triggered()), this, SLOT(killProcess()));
menuEdit->addAction("&Preference"); //
connect(action, SIGNAL(triggered()), this, SLOT(preference()));

QMenu *menuView = menuBar()->addMenu("&View");
menuView->addAction("&Active Process"); //显示活动进程
connect(action, SIGNAL(triggered()), this, SLOT(activeProcess()));
menuView->addAction("&My Process"); //显示当前用户进程
connect(action, SIGNAL(triggered()), this, SLOT(myProcess()));
menuView->addAction("All Process"); //显示所有进程
connect(action, SIGNAL(triggered()), this, SLOT(allProcess()));
menuView->addSeparator();
menuView->addAction("&Dependency");
connect(action, SIGNAL(triggered()), this, SLOT(dependency()));
menuView->addAction("Hide Process"); //隐藏进程进程
connect(action, SIGNAL(triggered()), this, SLOT(hideProcess()));
menuView->addAction("Hided Process"); //显示隐藏进程
connect(action, SIGNAL(triggered()), this, SLOT(hidedProcess()));
menuView->addSeparator();
menuView->addAction("Memory Image"); //
connect(action, SIGNAL(triggered()), this, SLOT(memoryImage()));
menuView->addAction("Opened File"); //打开文件
connect(action, SIGNAL(triggered()), this, SLOT(openedFile()));

QMenu *menuHelp = menuBar()->addMenu("&Help");
menuHelp->addAction("Help"); //帮助
connect(action, SIGNAL(triggered()), this, SLOT(showHelp()));
menuHelp->addAction("About"); //关于
connect(action, SIGNAL(triggered()), this, SLOT(showAboutBox()));

tabWidget = new QTabWidget; //用tab分页显示各种信息
tabWidget->addTab(new ProcessTab, "Process"); //进程信息显示面板
tabWidget->addTab(new ResourceTab, "Resource"); //资源信息显示面板
tabWidget->addTab(new FileSystemTab, "Partition"); //分区信息显示面板

setCentralWidget(tabWidget);
setWindowTitle("Linux Resource Manager");
}
/*进程创建消息槽的实现*/
void MainWindow::createProcess()
{
bool ok;
QString text = QInputDialog::getText(this, tr("Input file name:"),
tr("Open File:"), QLineEdit::Normal, "File Name", &ok);
if(ok)
QProcess::startDetached(text);
else
return;
}
/*由于时间关系,其他消息槽均未实现*/
void MainWindow::stopProcess()
{
}
void MainWindow::continueProcess()
{
}
void MainWindow::killProcess(){}
void MainWindow::endProcess(){}
void MainWindow::changePriority(){}
void MainWindow::preference(){}
void MainWindow::activeProcess(){}
void MainWindow::myProcess(){}
void MainWindow::allProcess(){}
void MainWindow::dependency(){}
void MainWindow::hideProcess(){}
void MainWindow::hidedProcess(){}
void MainWindow::memoryImage(){}
void MainWindow::openedFile(){}
void MainWindow::showAboutBox(){}
void MainWindow::showHelp(){}



/*主窗口头文件mainwindow.h*/
/*主窗口类的定义,包括所有的消息和消息槽的定义以及成员变量的定义*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMenu>
#include <QWidget>
#include <QTableWidget>
#include <QTabWidget>
#include <QListWidget>
#include <QMenuBar>
#include <QVBoxLayout>
#include <QInputDialog>
#include <QProcess>

#include "tab.h"

class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); //构造函数

void newProcess(const QString &fileName);

QString *fileName;



/*消息槽的定义*/
public slots:
void createProcess();
void stopProcess();
void continueProcess();
void killProcess();
void endProcess();
void changePriority();
void preference(); //首选项
void activeProcess();
void myProcess();
void allProcess();
void dependency();
void hideProcess();
void hidedProcess();
void memoryImage();
void openedFile();
void showAboutBox();
void showHelp();



private:
QTabWidget *tabWidget;
QTableWidget *tableWidget;
QListWidget *listWidget;
};

#endif



/*表格tab.cpp*/
#include "tab.h"

double cpu; //全局变量,用来保存上一次cpu使用时间
/*进程信息表格的实现*/
ProcessTab::ProcessTab(QWidget *parent)
: QWidget(parent)
{
QStringList tableHeaders; //用list分别显示各条进程信息
tableHeaders << "Name" << "PID" << "User" << "Status" << "VM" << "Resident MM" << "CPU%" << "nice" << "Memory"; //各项进程信息
tableProcess = new QTableWidget(0, 9, this);

//设置表格标题栏
tableProcess->setHorizontalHeaderLabels(tableHeaders);

QPushButton *pushButton = new QPushButton("Kill Process");
QLabel *titleLabel = new QLabel("<h3><font color=green>Current System CPU Usage: </font></h3>");

for(int i = 0; i < 3; i++)
cpuDataStart[i] = 0;


cpuUsageLabel = new QLabel;
/*每秒钟定时更新cpu使用率*/
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateCpu()));
timer->start(1000);
updateCpu();
/*没10秒更新进程信息*/
QTimer *timer2 = new QTimer(this);
connect(timer2, SIGNAL(timeout()), this, SLOT(updateProcess()));
timer2->start(10000);
updateProcess();

QVBoxLayout *processLayout = new QVBoxLayout;
processLayout->addWidget(titleLabel); //主面板上添加组件
processLayout->addWidget(cpuUsageLabel);
processLayout->addWidget(tableProcess);
processLayout->addWidget(pushButton);
setLayout(processLayout);
}

/*cpu使用率更新函数,第一次取前3项之和除以4项之和,以后每次用前一次的各项分别相减然后再用结果的前3项的和除以4项之和,结果以百分数和进度条动态显示*/
void ProcessTab::updateCpu()
{
QFile file("/proc/stat"); //从/proc/stat读取cpu信息
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QString line = file.readLine();

QStringList list;
int current[4], used = 0, total = 0;
bool ok;

list = line.split(" ");

for(int i = 2; i < 6; i++)
{
cpuDataEnd[i-2] = list[i].toInt(&ok, 10);
current[i-2] = cpuDataEnd[i-2] - cpuDataStart[i-2];
cpuDataStart[i-2] = cpuDataEnd[i-2];
total += current[i-2]; //4项总和
}
used = total - current[3]; //计算前3项之和
cpu = 100.0 * used / total; //计算cpu使用率
cpuUsageLabel->setText(QString::number(cpu, 'f', 2).append("%")); //显示小数点后2位
}
/*更新进程的函数,每隔10秒从/proc下的各个进程的stat文件读取进程信息,并用表格形式动态显示*/
void ProcessTab::updateProcess()
{
bool ok;
DIR *dir;
FILE *fd;
struct dirent *dirName; //目录结构
char stat[2], nice[3]; //分别保存进程当前状态和nice数
char vmsize[20], rmsize[20]; //进程所用虚拟内存大小以及所占实际物理内存大小
char processName[50]; //进程名
char fileName[50];

tableProcess->setRowCount(0); //每次更新进程信息时,先将表格清零
if((dir = opendir("/proc")) == NULL) //从/proc目录读取进程号
return;
while((dirName = readdir(dir)) != NULL)
{
if(atoi(dirName->d_name)) //根据进程号为非零整数,判断文件夹名是否为进程号
{
tableProcess->insertRow(0); //将进程信息添加到表格
sprintf(processName, "/proc/%s/stat", dirName->d_name); //

if((fd = fopen(processName, "r")) == NULL)
{
printf("open error/n");
return;
}


//从进程的stat文件读取进程名,状态,nice值,以及内存的使用情况 fscanf(fd,"%*s%s%s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%s%*s%*s %*s%s%s", fileName, stat, nice, vmsize, rmsize);
fclose(fd);
tableProcess->setItem(0, 0, new QTableWidgetItem(fileName));
tableProcess->setItem(0, 1, new QTableWidgetItem(dirName->d_name));
switch(stat[0]) //根据进程的状态,将其转换为更友好的形式显示
{
case 'S' :
tableProcess->setItem(0, 3, new QTableWidgetItem(tr("Sleep")));
break;
case 'R' :
tableProcess->setItem(0, 3, new QTableWidgetItem("Running"));
break;
case 'Z' :
tableProcess->setItem(0, 3, new QTableWidgetItem("Zombie"));
break;
case 'D' :
tableProcess->setItem(0, 3, new QTableWidgetItem(tr("Disk Sleep")));
break;
case 'T' :
tableProcess->setItem(0, 3, new QTableWidgetItem("Stop"));
break;
case 'X' :
tableProcess->setItem(0, 3, new QTableWidgetItem("Dead"));
break;
default:
break;
}
tableProcess->setItem(0, 7, new QTableWidgetItem(nice));
tableProcess->setItem(0, 4, new QTableWidgetItem(QString("%1M").arg((atof(vmsize) / (1024 * 1024)))));
tableProcess->setItem(0, 5, new QTableWidgetItem(QString("%1M").arg((atof(rmsize) *4 / 1024))));
}
}
}
/*资源面板的实现*/
ResourceTab::ResourceTab(QWidget *parent )
: QWidget(parent)
{
QLabel *cpuLabel = new QLabel("<h3><font color=green>CPU:</font></h3>");
cpuBar = new QProgressBar; //用进度条动态显示cpu使用率
QLabel *memLabel = new QLabel;
memoryLabel = new QLabel; //内存使用率
memoryBar = new QProgressBar; //内存使用率进度条表示
swapLabel = new QLabel; //交换分区使用率
swapBar = new QProgressBar; //交换分区使用率进度条表示
netReceiveLabel = new QLabel; //当前接受到的网络信息量
netTransmitLabel = new QLabel; //已发送的网络流量

memoryBar->setRange(0, 100);
memoryBar->setTextVisible(true);
swapBar->setRange(0, 100);
swapBar->setTextVisible(true);
cpuBar->setRange(0, 100);
cpuBar->setTextVisible(true);
//用Timer类实现每隔1秒钟更新数据
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateCpuBar()));
timer->start(1000);
updateCpuBar();

QGridLayout *resourceTabLayout = new QGridLayout;
resourceTabLayout->addWidget(memoryLabel);
resourceTabLayout->addWidget(memoryBar);
resourceTabLayout->addWidget(swapLabel);
resourceTabLayout->addWidget(swapBar);
resourceTabLayout->addWidget(cpuLabel);
resourceTabLayout->addWidget(cpuBar);
resourceTabLayout->addWidget(netReceiveLabel);
resourceTabLayout->addWidget(netTransmitLabel);
setLayout(resourceTabLayout);
}
//更新cpu使用率的进度条,同时更新内存与网络的使用情况
void ResourceTab::updateCpuBar()
{
cpuBar->setValue((int)cpu); //设置进度条的位置
updateMemory();
updateNet();
}
//更新内存与交换分区的使用情况
void ResourceTab::updateMemory()
{
FILE *fd;
QString str = "K";
QString strName = "<h3><font color=green>Total memory: </font></h3>";
QString swapName = "<h3><font color=green>Swap Total: </font></h3>";
char memoryTotal[10]; //物理内存大小
char memoryFree[10]; //空闲内存大小
char memoryBuffered[10]; //内存缓冲区大小
char memoryCached[10]; //
char swapTotal[10]; //交换分区大小
char swapFree[10]; //空闲交换分区大小
char buf[80];

/*读取内存使用情况*/
fd = fopen("/proc/meminfo", "r");
fscanf(fd, "%*s%s%*s", memoryTotal);
fscanf(fd, "%*s%s%*s", memoryFree);
fscanf(fd, "%*s%s%*s", memoryBuffered);
fscanf(fd, "%*s%s%*s", memoryCached);

for(int i =0; i < 8; i++)
fgets(buf, 80, fd);
/*读取交换分区使用情况*/
fscanf(fd, "%*s%s%*s", swapTotal);
fscanf(fd, "%*s%s%*s", swapFree);

memoryBar->setValue(100 * (atoi(memoryTotal) - atoi(memoryFree) - atoi(memoryBuffered) - atoi(memoryCached)) / atoi(memoryTotal));
memoryLabel->setText(strName + memoryTotal + str);
swapBar->setValue(100 * (atoi(swapTotal) - atoi(swapFree))/atoi(swapTotal));
swapLabel->setText(swapName + swapTotal + str);
}
/*更新网络使用情况*/
void ResourceTab::updateNet()
{
QString strReceive = "<h3><font color=green>Total Received: </font></h3>";
QString strTransmit = "<h3><font color=green>Total Transmitted: </font></h3>";
FILE *fd;
char temp[80];
char receive[20], transmit[20];
int receiveSpeed;
char toInt[12];

if((fd = fopen("/proc/net/dev", "r")) == NULL)
return;
for(int i = 0; i < 5; i++)
fgets(temp, 80, fd);
fscanf(fd, "%s%*s%*s%*s%*s%*s%*s%*s%s", receive, transmit);
fclose(fd);
strcpy(toInt, &receive[5]);
netReceiveLabel->setText(strReceive + QString(" %1 M").arg(atof(toInt)/(1024*1024)));
netTransmitLabel->setText(strTransmit + QString(" %1 M").arg(atof(transmit)/(1024*1024)));
}
/*硬盘分区情况表格的实现*/
FileSystemTab::FileSystemTab(QWidget *parent )
: QWidget(parent)
{
QStringList tableHeaders;
tableHeaders << "Device" << "Dirctory" << "Type" << "Sum" << "Free" << "Capacity" << "Used";
tableFileSystem = new QTableWidget(0, 7, this);
tableFileSystem->setHorizontalHeaderLabels(tableHeaders);

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(fsList()));
timer->start(10000);
fsList();

QVBoxLayout *fileSystemLayout = new QVBoxLayout;
fileSystemLayout->addWidget(tableFileSystem);
setLayout(fileSystemLayout);
}

void FileSystemTab::updateFileSystem()
{
}
/*获取分区信息并显示*/
void FileSystemTab::fsList()
{
FILE *fd;
QString str = "/dev/";
int i = 0;
char buf[80];
char items[4][10];

tableFileSystem->setRowCount(0);

fd = fopen("/proc/partitions", "r");
fgets(buf, 80, fd);
fgets(buf, 80, fd);
while(fgets(buf, 80, fd))
{
sscanf(buf, "%s%s%s%s", items[0], items[1], items[2], items[3]);
tableFileSystem->insertRow(0);
tableFileSystem->setItem(0, 0, new QTableWidgetItem(str + items[3]));
tableFileSystem->setItem(0, 3, new QTableWidgetItem(items[2]));
}
}



/*表格头文件tab.h*/
#ifndef TAB_H
#define TAB_H

#include <QLabel>
#include <QWidget>
#include <QTableWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QTimer>
#include <QFile>
#include <QTextStream>
#include <QList>
#include <QDir>
#include <QProgressBar>
#include <QLocale>

#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>

class ProcessTab : public QWidget
{
Q_OBJECT
public:
ProcessTab(QWidget *parent = 0);



private:
QLabel *cpuUsageLabel;
QTableWidget *tableProcess;

int cpuDataStart[4];
int cpuDataEnd[4];



private slots:
void updateCpu();
void updateProcess();
};



class ResourceTab : public QWidget
{
Q_OBJECT
public:
ResourceTab(QWidget *parent = 0);



private:
QProgressBar *cpuBar;
QProgressBar *memoryBar;
QProgressBar *swapBar;
QLabel *memoryLabel;
QLabel *swapLabel;
QLabel *netReceiveLabel;
QLabel *netTransmitLabel;

/*消息槽*/
private slots:
void updateCpuBar();
void updateMemory();
void updateNet();
};



class FileSystemTab : public QWidget
{
Q_OBJECT
private:
QTableWidget *tableFileSystem;



public:
FileSystemTab(QWidget *parent = 0);



/*消息槽*/
private slots:
void updateFileSystem();
void fsList();
};



#endif
============================

全部手写, 未用QT designer, 未完成, 只实现了部分功能。



运行界面如下图。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: