Custom class in qt creator - c++

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.

Related

Qt equivalence to controllers in C# or generalization of gui elements

In C# there are controllers which takes a GUI element and everything in it to be able to use in multiple places at the same time, does Qt have the same thing?
In my case I have various Groupboxes with with textEdits which I need to fill depending on some options. Currently I tried a QStackedWidget but the contents cant have the same objectname so it I cant fill the textEdits as easily.
How should I go about to generalize it?
in qt the same, you can always "move" widgets from one layout to another,
and if you are using qt creator, then widgets in editor are inserted in the ui so you can always have access to them by its name..
for example:
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
you will have some private member Ui::MainWindow* ui{nullptr}; and there you can get the labels you inserted in the main window doing:
ui->myLabel->setText(.....
or
ui->myButton->setEnable(....

Qt 5.10 - How to add a chart example to a layout

It's my very first experience with Qt so i hope its a basic question with a basic answer I couldn't find. I need to add a "custom" chart widget
(like in the following example: https://doc.qt.io/qt-5.10/qtcharts-zoomlinechart-example.html)
to some Qt container like "layout" or "form". Its very straightforward when you have the widget in the toolbox and you use the designer but since it is a custom widget i cannot do that.
How do you do this in Qt creator?
If your Chart class inherits from QWidget, you have two ways to do this:
In the Design mode, put a QWidget on your Window, or into a Layout. Then, right click on it and select "Promote to ...". There, write your class name in "Promoted class name".
In your window cpp file, write:
YourChartClass* ycc = new YourChartClass(this);
ycc.show();
or
YourChartClass* ycc = new YourChartClass();
this->layout()->addWidget(ycc)
If your chart inherits from another class, and that class inherits from QWidget, the code lines are the same.

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

Custom menu actions in Qt Designer

I'm currently trying to use Qt Designer to build a GUI and I would like to customize slots of my menu actions.
E-g: I'd like the user to press a menu action and it'd show a widget if it is hidden or hide it if it is already visible.
Basically, what I want to do is execute some code of mine and not the default actions such as show() or hide().
So I'm wondering if I should create a subclass of QMenuBar, add custom slots to it, then create a plugin to use it inside Qt Designer or if I should create a subclass for QMenu or QAction ? Or maybe it isn't the right way to do that ?
I'm working under Visual Studio and I'm only using Qt Designer, not Qt creator.
I'm new to GUI and Qt programming and I'm a bit lost here.
Thanks in advance :)
You have basically 2 options:
Implement the custom logic in the Mainwindow sublcass.
For this, you simply add the slots required for your handling in the class, and make them available in Qt Designer. You can do this:
either in the Signal/Slot editor and click "Modify" and then click on the + Symbol. By this you make new slots available in QtDesigner;
or when your slot is called on_(senderName)_(signalName), Qt autowiring will automatically connect the signals, and you don't have to do this in code or desinger.
Create a QMenuBar subclass and implement the custom logic there.
Your case tell Qt Designer to select your specific subclass as replacement for the default QMenuBar by right-clicking on it, and select "Promote to...". In the new dialog, you can specify your custom class that will be used as replacement in actual code, but in design time a QMenuBar is used. With this mehtod, you don't have to write a separate plugin to make your class available in Qt Designer.
Note that with the second option, your custom logic will only be called when the actions are triggered through the menu bar, not by shortcuts or tool buttons
Create a slot in your class:
onMenuActionTriggered()
Use the connect() to react on action's signal:
connect(ui.myAction, SIGNAL(triggered()), this, SLOT(onMenuActionTriggered()));
In your slot you can do whatever you want.
Another solution (not my favourite one, but possible) is to use the auto-connect functionality, which means, by declaring a slot 'on_myAction_triggered()' (where myAction is the name of your QAction) you don't need to use the connect() since it is automatically connected by Qt
The menu bar is automatically added to any new form derived from QMainWindow (the default when creating a gui application, but you can create new main windows using file->new file or project... and selecting Qt->Qt Designer Form Class ).
To add options to it you simply click in the area labeled "Type here" and write your option text. When you do so an action will appear in a list in the lower part of Qt Designer. Right click on that action and select "go to slot". It will pop up a dialog with "triggered()" already selected for you. Simply click "Ok" and Qt Creator will take care of all the details and transport you to the body of the slot function.

Splitting Qt forms between multiple ui files

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.