[Interest] Interest Digest, Vol 137, Issue 4

Roland Hughes roland at logikalsolutions.com
Sat Feb 4 19:08:44 CET 2023

On 2/3/23 05:00, Stefan Seefeld wrote:
> Hello,
> I haven't got any response to my question, but as the answer may really
> help us simplify our code I'm sending it again.
> Thanks for any help !
> On Tue, Nov 22, 2022 at 9:02 AM Stefan Seefeld <stefan at seefeld.name> wrote:
>> Hello,
>> we are using Qt State Machines in a number of places in our applications
>> to manage object states for certain types of objects. Occasionally I would
>> like to use and manipulate such objects in a non-event-driven context, i.e.
>> without a running event loop.
>> Short of a StateMachine function that allows me to wait for outstanding
>> transitions to be completed, I wrote a little helper function that
>> instantiates a `QEventLoop`, then calls
>> `processEvents(QEventLoop::ExcludeUserInputEvents)` to drain the event
>> queue and thus make sure that all in-flight transitions have been completed.
>> While this appears to be working fine, I'm not sure this is the best way
>> (or at the very least, a particularly elegant way) to achieve what I want.
>> Is the above a "correct" way to get what I want ? Is there a better way ?

You aren't getting responses because you have run headlong into the 
single-threadiness of Qt. During the days of OS/2 and the 486/SX this 
single-threadiness didn't matter. We had one CPU. We could kind of 
predict how things would run. The Qt architecture became "everything in 
the main event loop and that loop runs only in the primary thread."

Despite the cries of impurity against it, QDialog has its own event loop 
because that is how life works. Tasks interrupt you that must be 
completed prior to anything else moving forward.

You probably need to purge Qt from your design tools. Without knowing 
more I cannot say for certain. I can tell you of the sacrilege (in the 
eyes of the Qt dev team) you are going to be forced into due to this 
architectural flaw.

Solution 1: the qApp pointer

Because the architecture of Qt doesn't work in real life, there has been 
since the earliest days the qApp pointer.


Under the hood it is QCoreApplication::instance(). That gets you access 
to the main event loop so you can qApp->processEvents(); The vast 
majority of database applications have to resort to this. Too many bits 
and pieces seem to queue events rather than just processing so for big 
I/O one gets forced into this despite all of the clucking of tongues 
from the Qt purists.

Solution 2: No Qt.

The C++ standard has moved forward and made copy-on-write illegal since 
C++11. If you want to read a "discussion" about it here:


Here are some good discussions on rolling your own pure C++ state 
machine classes.

Barr group



In particular, you should also look at the set_callback() methods found 
in this NanoGUI demo program.


As stated earlier, the C++ standard has moved forward in a manner that 
is away from "the Qt way." Your classes can now have std::function 
elements which may or may not be set. If you don't have multiple 
subscribers you don't need signals & slots.

The roll-your-own implementation gets you out of "the main event loop" 
so you can do what you wish when you wish in any thread you wish. Where 
you will be hamstrung by Qt again (assuming you need it) is screen 
updates. Painting can only occur in the main event loop which only 
exists in the main thread.

Hope this helps. At least I responded when everyone else turned a deaf ear.

Roland Hughes, President
Logikal Solutions


More information about the Interest mailing list