Qt main loop
-
wrote on 15 Feb 2023, 08:05 last edited by
Hi,
Is it possible to use an int main equivalent loop to run through code continually, instead of being triggered by a signal?Ideally, if this could be done without Qtimer to give the signals to run the code, would be great...
I don't actually know where the main loop is, is there one at all?
-
Hi,
Is it possible to use an int main equivalent loop to run through code continually, instead of being triggered by a signal?Ideally, if this could be done without Qtimer to give the signals to run the code, would be great...
I don't actually know where the main loop is, is there one at all?
@agmar said in Qt main loop:
I don't actually know where the main loop is, is there one at all?
Did you start one? You should know.
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); // THIS STARTS EVENT LOOP }
Can you explain what you actually want to do? Do you need an event loop? A Qt application usually needs an event loop.
-
@agmar said in Qt main loop:
I don't actually know where the main loop is, is there one at all?
Did you start one? You should know.
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); // THIS STARTS EVENT LOOP }
Can you explain what you actually want to do? Do you need an event loop? A Qt application usually needs an event loop.
wrote on 15 Feb 2023, 08:15 last edited by@jsulm it would be nice to have something print out at supersonic speed, like in an arduino serial monitor without any delay, putting in a debug into the main loop does not seem to do that...
const char test = 'a'; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test; }
-
@jsulm it would be nice to have something print out at supersonic speed, like in an arduino serial monitor without any delay, putting in a debug into the main loop does not seem to do that...
const char test = 'a'; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test; }
@agmar I still don't understand your use case. Do you want to print data coming from Arduino? Why does it have to be "supersonic speed"?
-
@jsulm it would be nice to have something print out at supersonic speed, like in an arduino serial monitor without any delay, putting in a debug into the main loop does not seem to do that...
const char test = 'a'; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test; }
@agmar said in Qt main loop:
const char test = 'a';
int main(int argc, char *argv[])
{QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test;
}
Well, this will of course print 'a' after the event loop terminates. But what is the point of this? If your read your data from Arduino (via serial port) you can do it perfectly fine using asynchronous QSerialPort running an event loop...
-
@jsulm it would be nice to have something print out at supersonic speed, like in an arduino serial monitor without any delay, putting in a debug into the main loop does not seem to do that...
const char test = 'a'; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test; }
wrote on 15 Feb 2023, 08:25 last edited by JonB@agmar said in Qt main loop:
putting in a debug into the main loop does not seem to do that...
You do not put a
qDebug()
into the main loop, you have put it after the main loop. The main loop is inside theQApplication::exec()
, and that does not return till told to quit.As @jsulm has said, if you want something to happen call from inside the main loop you need to use async calls on the serial port.
-
@agmar said in Qt main loop:
const char test = 'a';
int main(int argc, char *argv[])
{QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test;
}
Well, this will of course print 'a' after the event loop terminates. But what is the point of this? If your read your data from Arduino (via serial port) you can do it perfectly fine using asynchronous QSerialPort running an event loop...
wrote on 15 Feb 2023, 08:37 last edited by agmar@jsulm i probably should have said " just like in an arduino serial monitor without any delay''
It has no requirement to be fast, but should be given that the printout has no delay and the same ''print'' command would run repeatedly with no breaks in between.This video shows what i mean, but it has a delay: https://youtu.be/Ay6cUgzttNM?t=723
If there were no delay, the current value would just fill the monitor with thousands of prints per second (<---goal)
For some additional context, i am use to a while(1) loop running continually with interrupts triggering a function, in Qt, signals take care of the interrupt part, but i have no idea how to get a loop running that will not block out the signals...
-
@agmar said in Qt main loop:
putting in a debug into the main loop does not seem to do that...
You do not put a
qDebug()
into the main loop, you have put it after the main loop. The main loop is inside theQApplication::exec()
, and that does not return till told to quit.As @jsulm has said, if you want something to happen call from inside the main loop you need to use async calls on the serial port.
-
@JonB Where do i put the qDebug() << test; then? Because i think putting it in the brackets will give nothing useful
wrote on 15 Feb 2023, 08:43 last edited by@agmar
You need to write code that will be executing while the main loop is running. You cannot do this anywhere in the code you show. You need e.g. to create aQSerialPort
(perhaps as a member variable inMainWindow
) and attach slots to its signals (e.g.readyRead()
), that is where you can put output etc, statements. -
@agmar
You need to write code that will be executing while the main loop is running. You cannot do this anywhere in the code you show. You need e.g. to create aQSerialPort
(perhaps as a member variable inMainWindow
) and attach slots to its signals (e.g.readyRead()
), that is where you can put output etc, statements.wrote on 15 Feb 2023, 08:52 last edited by@JonB is it not possible to have a loop running? this should not be associated with any serial port, this is a seperate issue that i want to tackle...
ideally, i would be able to have the following:
int main(){
some setup code
while(1){
code that runs perpetually, until return 0;
}
}void some_interrupt();
the some_interrupt is code that would execute after some external event would trigger a pin on an mcu or something, and after it finishes, the while(1) would continue where it left off.
In my case for Qt, i want to have something similar to the while(1), with signals having the ability to execute mid (while) loop and resume the code that was running in the while loop, is this a thing that can be done?
-
@JonB is it not possible to have a loop running? this should not be associated with any serial port, this is a seperate issue that i want to tackle...
ideally, i would be able to have the following:
int main(){
some setup code
while(1){
code that runs perpetually, until return 0;
}
}void some_interrupt();
the some_interrupt is code that would execute after some external event would trigger a pin on an mcu or something, and after it finishes, the while(1) would continue where it left off.
In my case for Qt, i want to have something similar to the while(1), with signals having the ability to execute mid (while) loop and resume the code that was running in the while loop, is this a thing that can be done?
@agmar said in Qt main loop:
is it not possible to have a loop running?
Why do you need such loop?
You are using an asynchronous framework (Qt), there is no need for such loops most of the time.
Please explain better what you are doing: do you read data from Arduino? If so how? In Qt you can simply use QSerialPort and don't need any blocking loops.If you really want such a loop you would need to move it to another thread to not to block your main thread. But that increases complexity a lot and should only be done if really needed and if you really know what you're doing.
-
@JonB is it not possible to have a loop running? this should not be associated with any serial port, this is a seperate issue that i want to tackle...
ideally, i would be able to have the following:
int main(){
some setup code
while(1){
code that runs perpetually, until return 0;
}
}void some_interrupt();
the some_interrupt is code that would execute after some external event would trigger a pin on an mcu or something, and after it finishes, the while(1) would continue where it left off.
In my case for Qt, i want to have something similar to the while(1), with signals having the ability to execute mid (while) loop and resume the code that was running in the while loop, is this a thing that can be done?
wrote on 15 Feb 2023, 09:01 last edited by JonB@agmar
You absolutely do not want to use that pattern, with awhile (1)
blocking loop in the main thread (which will stop the UI from being responsive), when using Qt/an event-driven system. Try to get out of that mindset.The pattern you want to use will look like:
// in `MainWindow.h`, class `MainWindow` private: QSerialPort serial; private slots: void onReadyRead(); // in `MainWindow.cpp` MainWindow::MainWindow(...) { serial.open(...); connect(&serial, &QSerialPort::readyRead, this, &MainWindow::onReadyRead); } void MainWindow::onReadyRead() { QByteArray bytes = serial.readAll(); qDebug() << "Bytes read:" << bytes; }
This means that any time new data arrives
MainWindow::onReadyRead()
will be called. the rest of the time the Qt main loop is just servicing whatever UI input arrives. It remains "responsive" rather than getting "blocked". Note that there is no "while loop" or "interrupts". -
@agmar said in Qt main loop:
is it not possible to have a loop running?
Why do you need such loop?
You are using an asynchronous framework (Qt), there is no need for such loops most of the time.
Please explain better what you are doing: do you read data from Arduino? If so how? In Qt you can simply use QSerialPort and don't need any blocking loops.If you really want such a loop you would need to move it to another thread to not to block your main thread. But that increases complexity a lot and should only be done if really needed and if you really know what you're doing.
wrote on 15 Feb 2023, 09:06 last edited by@jsulm like i mentioned, this is not related to a serialport or anything i have asked help for in the past, this is a seperate thing, however, this is exactly what i hope to do-
C++ code found here:
https://www.geeksforgeeks.org/signal-handling-in-cpp/// CPP Program to demonstrate the signal() function #include <csignal> #include <iostream> using namespace std; void signal_handler(int signal_num) { cout << "The interrupt signal is (" << signal_num << "). \n"; // It terminates the program exit(signal_num); } int main() { // register signal SIGABRT and signal handler signal(SIGABRT, signal_handler); while (true) cout << "Hello GeeksforGeeks..." << endl; return 0; }
Output: Being in an infinite loop this code will show the following output until an interrupt is faced:
Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks...
Now if we press Ctrl+C to send an interrupt, the program will exit by printing:
Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... The interrupt signal is (22).
the while(1) is blocking, sure, but it should not matter because an interrupt(signal) should execute mid execution of any while(1) line
-
@agmar
You absolutely do not want to use that pattern, with awhile (1)
blocking loop in the main thread (which will stop the UI from being responsive), when using Qt/an event-driven system. Try to get out of that mindset.The pattern you want to use will look like:
// in `MainWindow.h`, class `MainWindow` private: QSerialPort serial; private slots: void onReadyRead(); // in `MainWindow.cpp` MainWindow::MainWindow(...) { serial.open(...); connect(&serial, &QSerialPort::readyRead, this, &MainWindow::onReadyRead); } void MainWindow::onReadyRead() { QByteArray bytes = serial.readAll(); qDebug() << "Bytes read:" << bytes; }
This means that any time new data arrives
MainWindow::onReadyRead()
will be called. the rest of the time the Qt main loop is just servicing whatever UI input arrives. It remains "responsive" rather than getting "blocked". Note that there is no "while loop" or "interrupts".wrote on 15 Feb 2023, 09:08 last edited by@JonB this is not for a serial port however, what you wrote makes perfect sense, but it is not the problem i want to solve, its separate from everything i needed help with before, my latest reply to jsulm should make sense, i hope
-
@agmar said in Qt main loop:
is it not possible to have a loop running?
Why do you need such loop?
You are using an asynchronous framework (Qt), there is no need for such loops most of the time.
Please explain better what you are doing: do you read data from Arduino? If so how? In Qt you can simply use QSerialPort and don't need any blocking loops.If you really want such a loop you would need to move it to another thread to not to block your main thread. But that increases complexity a lot and should only be done if really needed and if you really know what you're doing.
-
@jsulm like i mentioned, this is not related to a serialport or anything i have asked help for in the past, this is a seperate thing, however, this is exactly what i hope to do-
C++ code found here:
https://www.geeksforgeeks.org/signal-handling-in-cpp/// CPP Program to demonstrate the signal() function #include <csignal> #include <iostream> using namespace std; void signal_handler(int signal_num) { cout << "The interrupt signal is (" << signal_num << "). \n"; // It terminates the program exit(signal_num); } int main() { // register signal SIGABRT and signal handler signal(SIGABRT, signal_handler); while (true) cout << "Hello GeeksforGeeks..." << endl; return 0; }
Output: Being in an infinite loop this code will show the following output until an interrupt is faced:
Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks...
Now if we press Ctrl+C to send an interrupt, the program will exit by printing:
Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... Hello GeeksforGeeks... The interrupt signal is (22).
the while(1) is blocking, sure, but it should not matter because an interrupt(signal) should execute mid execution of any while(1) line
wrote on 15 Feb 2023, 09:12 last edited by JonB@agmar said in Qt main loop:
the while(1) is blocking, sure, but it should not matter because an interrupt(signal) should execute mid execution of any while(1) line
Your example is not a Qt program and is not for a Qt program. It is a pattern for a "command line" application and you are inappropriately copying it into an event-driven GUI application. If you want to write a Qt command-line-only program you can do so, but you are writing a UI one so not. This seems to be the crux of your (mis-)understanding.
In any case, what exactly are you trying to achieve? Why are trying to write an application with windows/a UI built around an example using Ctrl+C interrupt and
cout
s? -
@jsulm sorry for not answering : Why do you need such loop?
i think it would be useful to know how to do, this might not be useful now , but this is one of the fundamentals to learn, for me, at least...
@agmar said in Qt main loop:
i think it would be useful to know how to do, this might not be useful now
A loop is a loop not much to learn. Just write a loop.
What you really need to understand and learn is that you do not want to have endless (or long lasting) loops in an event driven application! If you put such a loop in main thread you block the Qt event loop and your app stops responding to user input or to process any signals. If, for whatever reason, you need such a loop in an event driven application you need to move it into another thread."the while(1) is blocking, sure, but it should not matter because an interrupt(signal) should execute mid execution of any while(1) line" - yes, and you can handle system signals in a Qt application in exact same way as you do in any other C/C++ application - install a handler for the system signal you want to handle...
-
@agmar said in Qt main loop:
i think it would be useful to know how to do, this might not be useful now
A loop is a loop not much to learn. Just write a loop.
What you really need to understand and learn is that you do not want to have endless (or long lasting) loops in an event driven application! If you put such a loop in main thread you block the Qt event loop and your app stops responding to user input or to process any signals. If, for whatever reason, you need such a loop in an event driven application you need to move it into another thread."the while(1) is blocking, sure, but it should not matter because an interrupt(signal) should execute mid execution of any while(1) line" - yes, and you can handle system signals in a Qt application in exact same way as you do in any other C/C++ application - install a handler for the system signal you want to handle...
wrote on 15 Feb 2023, 09:44 last edited by@jsulm said in Qt main loop:
yes, and you can handle system signals in a Qt application in exact same way as you do in any other C/C++ application - install a handler for the system signal you want to handle...
@agmar
...But be aware that a Qt application with a UI is not going to receive any interrupt signal from pressing e.g. Ctrl+C in a window, that is a tty function and you are not using a tty here. Nor will yourcout
s go anywhere useful.... -
-
@jsulm it would be nice to have something print out at supersonic speed, like in an arduino serial monitor without any delay, putting in a debug into the main loop does not seem to do that...
const char test = 'a'; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); qDebug() << test; }
wrote on 16 Feb 2023, 08:07 last edited by@agmar said in Qt main loop:
it would be nice to have something print out at supersonic speed
This is why your while(1) loop is wrong. Qt is event driven, like others have said already. QSerialPort has a signal that fires immediately when something arrives on the serial port (as "immediate" as possible). This signal needs to be connected to a slot that does the output. There is no noticeable delay in this approach. If you use cout for output, you need to make sure to flush the output immediately. Otherwise the buffer needs to be filled up before if flushes on its own. That indeed would be a delay.
1/19