Qt: Concatenate internal constructor. Will the slot be called before the object is initialized?

I am studying the Qt (C ++) framework and was wondering if QT has any mechanisms to protect slots from being called before the object is fully initialized.

Consider the constructor of class A:

A::A() {
    mTreeView = new QTreeView();
    ...
    connect(mTreeView, &QTreeView::customContextMenuRequested,
        this, &A::OnContextMenuRequested);
    ...
}

      

My concern is that the user will be able to right click on the tree view before the constructor finishes. 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 () starts.

Should I be worried about such scenarios? And if so, is there a way to avoid these problems by not initializing all of your objects first and then returning and concatenating events separately afterwards?

+3


source to share


1 answer


In most cases, you do not need to worry about such scenarios, since events are dispatched in a single thread. There is no "hidden multithreading" that you have to take care of. Unless you explicitly call the function in A's constructor that invokes event handling, you will be safe and your current method, slot execution, etc. Executed before the next event is processed.

Thus, the cases where a new event is handled and thus other code is executed (event handlers, slots):

  • the execution of the current event handler, slot, etc. has finished. (the code where you create A

    ) and Qt returns to the event loop to wait for the next event. In your case, after instance A.
  • you start a local event loop (create a QEventLoop object and call exec ())
  • you call QCoreApplication :: processEvents ()
  • you call exec () in QDialog

1) - normal Qt mode runs in: you run app.exec () which starts the event loop. Everything after that is directly or indirectly triggered by an event (user input, timer, I / O). The event occurs and is added to the event loop of the event loop. The event loop calls event handlers for the event. When the event handlers are complete, the event loop picks up the next event and calls the handlers for it.



So everything happens in an orderly fashion, one event after another, if only one of the event handlers (for example, the slot listening for the button clicked signal ()) does one of 2, 3, or 4. Qt then handles the next event in place, .ie where exec () or processEvents () is called. Event handlers / intervals are executed accordingly. Then exec () / processEvents () is called. Now all the certainties that exec () / processEvents () would not have been called are gone, unfortunately: the user could do random things, things could be arbitrarily changed or deleted (even the pointer this

if the user closed the window, for example). So especially 2) and 3) are error prone and usually lead to severe headaches, so I would avoid them whenever possible, or at least be aware of potential problems.

You can now use multithreading . Since all of the actual UIs and their associated custom events are handled on the same main thread, multithreading here usually means that you have threads that execute non-UI and that interact with your UI thread by calling functions on objects living in user interface thread by modifying the data shared by both threads or using signal / slot cross-stream connections.

  • If you don't use signals / slots, but direct method calls from a secondary thread to the UI thread, or modify shared data, the usual rules of multithreading apply: things will go wrong if you don't know what you are doing and use synchronization accordingly. Qt UI classes are not thread safe.
  • If you are using signals / slots, calls are / are queued /, that is, if thread B emits a signal and you receive it in a slot in the main thread, the slot call is delivered in the same way as the event user: the same rules apply as for custom events. If you don't do one of 2, 3, 4, the slot will not be called until the event handler / slot returns. Thus, connections between signals / slots for cross-streams are a way of passing / passing messages / where messages are delivered through an event loop.
+6


source







All Articles