How can i stop listview and listWidget from flickering?
-
Hello everyone.
I am trying to get the list of processes in a <1 ms intervals and then show the latest list in a listwidget or a listview.
In the listWidget i am having lots of flickering happening!
i tried listview it is even worse!
this is my sample code :@#include "frmprocess.h"
#include "ui_frmprocess.h"
#include "qprocess.h"
#include <windows.h>
#include <tlhelp32.h>
#include "qstring.h"
#include "qtimer.h"
#include "qlist.h"
#include "qmessagebox.h"frmProcess::frmProcess(QWidget *parent) : QMainWindow(parent), ui(new Ui::frmProcess)
{
ui->setupUi(this);//setting timer timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(OnTimerTick())); model = new QStringListModel(this);
}
frmProcess::~frmProcess()
{
delete ui;
}
//in each timer tick event, we get the latest list of running processes
void frmProcess::OnTimerTick()
{
LatestProcessList.clear();
LatestProcessList.append(GetAllRunningProcesses());if(ui->checkBox->isChecked()) { //getting new processes which are not in the white-list GetDifference(); }
ui->listWidget->addItems(GetAllRunningProcesses());
//Filling model! in order to avoid flickering!-- this doesnt help! model->setStringList(LatestProcessList); ui->listView->setModel(model);
}
//This is where we create a white-list out of our latest running process list
void frmProcess::on_pushButton_clicked()
{
// GetAllRunningProcesses();
WhiteList.clear();
ui->listWidget_2->clear();WhiteList.append(GetAllRunningProcesses()); ui->listWidget_2->addItems(WhiteList);
}
//This method gets the list of all running processes
QList<QString> frmProcess::GetAllRunningProcesses()
{
HANDLE hSysSnapshot = NULL;
PROCESSENTRY32 proc;QList<QString> list; proc.dwSize = sizeof(proc); hSysSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ); Process32First(hSysSnapshot,&proc); proc.dwSize = sizeof(proc); ui->listWidget->clear(); list.clear(); do { list.append(QString::fromWCharArray(proc.szExeFile)); } while(Process32Next(hSysSnapshot,&proc)); CloseHandle( hSysSnapshot ); return list;
}
void frmProcess::GetDifference()
{
QSet<QString> intersection = LatestProcessList.toSet().subtract(WhiteList.toSet());
ui->listWidget_3->clear();
ui->listWidget_3->addItems(intersection.toList());
}void frmProcess::on_btnStartTimer_clicked()
{
if(ui->btnStartTimer->text()=="Start")
{
timer->start(1);
ui->btnStartTimer->setText("Stop");
}
else
{
timer->stop();
ui->btnStartTimer->setText("Start");
}
}@ -
Hi,
Technically you are trying to refresh a widget at over 1kHz which is way too fast. What you can do is cache the data and refresh a bit more slowly.
Also, why trying to go that fast ?
-
Hi
Thanks for the response :)
the reason i am doing it in such a way is that i need and i want to get the closest time to the realtime events concerning creation of processes.
lessening that rate would result in un dependable results i.e the list doesnt represent the process lists at all. -
Hi,
There are no screens out there that can update at 1000 Hz. A typical modern screen can only update at around 60 Hz (once every ~17 ms). See http://www.tweakguides.com/Graphics_7.html
[quote author="Coderx" date="1387939887"]i need and i want to get the closest time to the realtime events concerning creation of processes.
lessening that rate would result in un dependable results i.e the list doesnt represent the process lists at all.[/quote]The human eye can't process updates that quickly :)Have a look at the Windows Task Manager, which has a table of processes. It updates at only 1 Hz. When I set it to View -> Update Speed -> High, the update rate goes up to 2 Hz. Updating every 500 ms is considered "high speed"!
[quote author="Coderx" date="1387772591"]
@
ui->listWidget_3->clear();
ui->listWidget_3->addItems(intersection.toList());
@
[/quote]
Destroying and creating new QListWidgetItems every iteration is expensive. Try updating your existing ones using QListWidgetItem::setText() instead. It might help, but I agree with SGaist: Your best solution is still to update the widget less frequently.(You can compute a new list every 1 ms, but don't update the widget every 1 ms)