Splitting Qt forms between multiple ui files - c++

I have a main window UI file created in Qt Designer. To avoid clutter and make the code more modular I'd like to create some parts of this window in separate ui files.
For example I may have a tab widget on the main window and then I'd like to have separate page1.ui and page2.ui which I can then "embed" inside the main window.
Is it possible with just UI files or do I need to create a class for each additional widget?
I was thinking about creating separate classes Page1UI and Page2UI which publicly inherit from ui_page1.h and ui_page2.h generated by qmake (so that the widgets inside them can be easily accessed from the main window) and then promoting main window's placeholder widgets to those classes. So in code I'd have something like this for example:
connect (page1->ui->someButtonFromPage1uiFile, ..., this->ui->someMainWindowWidget, ...);
However Qt documentation doesn't seem to mention public inheritance so I wonder if this is the right approach or if there may be a simpler way.

You don't need inheritance for this. These UI files are just widgets. So of course you can do this. You should have a main class which will have a tab widget and then just add your page1, page2, etc in main tab widget. What you need is composition here in my opinion.
What you need to do is create a separate class derived from QWidget which will contain an object of your generated UI form. You need to call setupUI() of that generated form in your new class with this as parameter.

Related

Qt5 Designer and Encapsulation

I've created a main window in Qt Desginer which has the following structure
Ui_MainWindow
VerticalLayout
QTabWidget
Widget (*A)
QChart
QChart
The uic generates a header file "ui_mainwindow.h". This header files contains references on all the sub (subsub, subsubsub, ...) widgets. In my point of view this isn't good encapsulation.
I found a way to set custom classes for the different widgets in the Qt Designer.
Since I have to write these classes manually I have no access/references to the child widgets. I only can control the widget itself. Still all widgets are referenced in the MainWindow UI.
Is there a way to generate separate classes for each (or some selected) widget? I'd like to intercept *A and access the child QCharts.
Thank you,
Even though you can already "intercept A" in the current form. You can certainly separate A in a different section then add a QWidget in your main window, right click on it and promote it to being A

Connecting multiple .ui files in Qt

I have a window(.ui file) and at certain point i want to erase everything inside of it and repaint a new interface by connecting a new .ui file to that class without creating seperate class. Is there a way to do it?
The task sounds like a good job for QStackedWidget. With its help you can design different widgets (aka "pages") conveniently in the designer, and switch between them inside your code using setCurrentIndex() and/or setCurrentPage().

Custom class in qt creator

I'm new to Qt and fairly new to C++ but I need help with this issue.
I have a custom class called HybridStack and I want it to extend a QStackedWidget and a QMainWindow.
I want it to extend a QStackedWidget so that I can use as many pages as I need and I want it to extend a QMainWindow so that I could be able to make each page have it's own MenuBar with different content of menu for different page.
I want to add this custom class HybridStack to Qt Designer by
promoting it from a QStackedWidget.
Is this possible? If it is, can you brief me on how to do this? If it's not possible then what's an alternative? Most importantly, I need to use it in the Designer because I need to use qmake
You can't derive from both QStackedWidget and QMainWindow, because both of those are in turn derived from QWidget. If you did so, you'd end up with the Dreaded Diamond. You'll have to use composition instead.
Even then, I'm not sure if it would work correctly to put a QMainWindow within a QStackedWidget, since it is designed to be a top-level item (i.e. its shown directly as a window, not embedded within another QWidget). Another way of accomplishing what you want (menu bar changing when the you change tabs) would be the following:
Make your top-level item a QMainWindow
Make the central widget a custom widget derived from QStackedWidget
When the item showing in the stack widget changes, you can call QMainWindow::setMenuBar to change the menu bar. Each widget within the QStackWidget could have its own QMenuBar instance that it uses for this purpose.

Refactoring / partitioning of Qt GUI widget source file

I have created a traditional Qt (widget based) GUI, something like this: MainWindow::MainWindow(parent) : QMainWindow(parent)
This is designed by Qt Creator as forms (mainwindow.ui), aka Design Mode. Everything works fine. But the GUI code with all widgets, initializing the corresponding models, and functionality gets quit long. I'd like to refactor to small units. Things I came up with:
I tried using specialized (derived) widgets. Example: A created MyTableView::QTableView contains the specialized model, as well the signal/slot handling between model and widget. This reduces the amount of code in MainWindow. However, I do loose the capability to design the GUI via Qt Creator's Design mode.
The best thing I came up with so far, was to spilt the source code (multiple cpp files). It still represents one class, but less code in one file.
So, how could I better partition my GUI class?
If you still want to uncouple the initialization of widgets by derived widgets, you can use "promote to ..." option in Qt designer. Steps:
class MyTableView : public QTableView {}, and so initialization of table view is moved to the constructor of MyTableView.
In Qt Designer, open the ui form (MainWidow.ui), and drag and drop a QTableView on it;
Right mouse click the QTableView, in prompt menu, there's a "promote to" option, open it
In the dialog of "promoting widget", specify your custom QTableView's class name and header file, say MyTableView, MyTableView.h. This step requires existing custom class and header file.
Borrowed a picture:
You could create your own Qt widgets and register them with QtDesigner. Then will you be able to use them on forms as mere QLabels and friends. See this link
In a recent project, we had pretty restrictive uncoupling requirements (especially not to be too strongly linked to Qt). What we used to do based on MVC-like pattern is:
Implement a controller that controls the application workflow
Add a GUI "adapter" class per screen that communicates with the controller. Let's say HomeScreen class, SecondScreen class
Each adapter class contains a given number of widgets: TimelineWidget, FormWidget
Each widget is composed of a ui member (Ui::TimelineWidget ui) that is generated from a .ui file designd with Qt designer
Note that this structure might not be suitable for small projects.

How to access Child UI files

How can i access ui files of children of a class. Lets say MainWindow class has twoa child dialog. I want to access LINEEDIT of dialog so that i can take text from there. Similarly how can i access ui files of parent inside child class in QT.
Note:
I havn't inherited any thing from Parent class.
I suggest you read the beginner tutorials of Qt. The ui files just carry XML that the uic can read to turn into 'real' C++ for the compiler. If you need to send data between decoupled UI components, use Signals/Slots - a fundamental building block in the Qt framework.