gpt4 book ai didi

c++ - 想要在 QThread 中更新 QtableWidget

转载 作者:太空狗 更新时间:2023-10-29 12:31:28 24 4
gpt4 key购买 nike

我正在启动一个名为 Nice System Monitor 的项目,旨在监控 Linux 上的进程,并且我正在使用 C++ 和 Qt 以及 QtCreator。

我已经开始制作一个 QThread 并调用一个函数来重复填充 QTableWidget,但即使我在再次填充之前删除每一行,该表也不会正确更新。

我是 Qt 的新手,并从 Internet 上的不同资源中获得灵感。

这是 QThread 的代码:

#include <unistd.h>
#include <ios>
#include <iostream>
#include <fstream>
#include <string>
#include <dirent.h>
#include <stdio.h>
#include <cctype>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include "renderprocesstablethread.h"
#include <proc/readproc.h>
#include <proc/procps.h>
#include "mainwindow.h"
using namespace std;


RenderProcessTableThread::RenderProcessTableThread(QObject *parent)
: QThread(parent)
{
restart = false;
abort = false;
}

RenderProcessTableThread::~RenderProcessTableThread()
{
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();

wait();
}

bool RenderProcessTableThread::isNum(char *s) {
int i = 0, flag;

while(s[i]){
//if there is a letter in a string then string is not a number
if(isalpha(s[i]) || s[i] == '.'){
flag = 0;
break;
}
else flag = 1;
i++;
}
if (flag == 1) return true;
else return false;
}

string RenderProcessTableThread::convertDouble(double value) {
std::ostringstream o;
if (!(o << value))
return "";
return o.str();
}

string RenderProcessTableThread::convertInt(int value) {
std::ostringstream o;
if (!(o << value))
return "";
return o.str();
}



void RenderProcessTableThread::run()
{
forever {
mutex.lock();
mutex.unlock();
fillProcessTable();
sleep(1000);
//cout << "ça marche" << endl;
}
mutex.lock();
if (!restart)
condition.wait(&mutex);
restart = false;
mutex.unlock();

}


void RenderProcessTableThread::setLocalMainWindow(MainWindow& w)
{
localMainWindow = &w;
ui_tableWidgetProcessus = localMainWindow->findChild<QTableWidget*>("tableWidgetProcessus");
ui_tableWidgetProcessus->setColumnCount(11);
ui_tableWidgetProcessus->setColumnWidth(10,508);
QFont fnt;
fnt.setPointSize(10);
fnt.setFamily("Arial");
ui_tableWidgetProcessus->setFont(fnt);
QStringList labels;
labels << "user" << "pid" << "cpu" << "nice" << "vsz" << "rss" << "tty" << "stat" << "start" << "time" << "cmd";
ui_tableWidgetProcessus->setHorizontalHeaderLabels(labels);
}


void RenderProcessTableThread::fillProcessTable() {

QMutexLocker locker(&mutex);

if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}

PROCTAB* proc = openproc(PROC_FILLUSR | PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS | PROC_FILLARG);
proc_t proc_info;

memset(&proc_info, 0, sizeof(proc_info));

int totalRow = ui_tableWidgetProcessus->rowCount();
for ( int i = 0; i < totalRow ; ++i )
{
ui_tableWidgetProcessus->removeRow(i);
}

int i = 0;
while (readproc(proc, &proc_info) != NULL) {
cout << proc_info.fuser << proc_info.tid << proc_info.cmd << proc_info.resident << proc_info.utime << proc_info.stime << endl;
ui_tableWidgetProcessus->setRowCount(i+1);
ui_tableWidgetProcessus->setItem(i,0,new QTableWidgetItem(QString(proc_info.fuser),0));
ui_tableWidgetProcessus->setItem(i,1,new QTableWidgetItem(QString((char*)convertInt(proc_info.tid).c_str()),0));
ui_tableWidgetProcessus->setItem(i,2,new QTableWidgetItem(QString((char*)convertInt(proc_info.pcpu).c_str()),0));
ui_tableWidgetProcessus->setItem(i,3,new QTableWidgetItem(QString((char*)convertInt(proc_info.nice).c_str()),0));
ui_tableWidgetProcessus->setItem(i,4,new QTableWidgetItem(QString((char*)convertInt(proc_info.vm_size).c_str()),0));
ui_tableWidgetProcessus->setItem(i,5,new QTableWidgetItem(QString((char*)convertInt(proc_info.rss).c_str()),0));
ui_tableWidgetProcessus->setItem(i,6,new QTableWidgetItem(QString((char*)convertInt(proc_info.tty).c_str()),0));
ui_tableWidgetProcessus->setItem(i,7,new QTableWidgetItem(QString(proc_info.state),0));
ui_tableWidgetProcessus->setItem(i,8,new QTableWidgetItem(QString((char*)convertInt(proc_info.start_time).c_str()),0));
ui_tableWidgetProcessus->setItem(i,9,new QTableWidgetItem(QString((char*)convertInt(proc_info.stime).c_str()),0));

//cout << "proc_info.tid : " << proc_info.tid << endl;
//cout << "proc_info.cmdline : " << proc_info.cmdline << endl;

string text;
if (proc_info.cmdline != 0) {
vector<string> v(proc_info.cmdline, proc_info.cmdline + sizeof(proc_info.cmdline) / sizeof(string));
text = v[0];
}
else {
vector<string> v;
v.push_back(proc_info.cmd);
text = v[0];
}
//string text = char_to_string(proc_info.cmdline);

ui_tableWidgetProcessus->setItem(i,10,new QTableWidgetItem(QString((char*)text.c_str()),0));
i++;
}

closeproc(proc);

}

它们是更好的方法吗?

谢谢

帕特里克

最佳答案

这看起来像是 Qt 的 Signal and Slots .在您的情况下,线程发出信号,您的窗口中的一个插槽将被调用。

所以在你的 RenderProcessTableThread.h 中定义一个信号

signals:
void newValues(const QString &data);

在你的 mainwindow.h 中

public slots:
void showNewValues(const QString &data);

将数据添加到您的表中的这个插槽中。然后你必须连接它们(例如,在创建线程后在你的主窗口的构造函数中)

connect(yourThread, SIGNAL(newValues(QString)), this, SLOT(showNewValues(QString)));

每当您想显示新数据时,发出信号(例如,在您的 fillProcessTable() 函数中的某处):

emit newValues(yourValues);

Qt 为您建立线程之间的连接。

关于c++ - 想要在 QThread 中更新 QtableWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25697777/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com