Solved Writing own blocking function
-
@stvtdn said in Writing own blocking function:
The function should be blocking until a result has been created.
Don't block. Show a modal
QProgressDialog
instead. -
Hello,
thank you for your replies!I could implement SIGNAL/SLOTS for this task but I wanted to know, how - for example - "waitForReadyRead" works because it is sometimes a better workflow. If you call the blocking function you are able to proceed in the same context and do not have to implement an extra SLOT for this and comment your source code like "From here it goes on in the slot xyz()".
The blocking part itself is not a problem. It is running in a worker thread and will not block the GUI thread.
-
@stvtdn You can use local https://doc.qt.io/qt-5/qeventloop.html
-
@stvtdn said in Writing own blocking function:
I could implement SIGNAL/SLOTS for this task but I wanted to know, how - for example - "waitForReadyRead" works because it is sometimes a better workflow. If you call the blocking function you are able to proceed in the same context and do not have to implement an extra SLOT for this and comment your source code like "From here it goes on in the slot xyz()".
The blocking part itself is not a problem. It is running in a worker thread and will not block the GUI thread.
OK, that makes sense.
To clarify @jsulm's suggestion: Start a
QEventLoop
usingQEventLoop::exec()
in yourdoBlock()
function. This will causedoBlock()
to block until you quit the event loop. Connect your socket'sreadyRead()
signal to your data processing slot. In this slot, generate your result and callQEventLoop::quit()
. -
@stvtdn said in Writing own blocking function:
waitForReadyRead
The problem with this is that you can't quit the thread until this function returned which can (and sooner or later will) maybe create troubles.
-
here you have my way of doing it
void atpTcpSocket::socketReadyRead() { qint32 size = *sizeData; while (this->bytesAvailable() > 0) { QByteArray sockReadAll = this->readAll(); buffer->append(sockReadAll); while ((size == 0 && buffer->size() >= 4) || (size > 0 && buffer->size() >= size)) { //While can process data, process it if (size == 0 && buffer->size() >= 4) {//if size of data has received completely, then store it on our global variable size = ArrayToInt(buffer->mid(0, 4)); *sizeData = size; buffer->remove(0, 4); } if (size > 0 && buffer->size() >= size) {// If data is received completely, then emit our SIGNAL with the data QByteArray data = buffer->mid(0, size); buffer->remove(0, size); size = 0; *sizeData = size; emit socketDataReceived(isLoggedIn, connId, userName, data); } } } }
hope this help
I'm using signal end slots system and the GUI is not blocked at any time, also my server is running in thread pool mode with is the best way if you have to handle many connections at a time -
@arsinte_andrei said in Writing own blocking function:
while (this->bytesAvailable() > 0)
This is not needed since readyRead() is emitted as soon as there is new data available.
-
Thank you so much for your replies guys!
As suggested I am now using the QEventLoop which will be quitted by QCoreApplication::quit() instead of emitting a signal.
A little question to that: I have two event loops now, one in main.cpp and one in my worker class. It looks like that everything is going right but I do not really understand how it works.
Which event loop will be closed by calling QCoreApplication::quit()? Is it the last one created? In other words, in which context am I working, if I create a new event loop? -
Ok, that was a stupid question.... My application is quitting now.
-
@stvtdn said in Writing own blocking function:
As suggested I am now using the QEventLoop which will be quitted by QCoreApplication::quit()
I'm not sure why you want to exit your application when this event loop finishes?
I thought you wanted a blocking function, which blocks until it's done with its work?
To terminate your event loop you can connect a signal to https://doc.qt.io/qt-5/qeventloop.html#quit -
Thank you for your help! Yesterday I had a segmentation fault in my brain...
I think I got it now: https://pastebin.com/XuadvD9X
This example timeouts before the signal finished() is emitted. To test the correct way you need to set the timer value higher than the singleShot timeout.