I have the following situations where I would like to display some widgets.
My main windows is mostly a text editor.
I have an action called 'Run', which interprets the text and does something.
One of the possible results is that a window needs to be opened.
It works, but the window is only displayed after the run function (which I have as a slot)returns.
Another situation I have to open a window is that I want to be abe to same interpreter to run from console input.
But opening the window in this case results in errors like:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is Oxygen::WidgetStateEngine(0xee2d90), parent's thread is QThread(0xda53b0), current thread is QThread(0x7f2178004000)
QObject::installEventFilter(): Cannot filter events for objects in a different thread.
What can I do to somehow 'centralize' window operations so that this does not happen ?
All GUI objects are to be created within your main thread. You can get access to QMainWindow instance from any place in your code using static method QApplication::topLevelWidgets()
Related
OK, so a noob question here: How do you code this functionality that browsers have for example? You open a chrome browser for example and you can open multiple tabs open. Then you can move one tab out of the window and it becomes another window, having its own separate process. Then you can drag that tab into another window and they become one frame? Similar to docking in windows applications, but how do you do it with executables?
Windows-specific answer, though I think other OSs work pretty much the same: the HWND handle that you get for a window is global. If you send its numeric value to a different process, that process can use it to do things with the window: get its information, resize it, even draw on it. What it can't do is replace its event handler function.
To get process separation like browsers have nowadays, the key is to create a container window and send the handle to the child. The child then creates its own window as a child of the container. The child window simply fills out the entire content area of the container.
This way, the content process is contained within the parent's window, but can handle events.
Now, if you want to drag out a tab into its own top-level window, the parent process creates a new top-level window with all the UI inside, and then re-parents the content container to this new top-level window. The content child follows along.
I can't tell you how to code it, you should search the feature inside the chromium code to know how it's coded but I can tell you how it works:
Inside chromium every tab, extension, utility, etc is a process, each one of these processes is child of the "Browser" process, the "Browser" process manages everything (creating new windows, opening new tabs, closing tabs, destroying windows etc) so, for example, whenever you open a new instance of chromium you are telling the "Browser" process to create a new tab and put it inside a new window.
Every window is managed by the "Browser" process and every tab is managed by a process that is child of the main process.
Now to reply your question: when you drag & drop a tab outside a window you're triggering an event that is caught by the "Browser" process which then create a new window and assign the tab to the new window.
Those informations should give you a hint on how you could develop this feature yourself.
If you want to know more about the chromium architecture I suggest you to read how chromium is designed at https://www.chromium.org/developers/design-documents
I have dialog box and in it, it has OK and Cancel buttons then it also has a ListBox to display text in two columns. I would like to continue adding text into the ListBox after the dialog box is shown. How can I do that? Because after I call DoModal() to show the dialog box, the code does not continue to execute. Or should I create two threads (one is display dialog box while another thread continues adding text to dialog box)?
Make your dialog 'pull' the data it needs, maybe polling the data source with window messages every second, or every 100ms or so. Or, if you go the 'two threads' route (the better but more complicated option), have your data source post a window message to your dialog when there is new data, and then have the dialog fetch the data it needs. The reason for this is that it's much easier to use the existing CDialog infrastructure to get a window that behaves like an actual dialog, compared to building a modal window that acts like a dialog but isn't really.
If you do go the two threads route, your division of labor should be: one thread that does all the UI work (including showing the dialog), and one that 'generates' data and lets the UI know when there is new data. So the worker thread should not do anything related to the UI, nor call any methods on the dialog directly - you can't access windows from several threads. The only cross-thread window communication should happen through window message (i.e., use ::SendMessage()). So certainly don't do something like myDialog->m_theList.AddString("blah") from another thread, or something like it.
Showing a dialog box modally halts further execution until you close the box. Instead of showing it modal, show it normal but make it always on top so you can continue executing the code after the call to DoModal(). Alternatively, populate the box with all the info it will need before you call DoModal().
If you decide to take the "two threads" approach you will discover that the controls on MFC dialogs should not be updated or accessed from a thread other than the one that created the dialog. Even if you have pointers to these controls available in another thread it is not thread-safe to access them. This rule applies whether or not the dialog is modal.
Instead, your second thread would need to PostMessage or SendMessage to the dialog window, so the updates occur on the thread that created the dialog (most likely the main UI thread of the application).
I'm using this code to get the child windows of all open processes.
The code itself is working correctly, I get a 2 dimensional list of handles. Each index has a list of handles to the child windows of a specific process.
I'm trying to get a child window of a game. The game itself is inside window. It appears in the task manager and in my task bar. There is a button inside the game I press that opens a new window. The new window does not appear in the task manager but it does appear on the task bar.
The problem is the code in the link above will not return any child windows for the game even though a new window has opened and it can be seen in the task bar.
Any Ideas what I could be doing wrong?
Ok found the solution, should have used GetWindowText instead.
What is the best way to communicate between two windows in Qt?
I need to have a separate login window and main application window which appears one after another (the second one, I mean main application window, will show only if the login was successful). Should I create these two objects (login window and main application objects) in the main function or make login window data member of the main application class and create it in the constructor of the main application class?
You can create login window as a data member of the main application class and create it in its constructor. Next you can invoke login by connecting a signal named login_
asked() of the main class to a slot named perform_login() and emitting the signal after that:
QObject::connect(this,SIGNAL(login_asked()),this,SLOT(perform_login())
,Qt::QueuedConnection);
emit login_asked();
You should hide your main window in the perform_login() slot and show your login form like:
this->setVisible(false);
loginfm->show();
You can notify your main application of the failure or success in login by signals and slots like:
QObject::connect(loginfm,SIGNAL(login_accepted()),this,SLOT(entered()));
QObject::connect(loginfm,SIGNAL(login_canceled()),this,SLOT(canceled()));
In the the slot entered() of your main window you should show the main window:
this->setVisible(true);
This way you can invoke login as many as you like during the application life cycle by just emiting the login_asked() signal.
The login window should be a QDialog-derived window. This has accepted and rejected signals, which you can trivially handle in your main window. (This answers the question in the title)
It doesn't matter very much where you create them, that's really a style issue. I'd probably put it in main myself, but if I took over an existing codebase I wouldn't bother changing such details.
Multiple processes rendering to one window
Two processes, two windows, but one window acts as another window's child window.
For example a window contain a edit ctrl, but the edit ctrl is belong to another process.
How can I implement such a MFC application?
I don't think having more than one thread managing UI stuff is a good idea at all.
You should just have one thread in charge of the UI (main thread) and create as many working threads as you need. But these working threads do not access UI directly but they notify (SendMessage / PostMessage) the main thread to do the UI work.
The window and its child must belong to the same process. Period.
What you can do is redirect the output of a process (such as stdout) to a pipe. The GUI process in turns reads the pipe and display the contents into the dedicated child window (edit box or other).
This MSDN article about input/output redirection may help.
Actually you can achieve this, but has some limitation.
For example, you can embed MS word in your app. The Word window is embedded as a child window in your app. but actually, there is another process winword.exe.
Your app works as compound document container and the embedded one act as compound document server.
Please find "compound document" related stuff from MSDN.