C++ Qt - Hierarchy in the elements added to a GUI - qt

In general, is the order in which I add my widgets into each other, the same order I access them back?
Example:
If I have a bunch of QPushButton in a QHBoxLayout, and this layout in a Window::ui,
can I access those button by simply ui->button_name? or Do I must do ui->layout->itemAt(idx)?
EDIT: My question aims to find an easy way to access elements that are deep into the hierarchy, like a label in a frame, inside a layout, inside a frame, inside the window etc...
PS: Also, I would really appreciate any documentations about good practices of GUI architecture!

Use ui->object_name you don;t need to worry about the layout!
It's possible to redesign the layout, eg. for different platforms, without changing any of the C++ code.
There are a couple of good books on Qt and the sample code is very good.
C++ GUI Programming with Qt 4
Advanced Qt Programming

Related

Qt 5.x Custom Widget Creation and Use

I'm returning to Qt programming after an absence of a couple of years, and I'm starting with Qt 5.1. In the past, I've used the designer, and a good deal of hand-crafted code to put Qt projects together. Now, we'd like to make heavy use of the Creator.
But I'm not seeing how to accomplish some seemingly basic tasks. For example, I'd like to design a custom widget, then pull it into my main application, but although the Creator allows me to make multiple files within a project, they seem to have no knowledge of one another as far as the Creator itself is concerned. Once my widget is built, there's no way to pull it into the main application, and also no way to test it independently, at least that I'm able to find.
It seems as though documentation for Qt has taken a major blow somewhere along the line. It is cursory and thin, compared to the extremely detailed docs that used to be available in the past.
If someone can point me to a decent collection of documentation and tutorials, I would be grateful.
Unit Testing
Use the Qt Test module: https://doc.qt.io/qt-5/qttest-index.html
Using Custom Widgets
I'm not 100% sure what you meant by "pull [the widget] into the main application".
If you want to combine your custom widgets in Qt Designer, add a placeholder (blank) QWidget in the parent and Promote it to your custom widget:
https://doc.qt.io/qt-5/designer-using-custom-widgets.html#promoting-widgets
If you want to combine your custom widgets in C++, instantiate your custom child widget and add it into the parent widget's layout using QLayout::addWidget():
https://doc.qt.io/qt-5/qlayout.html#addWidget
If you want to make your application display a custom widget, simply #include the widget's header, instantiate the widget, and call QWidget::show():
https://doc.qt.io/qt-5/qwidget.html#show
If you want to develop your custom widget in a separate standalone project, include it in your main project as a Subproject:
https://doc.qt.io/qtcreator/creator-project-creating.html#adding-subprojects-to-projects
How do I make a subproject with Qt?
Other Notes
Qt Designer has been integrated into Qt Creator for many years. Qt Designer and its documentation have changed very little between Qt 4.8 and Qt 5.
The extremely detailed docs for Qt 5 are at https://doc.qt.io/qt-5/. There are links to useful doc collections in the nav bar on the right.
I recommend exploring QML/Qt Quick. It's much easier to create QML-based GUIs compared to widget-based GUIs. It's still a young technology though, so it might not suit your needs yet: http://doc.qt.io/qt-5/qmlapplications.html

which Qt project type we should use?

New to Qt. In the official Qt tutorial, it says:
To set up a project, you first have to decide what kind of an application you want to develop: do you want a user interface based on Qt Quick or HTML5 or Qt widgets.
We plan to use Qt to do medical image display, and also use Qt to build a GUI application to control a medical device. They will be two different projects.
Which Qt project type we should use for them?
Docs say:
QWidgets are a better choice if your UI is comprised of a small number of complex and static elements, and QML is a better choice if your UI is comprised of a large number of simple and dynamic elements.
I say:
If you're going for desktop applications I'd suggest Qt Widgets, you don't have to ship the final app with libs for QML and the whole source will be written in C++ (faster, simplier so easier to debug).
QML would be a nice alternative if you want to create phone/tablet (touch experience in general).
I would argue that between Qt Quick and Qt Widgets there is no objectively right answer. In theory, one should be able to replicate any UI using either method - because at the end of the day, they are both using QtGui behind the scenes. So functionality is probably not an issue.
One thing to note is that Qt Quick (i.e., QML) is designed explicitly to make UI programming require much less code, and much less C++ knowledge. I would say it achieves this goal very well.
However, at the end of the day, I think it mostly comes down to what language your developers are already familiar with. If you have a team of C++ pro's, then I would go with Qt Widgets - if only because it's going to be very easy for them to pick up, and it's something they're already familiar with. (I'm guessing this is the case because you're already writing C++ code for your project).
If, on the other hand, your developers are already very good at QML (or, more generally, JavaScript - which QML is heavily influenced by), then I would go with Qt Quick for the same reasons.
I know of two types of Qt UI: Qt Quick and widgets.
Widgets behave like most other UI toolkits out there, you have a GUI editor and a tree of UI objects. They are pretty mature and look like most standard UIs.
Qt Quick is the newer Qt UI toolkit. It uses a domain specific declarative language (QML) to specify the user interface and JavaScript for interactions. There are also plans to offer Qt widgets inside the Qt Quick framework, but I'm not sure how far that project has gotten. Qt Quick is meant to deliver more dynamic / custom user interfaces.
As far as I know Qt will continue to support both approaches in the foreseeable future so which one you pick depends on your use-case.

Qt GUI in designer or in code?

When it comes to designing a GUI in Qt, I am hesitating between using the designer in Qt Creator, or doing everything in source code. I'm using Qt widgets and not QML.
If I use the designer I can easily create a GUI using qt standard widgets. But as soon as I need to subclass a widget to extend its functionality I have to build a Designer plugin to support my new widget. Is that correct? Or is there another way to it?
You can build all the GUI in Designer including custom widgets, and you can also build your custom widgets in Designer.
Designer does not need to interpret your custom widgets. Just use the promote functionality. With promote, you start with a plain widget within Designer and then tell the "real" class of it (your custom one) and the header file where it is decleared. The only drawback is that within Designer, it will stay looking like an empty widget.
In my experience, it is much better to use Designer for the GUI than writing source code yourself. You can easily change all the properties afterwards etc., and it is helpful even if you rely on custom widgets. Source code is not a good declarative language for GUI objects, with all the properties etc. Also you cannot play around, you would need to compile all the time just to tell "Is it better to have this text label in bold font?".
Sometimes I edit the XML files that are created by Designer by hand. For example, if I want to put a widget somewhere else in the object tree. If you don't mess up the XML, Designer will still read it and not destroy your changes. The only reason I see for writing GUI in source code is when you have repetitive elements, or dynamic changes based on data input, e.g. a for()-loop that produces elements. In my project I have some Selector Boxes that are filled with options in the source code.
And btw: If you prefer to write your GUI in code instead of using Designer, maybe you are not the right person to craft the GUI. Most programmers don't understand that while they are technically able to design a GUI, they are not always also competent in doing it.
http://hallofshame.gp.co.at/index.php?file=shame.htm&mode=original
It is a bit of a shortcut, but I often use a simple QWidget as a container for my custom widget. This way, I can setup sizing policies, put the whole thing in the layout I want before my custom widget is even in. Then, in C++, I add the custom widget as a child of the container widget.
edit: As ypnos mentioned you can promote the placeholder directly. You can find guidelines here

Qt best practice: append signals and slots to my main window or create new class

Im just pondering best practice with an application I'm developing. Its a simple one window application using qt creator. It's just going to start a QProcess and show the output in a QTextEdit box. To do this there needs to be a bit of processing between the output of the QProcess and the QTextEdit but i dont know where i should do this, should i create a new class to do that or add member functions and extra signals and slots to my main window? I dont want mainwindow to become bloated and hard to read but equally i dont want to have more source files than really I need.
Any thoughts?
The main window class can very easily get bloated with all kinds of functionality. I've dealt with that myself, so it's a very real trouble.
Really, though, this is not so much of QT question as it is an object-oriented design question. The key is that your output window does not need to be a part of QMainWindow, so it probably shouldn't be. Make the display a widget, and insert it onto the main window. That is much more flexible, as if you ever need to move that output pane for any reason, it won't be coupled to a specific part of the program.
The logic that feeds data into that output pane should also get its own class, separating the responsibility for displaying the output from the responsibility for acquiring the output.
For reference on the concepts behind my suggestion, see the Single Responsibility Principle and the separation of concerns.
Also - you may wish to have a read at this link to model view delegate information which is how I tend to develop in Qt. Like the person above says - this is more a question of good OO design.

Qt Designer vs Handcoding

Every time I start a project with some graphical toolkit, one of the first conflicts happen with the decision of how to deal with the visual design and the widget layout: A graphical tool or handcoding?
This is a quite tricky/subjective question because most people will decide based on personal preference. It also depends greatly on the quality of the graphical tool. In this case I would like to focus just on the latest version of the QT library. I do not intend to discuss which method is better. I am convinced that the best answer is: depends on the project.
What I want is a reference to a good non biased article, based on experience after several projects. The article should just describe the tradeoffs of both choices
I started with doing everything hand-coded, and of late have been switching to using Qt Designer for most forms. Here are some benefits for each position:
Using Qt Designer
The biggest time saver for me is managing complex layouts; it saves a lot of tedious coding. Simply (very roughly) arrange your widgets, select them, right-click, and put them in the correct type of layout. Especially as layouts become nested, this is so much easier.
It tends to keep your implementation files cleaner instead of filling them with all the boilerplate layout code. I'm type-A, so I like that.
If you are translating your application, it is possible to send your translators the .ui files so they can see on your GUI where the text they are translating will be. (Assuming they are using Qt Linguist.)
Hand-coding
Control. If you have a layout where you need to instantiate / initialize the controls in a very particular order, or dynamically create the controls based on other criteria (database lookup, etc.), this is the easiest way.
If you have custom widgets, you can kind-of-sort-of use the Designer, adding the closest built-in QWidget from which your class derived and then "upgrading" it. But you won't see a preview of your widget unless you make it a designer plugin in a separate project, which is way too much work for most use cases.
If you have custom widgets that take parameters in their constructor beyond the optional QWidget parent, Designer can't handle it. You have no choice but to add that control manually.
Miscellaneous
I don't use the auto-connect SLOTS and SIGNALS feature (based on naming convention such as "on_my_button_clicked".) I have found that I almost invariably have to set up this connection at a determinate time, not whenever Qt does it for me.
For QWizard forms, I have found that I need to use a different UI file for each page. You can do it all in one, but it becomes very awkward to communicate between pages in any kind of custom way.
In summary, I start with Qt Designer and let it take me as far as it can, then hand-code it from there. That's one nice thing about what Qt Designer generates--it is just another class that becomes a member of your class, and you can access it and manipulate it as you need.
My answer is based on two years developing biochemistry applications using PyQt4 (Python bindings to Qt 4) and OpenGL. I have not done C++ Qt, because we only used C++ for performance-critical algorithms. That said, the PyQt4 API greatly resembles Qt4, so much here still applies.
Qt Designer
Good
Exploration. Discover what widgets are available, the names for those widgets, what properties you can set for each, etc.
Enforces separation of UI logic from application logic.
Bad
If you need to add or remove widgets at run-time, you have to have that logic in code. I think it's a bad idea to put your UI logic in two places.
Making changes to nested layouts. When a layout has no widgets in it, it collapses, and it can be really hard to drag and drop a widget in to the location you want.
Hand coding
Good
Fast if you are very familiar with Qt.
Best choice if you need to add or remove widgets at run-time.
Easier than Qt Designer if you have your own custom widgets.
With discipline, you can still separate UI layout from behavior. Just put your code to create and layout widgets in one place, and your code to set signals and slots in another place.
Bad
Slow if you are new to Qt.
Does not enforce separation of layout from behavior.
Tips
Don't just jump into creating your windows. Start by quickly sketching several possible designs, either on paper or using a tool like Balsamiq Mockups. Though you could do this in Qt Designer, I think it is too tempting to spend a lot of time trying to get your windows to look just right before you've even decided if it is the best design.
If you use Qt Designer for PyQt, you have the extra step of running pyuic4 to compile your *.ui files to Python source files. I found it easy to forget this step and scratch my head for a second why my changes didn't work.
If you code your UI by hand, I suggest putting your layout code in one place and your signals and slots in another place. Doing this makes it easier to change the way your widgets are arranged on a window without affecting any of your application logic. Or you can change some behavior without having to wade through all the layout code.
Enjoy Qt! Now that I am using Java Swing for work, I miss it.
I tend to layout dialogs using the designer but I do all the event handling stuff in the main code. I also do all the main windows, toolbars, menus in direct code.
The designer is just frustrating - a pity since decent drag and drop sizer based designers have been around for more than a decade
It depends on the number of different windows/panels you need for your application. If the number is small, use a graphical tool. It is much faster to get a few windows designed perfectly. If the number is large, the graphical tool can (and should) only be used for prototypes. You need to code the layout to be able to make application-wide changes at acceptable cost.
That includes creating a model of how the UI of the application works and dynamically adding and removing widgets at runtime. For an excellent example of such a model (in a different environment), take a look at the glamour model for creating object browsers.
I object to the suggestion that it is tricky/subjective (at least more than other development choices). It is easy to come up with criteria to decide on. Personal experience and preference are important for that, as they decide when the number of different windows should be considered small. The same goes for tool quality.
My personal opinion (just personal), all GUI based development distracts me too much, my imagination or my mind works very bad when i'm seeing gui objects, i prefer to hand-coding most the time because my imagination works better, you know, is like you were reading a book with no images... when i see nothing else than code its looks like i finish faster...
Second reason, i like c++ so much, so I see the good side of hand-coding, is that I keep my c++ practice no matter if I'm writing something redundant... Coding skill is improved when you only use text... Indeed, i could use nano or vim, but that is too far slow for debuging.
Hand-coding here ++vote
I use a combination of both:
I find for x,y coordinates, Designer is the way to go.
A lot of the other UI properties etc can be set in your code.
I think trying to do UI completely by hand-coding would be a very time consuming project. It's not as simple as setting up HTML tables.
Yes version 4 is bad, but people at work who have used version 3 said it was REALLY bad. Lots of crashing.
I, along with my fellow QTers, are truly hoping that version 5 will be an improvement.
I know this is an old question, but I hope this helps! One man's experience.

Resources