I'm developing an application which displays items on a QGraphicsScene. These
items have properties, which I would like to display in a tree-view, if the
item is selected. If possible, I would like to stick with the property system
implemented by QObject. However, this does not fit all my needs because I need
to store some meta-data along the properties, e.g.
a category used for grouping (e.g. "System properties" and "User properties")
a tooltip text which is shown when the mouse hovers over the property in
the tree-view.
Inspired by Qt Property Browser and by Qt's object framework, I have thought to
implement the following system:
All items in the scene are derived from PropertyItem (which itself inherits
QGraphicsItem or QGraphicsObject). It contains
the logic to get and set the value of a property.
Every class derived from PropertyItem has a static MetaPropertyItem.
A MetaPropertyItem holds instances of the class MetaProperty in order
to store meta-data about the properties of such as the category, the
tooltip string and the type of the property.
Whenever an item is selected in the scene, instances of the Property class
are created for every MetaProperty from the associated MetaPropertyItem.
These properties are then shown in the tree-view and deleted when the item
is deselected.
The more I think about this design, the more I get the feeling that I'm doing
something wrong. It seems that I'm just duplicating what is already part of Qt:
PropertyItem <--> QObject
MetaPropertyItem <--> QMetaObject
MetaProperty <--> QMetaProperty
Property <--> needs to be implemented
I also found this bug ticket, which proposes to add meta-data to a Qt property.
Unfortunately, it did not get any attention so far.
Looking for alternatives, I also stumbled upon QMetaPropertyBuilder which
will (probably?) be part of Qt 5. Unfortunately, documentation about this class is sparse
and what I understood from reading the sources it would not solve my problem.
Thus, my question: Is there actually a better way to achieve what I'm
looking for without re-implementing another Qt framework?
Related
I am creating an application that saves the data of an object sending service.
I created that with Qt, a model of type QStandardItemModel that I want to display with QtableView.
But QtableView shows me the line level on the left. I want to delete it or hide it if possible.
I also have a problem with a header that I want to divide into two horizontally then divide the corresponding part of the bottom in two vertically. The reason for these division is that I have two headers with similar beginnings (date of correspondence and correspondence number)
Thank you for your reply because it is really important for me.
This type of QHeaderView does not exist, but we can create it for it we must create a class that inherits from QHeaderView and rewrite mainly the method paintSection which is the method in charge of drawing the sections of the QHeaderView.
But to do the generic project for any type of visual design we have to keep the information of the position and size of each section, for this we will create a model, to understand why of the overwritten classes I recommend you read content of the following link.
Explain the logic of each method is extensive so only place the link of the project that implements the above and describe the task of each class:
TableHeaderItem: It is responsible for saving the information of each item, mainly rowspan and columnspan in addition to the label.
GridTableHeaderModel: Model class that provides access to each item so that we can edit and read each item
GridTableHeaderView: This class is the custom QHeaderView where the main methods are overwritten to get the desired look.
GridTableView(optional): is a TableView that has methods to work directly with GridTableHeaderView.
Output:
Note: to hide the vertical header it is only necessary to use the hide() method:
horizontalHeader()->hide();
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.
I want to embed two generic buttons like "Select" and "Cancel" to CMFCPropertyGridCtrl property line. Is there a painless way to do that?
Found a solution myself. You can use OnCreateEditor virtual method to send a custom control to a property. Note, that it will be shown on property edit. Another important note, that CMFCPropertyGridCtrl calls OnCreateEditor each time the user edits the property but before the control is destroyed it deletes the last received CWnd object itself. You should consider that. I have found no notes about that in MSDN CMFCPropertyGridProperty documentation (you know what to say).
I've been reading about Qt's Model/View framework. I find it really helpful on working with tabled data like tables from a database. My question is: will it be useful for non-table data like property list or just some bunch of data of various types? If so, how should I approach it?
The goal is to come up with an editor for some property list like data. The list is constructed at runtime and the elements are of various types (numbers, strings, booleans, and file paths, to name a few). Each element is basically a name-value pair. The name, type, and restrains (limits for example) for each element are defined at compile time. They will be assembled at runtime into different lists depending on user input. And the list of elements can change during the edit session.
The UI will most likely be combination of various pre-designed widgets assembled according to user input. They may not be list or table views.
Some pointer to design pattern or examples are also much appreciated. Thanks.
I don't see a problem with MVC framework in QT for doing that.
Basically the difference between a standard table display and this is that you create a list dynamically akin to a map of:
QMap<QString, QVariant> property_map;
You can do a:
QList<std::pair<QString, QVariant>> property_list;
which you can then use to display in a table the property. The best way would probably be:
struct {
QString prop_name;
int prop_type;
QVariant prop_value;
};
QVariant basically will provide you with a single abstraction class for data storage and it is actually what's being returned by the data() function inside the QAbstractItemModel which you might be reimplementing.
So basically you will take a property list and boil it down to the same table like data as the database.
AMENDED
If you have a Widget that you want to have this widget populated with other predefined widgets you are quite likely to have multiple problems unless widgets are of same or well defined size.
What you can do is in you Display widget define a layout like: QGridLayout or other possible layouts and then add your other widgets to it using some set of parameters, which could be done but can be somewhat of a pain.
The other approach that you may take is to place all property widgets up front on the display UI and simply turn the ones you need on and the rest off, but this only applicable if you have a well defined limited number of pre-designed widgets.
I've been using Model/View framework for quite some time now and I usually implement my own models with a backend based on Qt containers (vectors, list, etc). Even if data eventually comes from a database, working with (e.g.) a vector of database ids can dramatically improve performance (and sometimes is the only way you can do).
This trivial example from Qt docs (see "Creating a Custom Model) is the point where I started and shows how to use a QStringList as a backend for a custom model.
Once defined your model you can define your custom Views, which will draw arranged widgets based on the content of the model underneath.
When the model change, your view will change accordingly rearranging widgets when necessary.
Leveraging QVariant capabilities you should be able to render the proper widget for every datatype (e.g. a QSpinBox for a float a QComboBox for a QStringList, and so on...)
I'm building a desktop app in QT (although that may be irrelevant) and I'm having a hard time working through the class structure and layout. The data model is fairly simple with a root container with a number of containers of items. Consider the following representation:
Root
+ Parent
+ Child
The UI is fairly simple and follows that data model with a main window with a scrollable area (root), widgets that contain layouts (parents) of custom widgets (children) with some labels and buttons.
My trouble is with handling events that need to go up the chain and then back down like moving a child from one parent to another, moving elements, or updating child meta-data that impacts several to many other widgets.
I'm currently splitting UI widgets and model objects but having each widget and corresponding model object pointing to and from each other feels cumbersome and I think it is leading to too much maintenance.
I'd suggest following a standard MVC pattern and ensure there are no dependencies from the model to the view; in your case this would mean that while there is a widget for every model item, the model items do not reference their corresponding widgets.
While the MVC pattern has many flavours, one way to accomplish this would be to have a view class that monitors the model for any changes and updates the view accordingly (this can be accomplished by connecting a slot in the view class to a signal emitted from the model class). Any changes the user initiates through the view can then be:
1) handled directly by the model
through a simple signal/slot
connection
2) handled
by a controller class which can
direct the model to update accordingly
Either of these would then cause the model to emit an update signal which would cause your view to update. The benefit of this is the ability to change your view (or add additional views) without having to update your model.
I'd recommend reading Qt's Model/View Programming Guide to better understand how MVC works in Qt and to see if there's an existing class or interface (e.g. QAbstractItemModel) that you could use instead of baking your own.
Consider using factory pattern and command pattern. There are plenty of samples. I am just giving a hint here.
http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Command_pattern
Forgot mention about qt book: cartan-cas-dot-suffolk-dot-edu/oopdocbook/html/