PDA

View Full Version : How to make a filterable and sortable list of Widgets



dlobron
10th February 2020, 20:58
I have a Qt C++ application to which I'd like to add a list of "Card" objects. Each Card can contain a few widgets, including a text area and two spinboxes. Here's the hard part: I want to be able to sort and filter this list dynamically. I tried making a QListView with a StandardItemModel, and set a SortFilterProxyModel on the StandardItemModel. This works fine when the items in the model (which must be QStandardItem) only contain text. The problem is that I can't add a Widget, such as a SpinBox, to a QStandardItem.

I tried subclassing QStandardItem, but I could not figure out how to display Widgets in my subclass. I tried the QStyledItemDelegate example of a custom spinbox (https://doc.qt.io/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html), but this only works for rendering a single spinbox: it doesn't let me add any Widget to my QStandardItem.

Is there a way to display a list of Widgets or Widget containers, such that I can filter and sort the list? My goal here is to make a list of card-like items (as described here: https://material.io/components/cards/#anatomy), and to show, hide, and sort the cards.

d_stranz
10th February 2020, 21:59
Seems to me that you have the problem that you are "confusing the map for the territory", that is, you are not distinguishing between the model for your cards and their contents with the way you display the model on the UI.

Your map is the model that describes the cards and the widgets each one contains. It is a hierarchy of widgets and layouts, with the card widget at the top and any layouts, spin boxes, line edits, etc. under that in a parent-child relationship.

Your territory is the way you display that information on screen. If you want to display your model as a hierarchy, then you would use QTreeWidget. If you want a list, you use QListWidget. For each QWidget in your model, you can retrieve its name (QObject::objectName()) and through the QMetaObject (via QObject::metaObject()) you can retrieve the class name (widget type) through QMetaObject::className(). What you display is the text that describes each of the components in your model.

This is exactly what Qt's "ui" files are all about. The ui file is a description of the widget and layout hierarchy for a dialog or other widget. At runtime, Qt uses the information compiled form that file to create the actual widgets on screen.