What should, and what must, be done in the UI thread?
-
I have some code. Written by people who are not me. One of the functions in there allows one to call a function, but have it run in the UI thread.
Some of what is being passed to the UI thread really, really does not look like it has to be done in there. Summations of values and updating some data structures and that sort of thing is being pushed off to the UI thread. I'm pulling such things back out of the UI thread, but I don't want to accidentally remove something that should (or even MUST) happen in the UI thread.
Should models be updated in the UI thread? I'm thinking not, so long as the UI thread "knows" not to update the view based on a model while the model is being updated, which I think is done by properly informing the model that it's being updated?
So can anyone give me the thirty second guide to what should and what MUST be done in the UI thread?
-
I use the following rule.
Anything that uses QtWidgets must be done in the GUI thread. Everything else can be pushed to another thread IFF(If and only if) it slowdowns the GUI thread.Often BL(business logic) is fast enough to run in GUI thread but if it is not then using Signal/Slot helps to decouple UI and BL(business logic) and make it easier to move BL to the threads later.
QNetworkAccessManager uses the threads to send requests so the sending requests do not affect GUI. Processing a response may be slow.
-
Hi,
[quote author="Moschops" date="1418397972"]Should models be updated in the UI thread? I'm thinking not, so long as the UI thread "knows" not to update the view based on a model while the model is being updated, which I think is done by properly informing the model that it's being updated?[/quote]By default, QAbstractItemModel and its subclasses must be updated in the UI thread. The reason is:
A View can read from and write to a Model. (To be precise, a Delegate does the writing, but that doesn't matter for our discussion.) Since a View is a QWidget, it does its reads/writes in the UI thread.
To make #1 thread safe, the Model must either (a) only be updated in the UI thread, or (b) use locks in setData(), data(), rowCount(), etc.
#2b is expensive, so Qt's built-in classes don't do it. Qt chose #2a instead.
Note: "Model inform the View that it's being updated" is not enough to guarantee thread safety. For this system to work, the View must also inform the Model when it's reading/writing the Model. However, this breaks the principle of MV design: The Model should not know about the View's existence, nor should it care what the View is doing.
[quote author="Moschops" date="1418397972"]Summations of values and updating some data structures and that sort of thing is being pushed off to the UI thread. I'm pulling such things back out of the UI thread[/quote]You could do the summations in your secondary thread, but writing the results to the data structures in the Model itself must happen in the UI thread.
Generally, if something isn't causing any performance issues, let it stay in the UI thread.
A fast operation could actually perform worse if you push it off into a secondary thread. There is a cost associated with multithreading. Make sure the benefits outweigh the costs before you use it.