Reputation: 23
I am trying to understand a very specific concept where values available from a model, are made available towards widgets. A specific widget that would require some internal lookups is QComboBox.
QDataWidgetMapper adds a QComboBox towards an index in a model via "addMapping", specific properties can be set too. The most naive method "just works" if the text is present in the values within the QComboBox. Under the hood there is likely some QItemDelegate that does the magic where the model can have a plain string, and the QComboBox would correctly select the right item.
I am trying to find the actual implementation in C++. I would expect it would happen as the QComboBoxDelegate, but nothing there suggest that any index lookup is done. In the super class QStyledItemDelegate hints setEditorData with editor->setProperty(n, v) is used. Is from that point on setCurrentText just called? Is editor->metaObject()->userProperty().name(); working due to Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged USER true)?
QStyledItemDelegate: commit QComboBox value to model on click QDataWidgetMapper ignoring inheritance
Upvotes: 0
Views: 51
Reputation: 48444
When a new QDataWidgetMapper instance is created, it internally creates and sets a basic QItemDelegate as its initial delegate[1].
There are two ways to use addMapping()
: by using the widget and section, or by also providing a property name specific to that widget.
When the widgets are being updated[2] only the widget and section are used for addMapping()
, QDataWidgetMapper calls setEditorData()
on the delegate:
The default implementation stores the data in the editor widget's user property.
The USER
property of QComboBox is, indeed, the currentText
[3]:
The setter
setCurrentText()
simply callssetEditText()
if the combo box is editable. Otherwise, if there is a matching text in the list,currentIndex
is set to the corresponding index.
If you need finer control over the behavior of the mapper with a combo box, you have different possibilities:
USER
property (the last declared user property is always considered the actual one);addMapping()
overload; in this case, Qt will simply call setProperty()
on the widget with the given property name;setEditorData()
and, possibly, setModelData()
;Note that, for the third choice, the basic QItemDelegate (or even QAbstractItemDelegate) should suffice. For some reason, Qt6 uses QStyledItemDelegate instead.
[1] See the constructor in qdatawidgetmapper.cpp
(Qt5 sources, codebrowser.dev).
[2] See the populate()
function in the same code (Qt, codebrowser).
[3] Sets the text on the line edit if the combo is editable, otherwise use findText()
and eventually setCurrentIndex()
if the index is >= 0.
Upvotes: 0