Common ui base for dialogs in Qt - c++

In Qt widget application, I'd like to have a common base view for all my dialogs, so that I could inherit other classes from it.
This "base/common" view would contain initially a set of buttons at the bottom and a custom frame with data at the top. A place in the middle would be used by derived classes for placing view-specific contents. If the common dialog style changes in the future, changes will be applied in one class only.
Is there any way to use such approach in Qt, since ui files are processed with 'uic' to create classes? Ideally would be to not to lose the ability of using the gui designer, at least for the derived classes.
Any hints much appreciated.

You can make your "base view" as its own ui file with a big QFrame in the middle with nothing in it and name it contentsFrame. Then create your other widgets you want to place inside the empty contentsFrame in designer.
Now you have a couple options. You can have both open side by side in designer, click on your contents widget, select all, and drag everything to your contentsFrame. Then just hit save as and save it as a different widget. If you aren't afraid to leave designer for a tiny bit, you can add your contents widget to the base widget in code. Either way, make sure you are setting the layout for your contentsFrame or everything will look like garbage.

Related

Qt: How can I use my widgets created with code in the *.ui file

I have a project in Qt made with the QWizard and QWizardPage classes. There are two ways to create a widget i.e: a Label:
One is going to the *.ui file and search the element and put it where you want (visual way). Then you can access it on your code with ui->nameOfLabel.
The other one is going to your code and creating it like QLabel codedLabel;
Actually I'm using the second way (it's easier for me to create, show and use) but my question is: Is there any way that I can see my label codedLabel on the *.ui file?
I would like to move it to a space in the screen and in that case, it would be much easier for me to be able to do it through the visual way (but having the label created in the code instead of the ui).
Thank you so much.
Widgets created at runtime from your source code and being added to a widget as child CANNOT be seen in Qt Designer when you edit the .ui file of the widget they will be added to.
However, there could be an alternative (reading what you are trying to achieve: having some child widgets being present or not based on the context):
Create the widget from the .ui within Qt Designer and hide it (QWidget::hide()) or even remove it (QLayout::removeWidget()) programmatically if not needed at runtime.
If the real reason why you want to see it is because you want to "move it to a space in the screen and in that case, it would be much easier for me to be able to do it through the visual way". Then I recommend that you simply create an empty QWidget (or QLayout) in Qt Designer (graphically: easy to place where you want to) and later (programmatically) add your QLabel to it (rather than adding it to the main top-level widget): then, it goes in the place you determined from Qt Designer tool.
You should not need any complex code to programmatically display your QLabel in a specific place, just choose the right parent to have it be displayed in the right place!

Design issue: apply specific treatment to a subclass only manipulating the superclass

