1

I am new to and learning the Qt GUI framework.

I have an ultrasonic sensor wired up to the Raspberry Pi, to measure water level. If I were coding in C, I would have used a while(1) loop to constantly read the sensor input. But when I put while(1) inside MainWindow.cpp, the window cannot be displayed. However, using qDebug() I can still print out the sensor value, which means my while(1) still running but the main window won't appear. I found out in this answer that because of while(1),

MainWindow ctor never returns, so w.show() is never called and a.exec() (main message loop) is never executed.

To solve this, I use QTimer instead of a loop: connect the timeout() SIGNAL to a SLOT which is a function to read the sensor value one-time:

waterLevelTimer = new QTimer(this);
connect(waterLevelTimer, SIGNAL(timeout()), this, SLOT(getWaterLevel()));
waterLevelTimer->start(100); // "loop" once every 100 millisecond

With this method, I can read the sensor value with the fastest interval is 1 millisecond and the GUI still displayed fine.

But should I use QTimer to mimic a while(1) loop? Is there a better way to have an infinite loop to read GPIOs while still being able to use GUI for other work?

6
  • You should never have infinite loops in event-driven program (which basically all GUI programs are). And a constructor should really only initialize an object, not perform work. Commented Jul 24, 2021 at 9:26
  • 1
    And the solution you your problem is a timer, not an infinite loop. As a possible secondary solution you might be able to use a worker-thread but that could add other complications with synchronization and communication between the GUI and the thread. Commented Jul 24, 2021 at 9:28
  • Thanks for the comments! Where should I put my work-performing code? I followed several Qt beginner examples and they all code inside MainWindow.cpp. Commented Jul 24, 2021 at 9:35
  • If you need to do something at periodic intervals a timer (QTimer) is perfect, that's what it's for. It's bettern than an infinite loop where you call sleep or something similar. Commented Jul 24, 2021 at 9:39
  • Can QTimer handle one-hour long interval? Commented Jul 24, 2021 at 9:47

1 Answer 1

2

The main thread where the GUI of Qt runs never should be blocked by long-lasting operations like an infinite while-loop, because otherwise you would block the event system and nothing will work anymore.

Instead you usually create a worker thread in parallel (see QThread) where you do your loop in the run function of the thread. Maybe also use such timer as you suggest, which works if the executed code is faster than the timer duration.

QThread *thread = QThread::create([]{
    while(1)
        checkSomething();
});
thread->start();
Sign up to request clarification or add additional context in comments.

2 Comments

QThread seems perfect for me. But your last sentence, what will happen if the work takes longer than the timer's interval?
If the timer triggers faster than the executed code takes, it will lead to congestion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.