Interrupt in Qt event - c++

I am working with Qt, Directx 11 and C++. When my widget opens I start an Engine with system->Run(). This function calls every frame a function named Frame() as long as the variable done is set to false.
When the closing event is called in my Qt class, then I want to shutdown the engine. So I made a function named isDone() which sets the variable done to false and then I release all variables I have created with System->Shutdown(). But the problem is that the program crashes because when the closing event is called, the System->Run() function is interrupted as long as the closing event is over, but I want that the Run() function is executed after the call from the function isDone() before the System->Shutdown() function is executed.
Is there any possibility to make an interrupt in the closing event, so that other things in the queue are executed?

Is there any possibility to make an interrupt in the closing event, so that other things in >the queue are executed?
You can call qApp->processEvent in cycle, and wait some flag.

Related

CPP, 'X' button listener

I'm writing a CPP program, and I want to execute a function when the 'X'(shut down) button is pressed.
For example, I have an infinite loop that prints the same thing everytime it iterates, until the 'X' button is pressed, and I want to execute a function before the process ends.
Is there some kind of listener for this matter? Or some other solution maybe (like delaying the process shut down for a few seconds or something)?
Thanks!
If you want to execute something before your process ends, you can register an std::atexit handler. This function will be called before your process exits.

How to know in which thread Qt executes slots?

