Is it possible to run several QWidgets in separate threads - qt

I am learning Qt and trying to create application that open documents in tabs of QTabWidget. And I need to have each tab running in separate thread. Is it possible? And if it is, can you please show a simple example.

No, this is not possible. Widgets needs to be always drawn and handled by the main thread, where the event loop is executed.
What you can do is defining some slots for each tab which open a document and connect to to some signals in your threads. This way you can emit a signal if a document should be opened in a tab from a different thread and it will be opened and handled by the event loop thread.

Related

Why std::thread can't open a QT Dialog?

I want to open a simple QT dialog inside a std::thread, but it crashes after the dialog open success.
std::thread([&](){
DialogWarning* dlg=new DialogWarning();
dlg->setModal(true);
dlg->exec();
delete dlg;
}).detach();
What is the problem with this code?
UI components can only be opened from the main thread (aka the GUI thread).
From Threading basics | Qt 5.13:
The Qt GUI must run in this [the main] thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads.
The main reason that you cannot open the dialog in a different thread has been correctly mentioned by #MarkoPacak.
However, what you can do to fix the problem is to emit a signal in your thread to be captured by a slot in the main thread. Then, in your slot, you can show the dialog.

prevent QApplication::exec from blocking main thread

I have a visual c++ program which creates multiple GUI on the main thread. I want to show a QWidget alongside all the other GUI. Currently, if I call QApplication.exec(), it blocks the main thread until I close the window. Is there any way to prevent the exec function from blocking the main thread or to use QWidget without calling exec?
The method is not blocking the main thread, on the contrary: it allows the event loop to execute, ensuring that the UI remains responsive.
While the widget is shown, all the other GUI will be responsive, as Qt's event loop fully interoperates with the native message queue.
If you want something to happen when a dialog widget gets closed, connect the relevant code to e.g. the dialog's accepted() signal.

QT Application with Dialogs

I am writing an application in qt. This application will have many dialogs. My question is: what is the strategy with dialog handling? Should I create them in the constructor of the main window or shouold they be created when the user click on buttons (that is when the user need it). Should they be destroyed or they are automatically destroyed?
There is no hard rule to this. Generally dialogs are small and light, and therefore are created when opened and destroyed (usually automatically) when closed. However, if you have a custom dialog that contains very heavy widgets and/or needs to get data from a slow source, then you can create a dialog and only show when it when required.
Should they be destroyed or they are automatically destroyed?
This depends entirely on how you create it. The best I can do is point you to the most informative source.

Qt: How to initialize dialog widgets?

I would like to know what the established procedure is for initializing the controls within a Qt custom dialog box. In the code I am writing, the dialog would present a QListView containing directories from an object passed (by reference) to the dialog class during construction. When the dialog is displayed, I obviously want the list to display the directories currently configured in the object.
Where should this be done though? Perhaps in the overridden showEvent() method?
Background: I used to do a lot of MFC programming back in the day, and would have done this sort of stuff in the OnCreate method, or some such, once the window object had been created.
Thankfully Qt doesn't require you to do any hooking to find the moment to create things (unless you want to). If you look over the Qt examples for dialogs, most do all the constructing in the constructor:
http://doc.qt.io/archives/qt-4.7/examples-dialogs.html
The tab dialog example--for instance--doesn't do "on-demand" initializing of tabs. Although you could wire something up via the currentChanged signal:
http://doc.qt.io/archives/qt-4.7/qtabwidget.html#currentChanged
Wizard-style dialogs have initializePage and cleanupPage methods:
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#initializePage
http://doc.qt.io/archives/qt-4.7/qwizardpage.html#cleanupPage
But by and large, you can just use the constructor. I guess the main exception would be if find yourself allocating the dialog at a much earlier time from when you actually display it (via exec), and you don't want to bear the performance burden for some part of that until it's actually shown. Such cases should be rare and probably the easiest thing to do is just add your own function that you call (like finalizeCreationBeforeExec).

Force immediate paint in JavaFX

Is there a way to force a JavaFX app to repaint itself before proceeding? Similar to a Swing Panel's paint(Graphic g) method (I might be getting the keywords wrong there).
Consider the following example: you write a TicTacToe app along with the AI required for a computer player. You would like the ability to show two computer players duke it out. Maybe you put in a two second pause between computer turns to give it a life-like affect. When you hit your "Go" button, there's a large pause of unresponsiveness (the time it takes for the 9 turns to go by with faked pauses for the computer to 'decide') and then suddenly the app's visual is updated in with the completed game's state.
It seems like JavaFX repaints once processing in the app's thread is finished? I'm not completely sure here.
Thanks!
You are right. JavaFX is event-driven and single-threaded. This means that repaint and event response can not be done simultaneously. Long-running task should be executed on separate thread so they do not block the rendering of the UI, When the task is finished it can sync back to the FX thread by calling FX.deferAction() which will simply execute the code on the main thread.
This won't be the most helpful answer as I have toyed around with JavaFX for all of half a day, but wouldn't you use Timelines, Keyframes, and binding to accomplish your repaints instead of calling them explicitly like you have described?
See this tutorial for an example.
JavaFX's model is to separate you from the painting of the "stuff" on the screen. This is very powerful but is a change from how you might be familiar with.
whaley is correct that the appropriate way of doing this in JavaFX is to make a timeline where the move is done every X seconds and will be drawn at that keyframe.
If you have a question about how to do this, try it and make a new question with some code.

Resources