Iโm having difficulty understanding the best approach to an application that needs to display a large amount of data on a screen that updates at a high speed. I am writing this application in Qt for Windows. I will not go into the details of the actual application, but I wrote an example application below to demonstrate the problem.
In this, I have a thread that calculates values. In this case, this is a single value that is simply a counter. In a real application, its many values. This update is once every millisecond. This metric represents the required data rate, not the required update rate for the graphical interface. As already mentioned, this is done in our own topic. The idea of โโthis stream is that it simply calculates the data and does not care about displaying it.
Now, to update the data display in this example, I use the QLabels grid to display the value several times (simulating the display of many different values). I understand from the Qt documentation that updating a widget should be done in the main GUI thread. So, what am I doing here, I get a stream calculating the values โโin order to emit a signal with the calculated value every time it recounts it (1 ms). It then connects to the main GUI, which then updates each widget in turn to display the value.
The conclusion from this:
- The GUI stream is loaded with a 1 ms update from the data stream, so the display becomes very slow to update. On my machine, with 100 widget updates, I rate the update at approximately 4fps.
- All other aspects of the graphical interface, such as moving, resizing and pressing buttons, all the time try to get processor time.
- It seems that updating a simple QLabel with text seems rather slow. This is normal?
- I also added a synchronization code to this, and a 1 ms update in the GUI stream runs on avergae for about 1.8 ms with a maximum delta time of 40-75 ms. Thus, it works pretty fast, even though it is lagging behind. But, apparently, behind the scenes other events go in line with the events of the GUI thread to actually draw updates on the screen, and they are really struggling.
- I really donโt understand what determines the actual screen refresh rate? How does Qt decide when to refresh the screen here?
, , . , 1 , . , , . GUi GUI?
Qt .
, :
class Generator : public QObject
{
Q_OBJECT
public:
explicit Generator(QObject *parent = 0);
signals:
void dataAvailable(int val);
public slots:
void run(bool run);
void update(void);
private:
QTimer *timer;
int value;
};
void Generator::run(bool run)
{
if(run)
{
value = 0;
timer = new QTimer;
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1);
} else
{
timer->stop();
delete timer;
}
}
void Generator::update()
{
value++;
emit dataAvailable(value);
}
GUI, :
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
QLabel *labels[ROW_MAX][COL_MAX];
Generator *dataGenerator;
public slots:
void dataAvailable(int val);
signals:
void runGenerator(bool run);
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QGridLayout *layout = new QGridLayout;
for(int iCol=0; iCol<COL_MAX; iCol++)
{
for(int iRow=0; iRow<ROW_MAX; iRow++)
{
QLabel *label = new QLabel("Hello");
labels[iRow][iCol] = label;
layout->addWidget(labels[iRow][iCol], iRow, iCol);
}
}
centralWidget->setLayout(layout);
dataGenerator = new Generator;
QThread *dgThread = new QThread;
dataGenerator->moveToThread(dgThread);
dgThread->start(QThread::HighestPriority);
connect(this, SIGNAL(runGenerator(bool)), dataGenerator, SLOT(run(bool)));
connect(dataGenerator, SIGNAL(dataAvailable(int)), this, SLOT(dataAvailable(int)));
emit runGenerator(true);
}
void MainWindow::dataAvailable(int val)
{
for(int iCol=0; iCol< COL_MAX; iCol++)
{
for(int iRow=0; iRow<ROW_MAX; iRow++)
{
labels[iRow][iCol]->setText(QString::number(val));
}
}
}