I use Qt and I need to execute some code in the main thread. I realized that successfully using signals & slots.
My question is, even tho it's working atm: what defines in which thread a slot is executed as the direct result of signal emitting?
Is it inside the thread that executes the connect() function or what?
It depends how you set up your connection.
If you use Qt::DirectConnection, the slot will be executed immediately in the signaling thread, bypassing any event loop.
If you use a Qt::QueuedConnection, it will be executed in the receiving objects event loop, in the receiving objects thread.
If you don't specify the connection type, it defaults to Qt::AutoConnection, which defaults to Qt::QueuedConnection if the two QObjects have different thread affinities.
A directly connected slot always executes immediately, before the signal returns.
A slot connected via a queued connection will execute in the event loop running in its object's thread(). The slot is called from within the exec().
The default automatic connection determines which method to use every time the signal is emitted. If the target object is in the same thread, the slot will be called immediately from the signal, otherwise an event will be posted to the target object, picked up by the target thread's event loop, and executed there.
The logic is, effectively:
void mySignal(params) {
// moc-generated code below
for (all directly connected slots, all automatically connected slots in this thread):
slot(params);
for (all queued-connected slots):
QCoreApplication::postEvent(slot's object, new QMetaCallEvent(slot, params));
}
The direct connection doesn't require an event loop to work, and is like any indirect function call through a function pointer.

Qt: Connect inside constructor - Will slot be invoked before object is initialized?

I am learning Qt framework (C++) and was wondering if QT has any mechanisms to protect slots from being called before an object is fully initialized.
Consider Class A constructor:
A::A() {
mTreeView = new QTreeView();
...
connect(mTreeView, &QTreeView::customContextMenuRequested,
this, &A::OnContextMenuRequested);
...
}
My worry is the user would be able to right-click on the tree-view before A's constructor has finished. Another context is as follows:
A::A() {
mQObj = new MyQObject();
connect(mQObj, &MyQObject::SomeEvent, this, &A::OnEvent);
}
A::InitB() { mB = new B(); }
A::OnEvent() { mB.doSomething(); }
Here, the doSomething() method can be called before InitB() runs.
Do I have to worry about such scenarios? And if so, is there a way to avoid these issues without having to initialize all your objects first, then going back and connecting the events afterwards separately?
You don't have to worry about such scenarios in most cases, because events are delivered in the same thread. There's no "hidden multithreading" going on you have to care about. If you don't explicitly call a function in the constructor of A that causes events to be processed, you're safe and your current method, slot etc.'s execution is completed before the next event is processed.
That said, the cases where a new event is processed and thus other code (event handlers, slots) is executed, are:
the execution of the current event handler, slot etc. is finished (the code where you create A) and Qt returns to the event loop to wait for the next event. In your case, that's after the A instance is fully constructed.
you start a local event loop (Create a QEventLoop object and call exec())
you call QCoreApplication::processEvents()
you call exec() on a QDialog
1) is the normal mode Qt operates in: You start app.exec(), which starts the event loop. Everything after that is directly or indirectly triggered by an event (user input, timer, I/O). Event happens and is added to the event loop's event queue. The event loop calls the event handlers for the event. When the event handlers are completed, the event loop picks the next event and calls the handlers for it.
So everything happens in an orderly fashion, one event after another, unless one of the event handlers (say, a slot listening to a button's clicked() signal) does one of 2, 3 or 4. Then Qt processes the next event in-place, .i.e. where exec() or processEvents() is called. The event handlers/slots are executed accordingly. Then exec()/processEvents() returns. Now all the certainties one would have without calling exec()/processEvents() are gone, unfortunately: The user could have done random stuff, things could be arbitrarily changed or deleted (even the this pointer, if the user closed the window, for example). Thus especially 2) and 3) are error-prone and usually lead to major headaches, so I would avoid them whenever possible, or at least be aware of the potential issues.
Now there's the case that you use multithreading yourself. As all the actual UI and related user events is handled in a single main thread, multithreading here usually means that you have threads doing non-UI work and that interacts with your UI thread by calling functions on objects living in the UI thread, modifying data shared by both threads, or using cross-thread signal/slot connections.
If you don't use signal/slots but direct method calls from the secondary thread to the UI thread or modify shared data, the usual multithreading rules apply: Things will go majorly wrong unless you know what you're doing and use synchronization accordingly. Qt's UI classes aren't thread-safe.
If you use signal/slots, the calls are /queued/, i.e. if thread B emits a signal and you receive it in a slot in your main thread, the call of the slot is delivered in the same manner as a user event: the same rules as for user events apply. Unless you do one of 2, 3, 4, the slot won't be called before your event handler/slot returns. So cross-thread signal/slots connections are a way of /message passing/ where the messages are delivered via the event loop.

Windows phone C++

I'm writing simple application for WP 8.1 using C++/cx. My problem starts when I'm trying to do something in some event. For example if I create simple button event "tapped" and I want to do something inside for example change the color of the button background, it doesn't execute in the correct time. I mean that for the code below it will first execute Somefunction() and then change the color of the button.Same happens for example when I try to show message box using message dialog and ShowAsync function.
but->Background = ref new SolidColorBrush(Windows::UI::Colors::Red);
Somefunciton();
You have the background change and the function call in the same function and that function gets executed on one thread blocking it. This thread happens to be the UI thread which gets blocked for the time of your function execution. So you set the button background but the actual change will be applied only when the UI thread could run the render function and it will be able to do it only after your function call ends.
So in terms of program execution the button background gets updated before the call to Somefunciton();. But visual changes are delayed until after the function call is completed so you might think that Somefunciton(); gets called before the background is set which is not the case.

QThreads interruption with slots and signals

I have a class which contains QThread. In the initialization function of this class the thread should be started. This works correct. in the thread there I have a while(bool certainCondition){} this certainCondition should be changed by a signal/slot connection.
The problem is that during the while is running the signal/slot is not opened.
You are not running an event loop in your thread, or you are blocking for a long time in your while-loop. Your slot cannot be called until you have returned control to the event loop, which will happen after you have finished the while-loop.
As a workaround, you can try calling QCoreApplication::processEvents() inside your while-loop.
In order for signals/slots to work across threads, the event loop must run.
If you use a while loop, the event loop is never run, and hence signals are not received.
This is how you normally run the event loop:
void Thread::run()
{
...do something
exec(); //<<this runs the event loop
}
Now, your problem is that you want continuously run some code until some condition is met. In the above code, this won't work, because of the exec() call.
There are 2 possibilities to solve that (depending on what you want to achieve in your loop):
Use a QTimer, that fires let's say every 5 seconds, and calls a slot which executes your repeating code.
Use a QWaitCondition to check for a certain condition to be fulfilled; but then you cannot use signals and slots; instead you have to trigger the QWaitCondition.