I am working in a project where I have a design issue that I don't know how to solve. I would like to find the best solution for extensibility of the code.
The project consists in a web browser with tabs, but in the tabs there are not only webpages, I can have other kinds of widgets.
I am using Qt, and so the widget in the tabs are QWidgets (QWebview and other types that I still have to code myself). Anyway, I'm going to try to keep this question generic enough.
There is a class QWidget from which 2 classes inherit: QWebView and MyWidget.
I have a container (QTabWidget) that can contain both of them, since it can contain QWidgets.
Moreover, I have a button (the previous page button, for instance), that only applies to one kind of QWidget: QWebView.
So, when I press this button, I ask the QTabWidget for the current QWidget and if its a QWebView I do something, otherwise I don't do anything.
That is the problem: I need to be able to distinguish between the two different types: if I ask the QTabWidget to give me the currentWidget, it gives me a QWidget*, but I don't know whether its a QWwbView or a MyWidget and so I have to doa nasty dynamic_cast<> to check the real type.
This means that if I add a new MyWidget2 with another action, I will have to update all my code where there are dynamic_cast<>, and I don't want that.
I have been thinking of command pattern and startegy pattern but I don't think they applu realy well.
Do you have any advise?
Thanks
At an abstract level, it sounds like you need some way of mapping the various widget types to the actions (e.g. "go to previous page") that they can support - that way, when you add a new widget type, you specify its actions as well. Depending on the currently-viewed tab, you can then enable/disable the relevant actions, so that when the user is able to perform an action you know that it will work for the type of tab currently being viewed.
One way of doing this would be to add a virtual member function to your base widget type that returns the relevant actions. You then cast the QWidgets returned by the tab widget to your base widget type. This still involves a cast (because QTabWidget isn't geared up to return widgets of your base widget type), but it gets rid of the maintainability problem when you add new types of widget.

Creating tabbed document interfaces in Qt Designer?

I am trying to write a program that will use a tabbed document interface (TDI) like seen in Notepad++ or most web browsers. I know how to build GUIs using Qt Designer, and code in Qt C++ (after a few days of playing around).
I have created an example of what each page widget will look like using Designer, and now I want to add the ability to create and testroy tabs at runtime, each containing a unique instance of the page widget. However, I have no idea how to do this without adding a class that extends QWidget, and building the page widget with code. I could go down this route, but I'm sure there must be a better way of creating a TDI; but I can't find any tutorials or examples of how to do this.
Does anyone have any suggestions?
For creating tab interfaces you should look into QTabWidget.
It is a container widget included in Qt Designer which automatically handles operations on tabs. It has several build in methods for manipulating its tabs and theirs contents.
Each page of QTabWidget is handled separately and can have different layouts and functionality.
If you want to include several different objects to one page assign a layout to it and then assign the objects to the layout.

Making a game in Qt regarding GUI windows

I've been wanting to program a simple game with a simple GUI using Qt (Its will be a VERY simple game, nothing fancy). What I've been wondering is, how can I create multiple windows and display them when needed? For an example, a battle screen and an inventory screen. The user should only see one of them, but should be able to access the other one when needed. I was using stacked widget but I'm not sure if that's the proper way. Also, is it better to design the windows in the designer or to code them?
A StackWidget certainly would accomplish what you want to do. The reason why it is not always used for this kind of thing, is that it all the screens are pre-created at the beginning and always exist. This means it takes a little longer to initialize, and you are using more resources than you need at any one time
But as you are saying, if this is a simple game, then I don't see a big problem with it. Just as easily, you could also, create an empty layout and swap the inventory and game panels as needed.
Add my vote to everyone else suggesting to use the designer. It is so much easier to manipulate layouts, actions, and such using the designer then through code.
You can see the Designer manual here
So this is what I would suggest:
Create your "battleScreen.ui" - which is the designer file for your battle screen and everything in it, and then create your "inventory.ui". Both of these could be QWidgets, or QFrames, or whatever makes sense.
Then create your "Game.ui" which will be your QMainWindow.
In your Game main window, you can then add your QStackWidget, and place your inventory, and battle screens in the stack widget.
If you don't know how to do that...
1) drag a QWidget into your form (into the stack widget)
2) select the new QWidget and right-click.
3) Select "Promote to..."
4) Fill out the information to promote the QWidget to your inventory class
Promoted Class Name: The name of your inventory class
Header File: The header file of your inventory class
5) Click add
6) Click Promote.
Hope that helps.
Since I'm not sure what your goals are I can't advise whether or not the stacked widget is appropriate but I think you can accomplish quite a lot using the designer and style sheets. If you need to code some parts of the GUI, you can always drop in a place holder widget and either replace it with coded items or make them children of the place holders.
A general answer for a general question:
Use the Designer to create your windows; hide and show the auxiliary windows as needed.
Use a flow manager class to manage the visibility of a related set of windows.
The stacked widget is useful for managing a button/icon whose appearance changes based on state; the different representations live in the stack.

Extract a portion of a Qt .ui file into its own .ui file

We have a designer creating a user interface for an application. The main window has several QStackedWidgets used for in place panel switching. What I'd like to be able to do is extract each individual panel that makes up each page of the QStackedWidget into it its own .ui file.
Is there an easy way to accomplish this from within Qt Designer, or are there any other tools to help accomplish this task short of redesigning all of the panels in their own .ui files?
You can cut/paste each panel into a blank QWidget (created with File > New), and save these widgets in their own .ui file.
When you copy a widget(lets call it widgetA) that contains other widgets(calling them miniWidgets) then the miniWidgets should still be layed out. WidgetA still needs a relayout and in that case its very easy to add a layout since you can practically use any layout you want (i suggest vertical or horizontal). Just right click on the widget containing widgetA then select Layout->horizontal Layout and that should do the trick.
If there is more than one widget than needs relayout then you are not copying the panel correctly and should copy one that englobes more of the panel.