user5160714
user5160714

Reputation: 3

GUI update and control at the same time in qt

I am trying to create a GUI for controlling and monitoring an industrial machine in QT. The GUI should update every 300ms with the measurements from the machine. And I should be able to control the machine at the same time. What I was doing (wrong) is I was trying to update the measurements in GUI using a timer which triggers every 300ms. But if I click my control buttons at the same time as the timer slot getting executed, the GUI is not responding. I tried using signals and slot technique too. Same result. I wasn't able to find a solution in internet. I would be happy if someone could help. Thanks in advance.

Upvotes: 0

Views: 640

Answers (2)

user5160714
user5160714

Reputation: 3

I found out what the problem was. It was not what I thought it was. I was requesting for the status of the machine with which I was communicating every 30ms. I increased it to 3000ms now it works fine. The button will not cause any problem even if clicked when another slot is being executed. It was a foolish thing to ask. Thanks for the help everyone. All the answers were very informative. Thanks again.

Upvotes: 0

Alex Huszagh
Alex Huszagh

Reputation: 14584

There are three main approaches to doing this, each which has their advantages and disadvantages.

Easy, Non-Scalable Solution


The easiest way is to call QApplication::processEvents() inside your "busy" code manually. For example, to manually update the GUI each loop you could do this:

for (int i = 0; i < 5000; ++i) {
    label->setText(tr("At Index %1...").arg(i));
    QApplication::processEvents();
}

Pros

  1. Very easy
  2. No concurrency issues

Cons

  1. Very limited functionality
  2. Pollutes code

Threads

If you want an easy solution, but scalable one, subclassing QThread and then running non-GUI tasks in a separate thread is a great approach:

class MyThread: QThread
{
    Q_OBJECT

    void run()
    {
        for (size_t i = 0; i < 50000; ++i) {
            std::cout << i << std::endl;
        }
    }
};

auto *thread = new MyThread;
thread->start();

While that long task occurs, the GUI will update, and Qt will take care of the garbage collection.


Pros

  1. Fairly simple
  2. Robust, scalable, and signals/slots allow data exchange

Cons

  1. You cannot update the GUI from any thread other than the main thread.
  2. Signals/slots must use QueuedConnection.

Event Loops

The last approach is Qt's native solution: a QEventLoop.

QTimer timer;
QEventLoop loop;

timer.setSingleShot(true);
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));

timer.start(5000); 
loop.exec();

This is substantially less intuitive, but happens to be much better in most cases by avoiding busy waiting.


Pros

  1. Minimal CPU usage

Cons

  1. Less intuitive.

You can read more here. I originally had a modern resource with the same information, so if you find a similar link on the Qt5 documentation, please edit this post.

Upvotes: 1

Related Questions