QMainWindow and docks positioning - c++

I use C++, Qt 4.8.7 for creating GUI application under Windows. I have additional main window as a tab (see an image below). A, B, C, D are dockable widgets. How can I put B widget on the top of C widget? I was able to do it via mouse, but I'd like to do it programmatically. I don't want to have tabified docks.
BTW, do I have to create a dummy zero-sized central widget? Are dockable widgets more stable in Qt 5.x? Moving docks within my mainwindow is not comfortable (I've created empty small central widget).

Related

QT How to embed an application into QT widget which is a background-transparent widget that runs behind the main QT widget?

There is a 2 overlapping widgets (A and B widgets) and they are fully screen in the designer. I want to embed an application to the widget A which has a widget stack order lower than the widget B. So, I want to run the exe in A widget as a background transparent widget of the B widget. How can I achieve that ?
On Windows, you can try to look into QWinHost. It can take the process ID of the exe, and embed its window into its own widget.

How to create QSplitter ui class via qt designer?

I am new to Qt and I need to implement a monitoring interface with the following considerations:
I have a main window, on which I should put multiple screens, qsplitter appears to be the best solution.
The interface provides user with the option of changing the number of cameras, so QSplitter should be created/re-created during run time.
The problem is that I have too many cameras to pre-define widgets for them, so I need to create QSplitter UI instances dynamically.
The problem is that I can't find QSplitter classes when using Qt Designer and creating QSplitter class programatically is not working as MainWindow has been created through Qt Designer (.ui).
I would like to hear any suggestions regarding this issue, if there are better approaches, please let me know.
In Qt Designer, the QSplitter is not a widget, but a Layout.
Select the widgets you want to include in the two splitter areas, then select Layout from the context menu (right mouse button) - you will find two entries Layout Horizontally in splitter and Layout Vertically in splitter to group the widgets in a vertical or in a horizontal splitter.
QSplitter isn't a strict UI element, it's essentially a parent element that controls child elements. If you want to do it through Designer you'd probably run into headaches, but the basic gist is you select a number of widgets to be controlled by it, and click the Layout Horizontally/Vertically in splitter button which is in the layout buttons group.
What you might be best doing is creating your child elements programmatically, creating your splitter programmatically, adding the child widgets with someSplitter->addWidget(...). In the Qt docs there's some sample code for this:
QSplitter *splitter = new QSplitter(parent);
QListView *listview = new QListView;
QTreeView *treeview = new QTreeView;
QTextEdit *textedit = new QTextEdit;
splitter->addWidget(listview);
splitter->addWidget(treeview);
splitter->addWidget(textedit);
http://doc.qt.io/qt-5/qsplitter.html#details
And if you really want to do it in Designer there's a guide here: http://www.bogotobogo.com/Qt/Qt5_Splitter.php
Although QSplitter is a widget, you can't create one directly in Qt Designer. It is only available for laying out pre-existing widgets - which does not fit your use-case, since you need to create child widgets dynamically.
However, you can work around this limitation by using widget promotion. This is a simple mechanism that allows you to add substitute classes to represent widgets that are not directly available in Qt Designer. The idea is that you add a widget that is most similar to the one you actually want (e.g. a QFrame is most similar to QSplitter) and then promote that to the substitute class which you have defined in your own header file. When uic finally generates the code, it will use your substitute class instead of the class of the widget added in Qt Designer (which just acts as a placeholder).
Note that when you create your substitute class in the Promoted Widgets dialog, the base class should be a QFrame, not a QSplitter. This is because you are extending a QFrame (i.e. your placeholder widget), rather than a QSplitter. Of course, you can define your substitute class to be anything you like.
Image is easier to understand.

Qt/C++ Technique To Show Inline Dialog

I have QtCreator 5.5 for the Mac, using C++, and I'm new at this. I have a MainForm window. I want to show a dialog inside that but draw it separately in its own UI designer. Then, at runtime, my code will pull that other UI and show it inside that window.
Imagine for instance a main application window. You click a button and you need to see a confirmation dialog. Normally you could do that with a separate window. Instead, I want it to be inline at runtime, to show it like a widget on the main window.
Sure, I could draw my dialog on top my existing window in a widget, but that defeats the point where I want to be able to adjust it in its own designer window, and just load it as necessary in the main window when I need it.
What's the technique in QtCreator and C++ to do this?
Open QtCreator. This task can only be done through there.
Assuming you have a regular Qt Widget Application, you need to just add a QWidget control on the MainWindow's centralWidget in the UI Designer.
Next, click Edit in the UI Designer and then rightclick Forms. Choose Add New...
In the dialog that opens up, choose Qt > Qt Designer Form Class, and click Choose...
Select Widget and then go with the defaults on the rest. This creates a widget called Form, and the form.h and form.cpp will also be added to your project.
Now find the form.ui and open it in Qt Designer. Add a Stacked Widget Control on the QWidget form. Size it to the same size as the parent widget. Next, stick a Label Control on the Stacked Widget Control's first page. This label will be temporary just to prove that this works. You'll set it to the text of "Testing". Now close the designer.
Flipping back to your UI File of your Main Window, find that QWidget you added and rightclick it. Choose Promote... and a dialog box appears. In that dialog, set Promoted Class Name to Form and then set Header File to form.h. Leave everything else on defaults and click Add and then Promote.
You may be expecting to see an immediate change in your Main Window in that QWidget that you added previously. However, that's not how this works unfortunately. You only see the change at runtime. So, now you should Run your application in Qt Creator. You'll see when it runs that your widget now contains the contents of that form.ui component you created.
Now, here's where it gets interesting. You can now draw all your inline modal dialogs on that form.ui, just putting them on different pages of your Stacked Widget control. You can also set the properties of your widget so that the background of the QWidget container is opaque and dark (creating a background dimmer) and then, at runtime, resize the QWidget to the size of your Main Window. When you need to switch to a different dialog, you can use setCurrentWidget() or setCurrentIndex() on that StackedWidget item like so:
QStackedWidget *w = ui->widget->findChild<QStackedWidget *>("stackedWidget");
w->setCurrentIndex(1);
In that example, I had a QWidget control on my MainWindow named simply widget. I then found the control on it called stackedWidget. Once I had it, I used the setCurrentIndex(x) method on it to change the page of that widget to show the one I needed. Remember that this is a zero-based index. So, (1) would be page 2.
QMainWindow::setCentralWidget
Inside your QMainWindow constructor add:
MyDialogClass myDialog = new MyDialogClass();
setCentralWidget(myDialog);

How to manage QSplitter in Qt Designer

When I press a button, I bring up a dialog where user select things and press 'Ok' at the end. I want a splitter in this dialog. Left pane will show tree and right will show something else. How do I do that right?
From Qt example itself:
QSplitter *splitter = new QSplitter(parent);
QListView *listview = new QListView;
QTreeView *treeview = new QTreeView;
QTextEdit *textedit = new QTextEdit;
splitter->addWidget(listview);
splitter->addWidget(treeview);
splitter->addWidget(textedit);
So in this example, splitter is created without any dialog resource. If I have to create this way, that would mean I have to create all my controls in the code as well rather than Qt Creator.
What is the right way to do this when I need other controls on the screen?
You can simply create splitter containing items in Qt Designer :
First place your widgets on your dialog or widget in designer (They should not be in a layout)
Select the widgets that you want to be in a splitter (By holding CTL and clicking on them)
Right click on a selected widget and from Layout menu select Lay Out Horizontally in Splitter or Lay Out Vertically in Splitter.
Now apply a grid layout to the dialog and everything should be OK. You would see something like this in Object Inspector View :
Okay, I know this is ancient, but here's the complete answer.
First, within some sort of widget container, plop your pieces in. For the window I just did, I have a Widget as my window. I put two widgets inside that labeled something like topContainer and bottomContainer. I then put all the widgets they each need into them, and gave them their own layouts.
Then do NOT select the main container. Select the two widgets you want to split. You're in effect putting a splitter on them, not on the main container. So I went to the widget list window and selected both together, then right-click for the dialog window, scroll down to the Layout option, and "Lay Out Vertically in a Splitter" is NOT greyed out. Select it.
You still need a layout on the main container. A splitter is not a layout. So at that point, I just put a vertical layout on the main container.
To repeat: you are NOT setting a layout on the container holding the pieces you're trying to split. You are selecting the two widgets to split and adding a QSplitter around them. That's the trick to get it to work.
You can still create your controls in a .ui file using Qt Designer (integrated in Qt Creator). Within Qt Designer, add a QWidget object to your dialog. Then, from QDialog derived class you'll write, directly in your constructor, create your QSplitter using the QWidget object as a parent.
This way, you can create all but the splitter object from Qt Designer.
I think it's also possible to create the QSplitter (as you can create a QButton, QCheckBox...) item directly from Qt Designer.

Window Templates in Qt (Or basically object oriented Windows)

So, I have a bunch of windows I want to create, each different, but has similar properties. For simplicity, lets just say I want a row of buttons along the bottom (the actual buttons differ for each window, but they should be in the same configuration). Then in the top half of the window, I want it to very based on what window is open.
In short, I would like to have window A which has the template of a window with buttons at the bottom. And then button B which instantiates the buttons, and has it's own thing at the top, and window C which has it's own set of buttons, and thing on the top, which is completely different than B.
Is there any way I can do this in Qt? Also would it be possible to just have one window A, and have it change back and forth between the configuration in B and C when appropriate?
Yes, it can be done with Qt. You can create the widgets dynamically. Design each window as a separate QWidget which will contain other widgets (the buttons, for example). The mainwindow will then contain a simple boxlayout and one of these window widgets created dynamically. When the required window type changes, delete the current window widget and create another one.
Another option would be to put all widgets needed by windows A, B and C to same the window. When the window A is needed, show widgets belonging to it and hide the others.
Actually, if you know anything about QTab, then it works exactly the way you're describing, except it adds a set of tabs at the top which is probably not wanted here.
But anyway... create a QMainWindow inside which you create 3 widgets (A, B, and C). Hide B and C when using A. Then hide A and C when using B, etc.
This is similar to what Roku was proposing, but he had a somewhat different tree organization as he would only show one window and change the widgets in that larger window. Having 3 widgets that cover the entire window and switching between them is probably easier to manage as you in effect have to change only 2 of them when switching from one to the other.