Why QEventLoop made segmentation fault in qt creator application?
-
I have Qt application. I have a serial port to send and receive data.When i write sth to my device on serial port, I will receive answer.My serial port class is in a thread and run in background to listen the device. this is my code:
PortSerial::PortSerial(QString port, int dev) { printErrors("PortSerial","start fn"); devid=dev; if(!openport(port)) { printErrors("PortSerial","Port:"+port+" can not open."); } moveToThread(&t); connect(&t,SIGNAL(started()),this,SLOT(readserialport())); t.start(); } void PortSerial::readserialport() { printErrors("readserialport","start fn"); while (1) { if(serialport.waitForReadyRead(100)) { printErrors("readserialport","the queue is clean"); printErrors("readserialport","wait for read data from sensor"); QByteArray responseData=serialport.readAll(); while (serialport.waitForReadyRead(100)) { responseData+=serialport.readAll(); } printErrors("readserialport","read:"+responseData.toHex()+"\n devid : "+devid); emit readyread(responseData,devid); } } }
when data ready from device my signal emit and fill my Queue in fp class.fp class is a class between my UI(QML) and serial port class.when my ui send data to fp class , the command send to serial port class . My problem is here, I need to wait for device response.so I create a wait function to wait for firing signal from serial port. If user click on cancel button my waiting function send me SEGMENTATION FAULT. but if user doesn't click cancel, all of them work well.
int FP::WaitProccessorForResult(int milisecond) { //ui_interface()->cancelUIOperation() => if true means cancel button pressed printErrors("WaitProccessorForResult","in waiting....."); int rv=0;int i=0; QEventLoop loop; QTimer timer; //timer.setSingleShot(true); //if device answer quit the loop connect( this,SIGNAL(fullQueue()), &loop,SLOT(quit()) ); //if user cancel quit the loop connect(ui_interface(),SIGNAL(CancelUIOperationChanged()),&loop,SLOT(quit())); //if timer finished quit the loop connect( &timer, SIGNAL(timeout()), &loop, SLOT(quit()) ); timer.start(milisecond); loop.exec(); if(timer.isActive()) qDebug("===============QEventLoop================encrypted"); else qDebug("+++++++++++++++QEventLoop++++++++++++++++timeout"); // for( i=0;i<milisecond;) // { // i=i+1000; // QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); // qDebug()<<i; // if(myque.length()>0 || ui_interface()->cancelUIOperation()) // { // i=milisecond; // break; // } // } if(ui_interface()->cancelUIOperation()) { ui_interface()->setCancelUIOperation(false); rv=cancelByUser; } return rv; }
before QEVENTLOOP i used QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);(as you see in comment) but segmentation fault occured again. some one told me to use QEVENTLOOP but there had not changed.
-
I have Qt application. I have a serial port to send and receive data.When i write sth to my device on serial port, I will receive answer.My serial port class is in a thread and run in background to listen the device. this is my code:
PortSerial::PortSerial(QString port, int dev) { printErrors("PortSerial","start fn"); devid=dev; if(!openport(port)) { printErrors("PortSerial","Port:"+port+" can not open."); } moveToThread(&t); connect(&t,SIGNAL(started()),this,SLOT(readserialport())); t.start(); } void PortSerial::readserialport() { printErrors("readserialport","start fn"); while (1) { if(serialport.waitForReadyRead(100)) { printErrors("readserialport","the queue is clean"); printErrors("readserialport","wait for read data from sensor"); QByteArray responseData=serialport.readAll(); while (serialport.waitForReadyRead(100)) { responseData+=serialport.readAll(); } printErrors("readserialport","read:"+responseData.toHex()+"\n devid : "+devid); emit readyread(responseData,devid); } } }
when data ready from device my signal emit and fill my Queue in fp class.fp class is a class between my UI(QML) and serial port class.when my ui send data to fp class , the command send to serial port class . My problem is here, I need to wait for device response.so I create a wait function to wait for firing signal from serial port. If user click on cancel button my waiting function send me SEGMENTATION FAULT. but if user doesn't click cancel, all of them work well.
int FP::WaitProccessorForResult(int milisecond) { //ui_interface()->cancelUIOperation() => if true means cancel button pressed printErrors("WaitProccessorForResult","in waiting....."); int rv=0;int i=0; QEventLoop loop; QTimer timer; //timer.setSingleShot(true); //if device answer quit the loop connect( this,SIGNAL(fullQueue()), &loop,SLOT(quit()) ); //if user cancel quit the loop connect(ui_interface(),SIGNAL(CancelUIOperationChanged()),&loop,SLOT(quit())); //if timer finished quit the loop connect( &timer, SIGNAL(timeout()), &loop, SLOT(quit()) ); timer.start(milisecond); loop.exec(); if(timer.isActive()) qDebug("===============QEventLoop================encrypted"); else qDebug("+++++++++++++++QEventLoop++++++++++++++++timeout"); // for( i=0;i<milisecond;) // { // i=i+1000; // QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); // qDebug()<<i; // if(myque.length()>0 || ui_interface()->cancelUIOperation()) // { // i=milisecond; // break; // } // } if(ui_interface()->cancelUIOperation()) { ui_interface()->setCancelUIOperation(false); rv=cancelByUser; } return rv; }
before QEVENTLOOP i used QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);(as you see in comment) but segmentation fault occured again. some one told me to use QEVENTLOOP but there had not changed.
@MhM93 said in Why QEventLoop made segmentation fault in qt creator application?:
My serial port class is in a thread and run in background to listen the device
Why do you use a thread?
QSerialPort is (as most of Qt) an asynchronous class and most of the time you do not need any threads when using it."My problem is here, I need to wait for device" - there is no need to wait. Consider to use signals/slots intead of messing around with threads and waiting (https://doc.qt.io/qt-6/qiodevice.html#readyRead).
-
i correct the first thread and serial port . it is working without thread. thanks.
but for the second I need to use this sequence :
[button click] -> [button function call] -> [fp class] -> ............SERIAL PORT.........
[button click] <- [button function call return] <- [fp class (return)]<- ..SERIAL PORT return
IS it possible to do that with out signal and slot or the only way is to use signal and slot? -
i correct the first thread and serial port . it is working without thread. thanks.
but for the second I need to use this sequence :
[button click] -> [button function call] -> [fp class] -> ............SERIAL PORT.........
[button click] <- [button function call return] <- [fp class (return)]<- ..SERIAL PORT return
IS it possible to do that with out signal and slot or the only way is to use signal and slot?@MhM93 said in Why QEventLoop made segmentation fault in qt creator application?:
[button click] -> [button function call] -> [fp class] -> ............SERIAL PORT.........
[button click] <- [button function call return] <- [fp class (return)]<- ..SERIAL PORT returnNot sure I understand what you want to do here. Do you mean you want to wait for the response from serial port? If so why?
-
@MhM93 said in Why QEventLoop made segmentation fault in qt creator application?:
i correct the first thread and serial port . it is working without thread. thanks.
but for the second I need to use this sequence :
[button click] -> [button function call] -> [fp class] -> ............SERIAL PORT.........
[button click] <- [button function call return] <- [fp class (return)]<- ..SERIAL PORT return
IS it possible to do that with out signal and slot or the only way is to use signal and slot?yes. i need that result and i want to return it to function that called.
I wanna to know is there any solution except signal and result? -
i correct the first thread and serial port . it is working without thread. thanks.
but for the second I need to use this sequence :
[button click] -> [button function call] -> [fp class] -> ............SERIAL PORT.........
[button click] <- [button function call return] <- [fp class (return)]<- ..SERIAL PORT return
IS it possible to do that with out signal and slot or the only way is to use signal and slot?@MhM93
To use an even-driven framework like Qt it is best if you change approach a bit to not wait/block for something to happen in your code. Instead of waiting for a serial response, send the request and then exit that code, returning to the main Qt event loop. (This is especially important if you have a UI and don't want it to "freeze".) Then when the response arrives at that point execute the code which you would have done had you waited with a blocking call. That is the general programming paradigm.Your latest post has just crossed with mine:
yes. i need that result and i want to return it to function that called.
Rewrite so your code does not need this wait. Make it so it executes the code when the response arrives (via a signal) instead of making it wait for that response.
-
@JonB said in Why QEventLoop made segmentation fault in qt creator application?:
Instead of waiting for a serial response, send the request and then exit that code, returning to the main Qt event loop. (This is especially important if you have a UI and don't want it to "freeze".) Then when the response arrives at that point execute the code which you would have done had you waited with a blocking call. That is the general programming paradigm.
How to to that? could you please give me a help. I used QEventLoop but when sth happened in GUI my app crashed with Segmentation fault.
-
@JonB said in Why QEventLoop made segmentation fault in qt creator application?:
Instead of waiting for a serial response, send the request and then exit that code, returning to the main Qt event loop. (This is especially important if you have a UI and don't want it to "freeze".) Then when the response arrives at that point execute the code which you would have done had you waited with a blocking call. That is the general programming paradigm.
How to to that? could you please give me a help. I used QEventLoop but when sth happened in GUI my app crashed with Segmentation fault.
-
@JonB said in Why QEventLoop made segmentation fault in qt creator application?:
Instead of waiting for a serial response, send the request and then exit that code, returning to the main Qt event loop. (This is especially important if you have a UI and don't want it to "freeze".) Then when the response arrives at that point execute the code which you would have done had you waited with a blocking call. That is the general programming paradigm.
How to to that? could you please give me a help. I used QEventLoop but when sth happened in GUI my app crashed with Segmentation fault.
@MhM93 said in Why QEventLoop made segmentation fault in qt creator application?:
How to to that?
Using signals/slots: https://doc.qt.io/qt-6/signalsandslots.html
There are many examples: https://doc.qt.io/qt-6/qtserialport-examples.html
Especially: -
@MhM93
Don't useQEventLoop
(nor a thread). Just act on signals when you receive them. I don't know what else to say, there are many examples of Qt code. Do you understand how to use signals & slots, have you read up on/used them?@JonB sorry. I confused I thought you said another way
Before this approach I used signal and slot. I knew it and i used it before and it worked well for me. I just try to test another approach with out signal and slot.
I wanna to find a way without using signal and slot.
sorry to make you confuse. and thanks for help -
@MhM93 said in Why QEventLoop made segmentation fault in qt creator application?:
How to to that?
Using signals/slots: https://doc.qt.io/qt-6/signalsandslots.html
There are many examples: https://doc.qt.io/qt-6/qtserialport-examples.html
Especially: