Qt generic widget handling - c++

I am using qt (pretty new to it). I am currently using filing to save user checkbox states. Whenever the user opens that windows file is read and implemented, but there are a lot of checkboxes and I am using a lot of if statements (to load previous states). I am just curious if there is a generic way to do this as I have a lot of windows and checkboxes to handle.
Thank you.

Each QObject instance has a name, available via QObject::objectName, and you can use a combination of the QObject::findChild methods to find all of the QCheckBox instances under whatever parent widget contains all of these. Then you can extract the name and checkbox state to write to the file. When you read the file in, you reverse that process.
The caveat is that the names of your objects need to remain consistent; through the life cycle of your program, if you change a name of a QCheckBox, files containing that name either become invalid, or you have to handle the name conversion. What I would recommend is to use Qt Designer to manually set the names of the QCheckBox instances so that they make sense based on what they represent rather than the automatically-generated names they get otherwise.

Related

How to add an action to the default context menu of a QSpinBox?

I am using Qt 5.7 (C++) and want to add custom functionality like a reset option to a QSpinBox (as well as QDoubleSpinBox and maybe some other input widgets). This functionality should be accessible via the context menu. However I do not want to replace the default context menu. Instead I want to add my custom actions on top or below the already existing actions.
I found almost matching answers to this question:
https://forum.qt.io/topic/81946/add-item-to-top-of-standard-context-menu-at-right-click
How to add an entry to toolbar context menu in qt?
However, these do not help in my case since it relies on the Widget to have a method that creates and returns the standard context menu (like QLineEdit::createStandardContextMenu()). The spin boxes do not have such a method.
I also tried to go the cheap way and copy the code that creates the default options directly from source (https://github.com/qt/qtbase/blob/5.7/src/widgets/widgets/qabstractspinbox.cpp line 1249). This is also not really satisfactory since it uses private members of the underlying line edit.
Is there a (standard) way to reuse and augment the default context menu of a Q(Double)SpinBox or any QWidget in general? Or do I have to manually re-implement the default behavior?
https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qabstractspinbox.cpp#n1315
Yeah it doesn't look like we have any easy "hook" for customizing it (and you can make a feature request if you like); OTOH it's not that much code to copy, since most of the menu entries are added by QLineEdit::createStandardContextMenu()

Qt QWidget multiple instances

We are multiple people working on one Qt app. I for one am implementing a library, which will be instanciated in multiple other parts of the app. This library has a display class+form along with it.
Until now I had simply created one single instance of the library, running on a dummy, and passed debug data to one instance of the display+form, and worked like that.
But now that core debugging is finished, goal is to have everything instantiable - not just the core library code, but also the form itself, and embed that form into other displays. Each caller/user would be reponsible for passing output data of the core library instance they are using to an instance of the form. Each instance of the form would separately display the information generated by a specific library instance, possibly with different display options - they are all independent.
Similarly, it is possible to enter values in my display. Goal is to be able to enter different values in different displays instantiated accross the app, and sending those to specific instances (caller's responsiblity).
Question is of course : how to do that ? Internet talks about promoting, but I still don't see anywhere in Qt Designer where to include so-called promoted objects in other objects.
TL;DR : : I want some existing form to appear in the menu on the left in Qt Designer to be able to instantiate it multiple times in other forms. How to do this ?
Thanks in advance for the help !
Charles
You can promote any QWidget to your control from within Qt Designer. Add a QWidget, right-click and promote.
Ideally, you should create a designer plugin for your control, make the relevant properties designable, and build the plugin as well as the library. That way you'll be able to drag your control from the palette, and it will behave like the real thing.
Qt QWidget multiple instances
You answered yourself. Qt Creator: "File->New->Qt->Qt Designer Form Class" with QWidget as a base class will suit you. Then you can promote a simple QWidget in the UI into this custom widget, to create an instance. Each instance will manage its own UI.

QT: Form validation with inter-fields rules

I would like to dynamically build a form to edit a set of properties (say from a xml file or so).
On top of that, I would like to perform validation for each property (mandatory values/optional values) with a set of rules (ideally also dynamically loaded).
These rules could be associated to a single field (allowed values, range, ...) but could also link several fields (conditional validation).
I would like to be able to save the results "on the fly" (as soon as a field loses focus).
Does someone have a good lead to get me started?
Here is what I found so far:
I could start from the Qt property browser framework for the dynamic form generation. I could extend this framework to suit my needs.
Regarding the validation, I read about QValidator which seems to be a good start. However, I couldn't find anything involving several fields (cross-parameter validation)
The QSettings framework does this auto-save feature quite nicely and I guess I could reuse that.
I just wanted to be sure I am not missing some existing framework to deal with my goals since
it seems like a relatively standard thing to do.
Assuming that the fields of the form are fixed. Then you could use a shared instance of a QValidatorto validate the text in all the fields by running your validaton over a list /dictionary /map containing pointers to the fields. The list/*dictionary*/map will have to by dynamically populated and cleared, and a pointer to it hard-coded inside QValidate::validate. And if QValidator sharing is not allowed you will have to create individual ones and execute your cross-field validation.
Alternatively, you could use Qt's Signal-Slot mechanism to implement your validation whenever the text in your field is changed.
I had no idea of QSetting, and would have used the very same signal-slot mechanism to do the autosave.

Making a game in Qt regarding GUI windows

I've been wanting to program a simple game with a simple GUI using Qt (Its will be a VERY simple game, nothing fancy). What I've been wondering is, how can I create multiple windows and display them when needed? For an example, a battle screen and an inventory screen. The user should only see one of them, but should be able to access the other one when needed. I was using stacked widget but I'm not sure if that's the proper way. Also, is it better to design the windows in the designer or to code them?
A StackWidget certainly would accomplish what you want to do. The reason why it is not always used for this kind of thing, is that it all the screens are pre-created at the beginning and always exist. This means it takes a little longer to initialize, and you are using more resources than you need at any one time
But as you are saying, if this is a simple game, then I don't see a big problem with it. Just as easily, you could also, create an empty layout and swap the inventory and game panels as needed.
Add my vote to everyone else suggesting to use the designer. It is so much easier to manipulate layouts, actions, and such using the designer then through code.
You can see the Designer manual here
So this is what I would suggest:
Create your "battleScreen.ui" - which is the designer file for your battle screen and everything in it, and then create your "inventory.ui". Both of these could be QWidgets, or QFrames, or whatever makes sense.
Then create your "Game.ui" which will be your QMainWindow.
In your Game main window, you can then add your QStackWidget, and place your inventory, and battle screens in the stack widget.
If you don't know how to do that...
1) drag a QWidget into your form (into the stack widget)
2) select the new QWidget and right-click.
3) Select "Promote to..."
4) Fill out the information to promote the QWidget to your inventory class
Promoted Class Name: The name of your inventory class
Header File: The header file of your inventory class
5) Click add
6) Click Promote.
Hope that helps.
Since I'm not sure what your goals are I can't advise whether or not the stacked widget is appropriate but I think you can accomplish quite a lot using the designer and style sheets. If you need to code some parts of the GUI, you can always drop in a place holder widget and either replace it with coded items or make them children of the place holders.
A general answer for a general question:
Use the Designer to create your windows; hide and show the auxiliary windows as needed.
Use a flow manager class to manage the visibility of a related set of windows.
The stacked widget is useful for managing a button/icon whose appearance changes based on state; the different representations live in the stack.

Is there something similar to WPF DataTemplates in GTK/Glade?

I am coding a pyGTK application, and I'd like to change an input based on the user's selection from a ComboBox. For example, a user could select truck/car/van, and the input parameters would change corresponding to the type of vehicle.
Is there a way one can define the different sub-panels using Glade? It would be easy to just define a new class for each different sub-panel, but is it possible to also do this in Glade?
In glade (at least for glade-3 that uses GtkBuilder), you can have any widget as a top-level widget so you can design those panels and then insert them into appropriate container.