Refactoring / partitioning of Qt GUI widget source file - c++

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.

Related

how to add a custom widget to Qt 4.8.6

I'm trying to figure out how to add a custom widget to Qt Designer. So far I've been unsuccessful. Very new to Qt. I'm running Qt 4.8.6. I know there is a newer version but due to project constraints I have to stick with this one. Essentially I'm need to add a hex spin box, i.e. a spinbox that counts in hex rather than in decimals. I even found code that implements it. It does explain how to integrate it into Qt Designer, however it is explained for version 3. Can someone offer assistance?
Any help is greatly appreciated
Read about creating designer widgets and using them, but briefly:
Subclass QDesignerCustomWidgetInterface to create your custom designer plugin for your custom widget
Build and install your designer plugin
Tell designer about your plugin location, or just make sure it's installed to $QTDIR/plugins/designer
There's also an example to follow.
Here is a documentation. At short, you just add any widget (e.g. QSpinBox to draw it nice in the Designer) to your form and convert it to the needed one.
To add a custom widget to Qt designer simply follow the steps:
In Qt designer create a new widget File->New->Widget.
Add your UI etc for this widget and save it->->MyWidget.ui
Create a class "MyWidgetHandler" to handle this widget in a MyWidgetHandler.h & cpp
In your MainWindow/Dialog wherever you want to display this widget add a "Widget" from the "Containers" section of the designer.
Now right-click the "Widget" container you just added and click "Promote to..."
This should open a dialog. You can select here the base class to inherit properties in your case QComboBox or just select the QWidget class.
Next enter the full class name i.e with namespaces eg: "blah::MyWidgetHandler"
In the Header file section simply add the path to the header file for this class. This should be a resolvable path. Eg: "UI/MyWidgetHandler.h" or "C:/UI/MyWidgetHandler.h"
Now click "Promote" and save your MainWindow.ui
The Property Editor should now show your custom class type eg: blah::MyWidgetHandler. and the properties from the base class you selected.
Don't forget to setup the UI in your handler class and include header in the Mainwindow handler.
Cheers !!!

Set CSS both in designer and in code for my custom widget

I have a custom widget subclassed from QPushButton, MyButton. It's implemented in a single .cpp file and I'm using it in Qt Creator in my application's form (I've added a QPushButton then promoted it to MyButton).
As discussed here: Should I really use a single qss file for my application instead of having one for each (UI) class? I wish to generally set its CSS inside its constructor (the general look of the button, the background image, hover behavior etc), but I would also like to be able to set it in Qt Creator (maybe customize the font size/color; generally specific to a particular button).
The issue is, as the setupUi call is issued, my buttons are created, they set their styles in their constructors, but then Qt applies the styles set in Qt Creator, immediately overriding mine.
What can I do to achieve this effect?

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.

How do you programatically update the UI in Qt?

I'm fairly new to Qt, and am trying to wrap my head around signals and slots. Though I've figured out how to create custom slots, I've yet to figure out how do update the GUI from my C++ code. I realized that the entire UI, which I created in the designer, is only written in what appears to be XML based UI code. Do I have to handwrite my own Qt C++ UI in order to update the interface, or can I somehow use C++ to update the XML based UI? I'm just looking to add a widget to the main form on a button click. Any help is appreciated. Thanks!
To add a widget to a form you can simply do
ui->layout()->addWidget(new Widget);
XML is used by QtDesigner as a mean to create, update, and persist your GUI, enabling a visual approach to development, but in the end you can build your application entirely without it.
you dont havfe to update the xml of UI . you can inherit the ui into your own class using setupUi
http://crpppc19.epfl.ch/doc/qt4-doc-html/html/qwidget.html#setupUi
now in your C++ class you can update the widgets like changing label text, lineEdit text, setting up spinbox value using Signals & slot.
That xml is used by Qt designer and outside of designer it's only used by uic as a source to generate C++ code, so everything that you do in the designer end-up as C++ code, so it can be updated (or done completely) in C++ code (you can look into the code and see that you most likely have a member called ui that is most likely a pointer, but it can also be an instance of a C++ class that is generated for you by uic, and trough that ui member you can access the widgets and layouts that you created in the designer).
A generic resource that i recommend you to read can be found here and then (if you still can't figure it out) ask a specific question about what exactly are you trying to achieve.
LE: that link contains 3 methods to use the generated code into C++ code, don't try all of them into your working project, you may choose one method or use the default one (ui member pointer)

QT widgets vs QT GUI

I'm new at QT, actually I didn't start yet but I'm intending to create a xml file (markups and nodes and everything .. ) from a QT user interface.
For example the user can find in my interface text fields where he can insert an employee name, id and age and my program will turn that to an employee node in my output xml file with its attributes name , id , age. so since I'm coding with c++ I wanted to create this interface as a QT GUI but I found that QT creator provides a project named QT Widget with the same option.
So I'm kind of confused now and I don't know what's the difference between them so I can chose.
I will appreciate any help from guys.
If I have understood your question correctly: a Qt Widget is a tiny element, one of the many items in a gui (buttons, comboboxes are all widgets). The Qt Widget, project type is for creating one, which you can use in a separate projects interface.
A Qt Gui is more likely the project type you want, that will allow you to drag in many widgets to create your 'interface text fields'.
You would use a Qt Widget project type if you need to do more advanced customization or create your own text field control.
Do you mean Qt Quick vs. Qt Widgets?
Qt Quick is a more recent type of Qt GUI which is created from a declarative markup languages known as QML. The QML source is interpreted at run-time as opposed to Qt Widgets which are compiled from C++ source code into native executable code. In addition to QML, Qt Quick uses inline Javascript for scripting the UI, but it can be (and usually is) interfaced from C++ for more complex processing.
EDIT: Qt Quick is also very much touch-oriented (at least at its current state) whereas Qt Widget GUIs provide a much richer set of UI elements. So if you are making a desktop application, you might want to leave Qt Quick alone.