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

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(....

Related

Qt Creator - GUI from designer vs. GUI from code - how to access element's functions

I am confused about some Qt architecture.
When I am designing the GUI in Qt Designer it is easy to put the elements in a layout (Grid, Box, what ever) and create a slot to connect elements (e.g. buttons) with a certain and action not much code in .cpp file.
In the related .cpp file I can access theses elements via ui->element->do_something even from different functions within the class;
When not using the designer, instead creating the whole GUI stuff within the .cpp (adding element objects, add those objects to a layout, creating a slot, etc...) I cannot access my e.g. Button like ui->Button->do_something.
I am stuck at ui->Layout->functions from layout and cannot access the single elements and their functions like ui->textEdit->text(); or like ui->Layout->textEdit->text() from other functions within the class.
So how can I access those elements?
I am afraid I am missing an important point of Qt's architecture here or something else.
When you use designer, an "Ui" file is auto-generated with the code of your layout, then you access through the Ui::Mainwindow which you can see auto-generated in your QMainWindow class.
You can see in the default constructor:
QMainWindow(parent), ui(new Ui::MainWindow)
So each component defined in the gui file is accessible through ui::nameofyourcomponent.
If you write the code manually you don't have any "access point" to your element so you have to build your hierarchy exactly like each other part of your code and classes.
Edit: A little snippet to answer to his comment.
In you header you can declare:
private slots:
void doSomething();
private:
QPushButton* mybutton;
QLabel* mylabel;
in your Cpp:
connect(myButton, SIGNAL(clicked()), this, SLOT(doSomething) );
MyClass::doSomething()
{
mylabel->setText("hello button!");
}
Of course you can use the connect chaining directly the components through their signal and slot.
All of the objects the designer creates are public members of the ui object, that's why you can use them. To be able to use a manually created object, you have to store a pointer or reference to it somewhere.

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 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.

Floating/Embedded QDockWidget in a QWidget (KXmlGuiWindow's CentralWidget designed in QT Designer)

I'm just trying to get into QT (and KDE) program, and have hit a snag trying to add a floatable, draggable QDockWidget to the .ui file (based as a QWidget) that is embedded into my KDE 4 program.
This is all from the basic template provided by KDevelop 4, so while I understand what's going on, I just don't know the best way to change it.
Here's the deal: main.cpp spawns a new AEmpire window, which starts the whole show off:
AEmpire::AEmpire()
: KXmlGuiWindow(),
m_view(new AEmpireView(this)),
m_printer(0)
{
// tell the KXmlGuiWindow that this is indeed the main widget
setCentralWidget(m_view);
setupActions();
setupGUI();
}
When a new AEmpireView(this) is created (which inherits from QWidget) and is assigned to m_view, this constructor is called:
AEmpireView::AEmpireView(QWidget *)
{
ui_aempireview_base.setupUi(this);
settingsChanged();
setAutoFillBackground(true);
}
So, when I am editing the ui to my program in QT Designer, I'm actually editing the AEmpireView_base ui file, which is a QWidget. It just represents the main view of the KXmlGuiWindow (derived from QMainWindow) and is loaded at runtime.
So, how do I add floatable, draggable QDockWidgets into my main application? Is designing them separately, and add them to the UI the best option? Or maybe removing the entire AEmpireView class, and making my ui file directly represent a KXmlGuiWindow object to be loaded by the AEmpireClass?
Or am I totally overlooking something obvious? Thanks for reading!
I would design the QDockWidget contents as separate UI files. Then create them and stick them into the QDockWidgets in the AEmpire constructor.