ComboBoxDelegate openPersistentEditor placement
I got a combobox delegate working for a QTableView:
However, I don’t like where I have placed the openPersistentEditor calls. The way I have done it, if the number of rows changes, it will break. Would I have to subclass the View to do this properly? Which function would I reimplement to turn on this persistent editor in an adaptable way?
Have a look at the wiki article Combo Boxes in Item Views – it may help you in this case.
Just a side note: Better use QStyledItemDelegate as the base for your subclass, it’s the standard delegate used by the views. This way you have less differences between view using the standard delegate and those using yours.
Volker – doesn’t that method only display the combobox when the cell has been clicked (edit mode entered)? I wanted to make it more clear to the user that this value was able to be selected from a list (by always displaying the combobox) which is when I found the openPersistentEditor idea. However, I didn’t know how to apply it to an entire column, rather than having to apply it manually to every row.
Yes, the combo box is only created on editing the cell.
In your case, I would go with an index widget. Have a look at QAbstractItemView::setIndexWidget()
setIndexWidget is a function of the View, so it seems like kind of the same problem I was having with the openPersistentEditor idea – that it won’t be “automatically applied” to every cell in a column. Where would I call setIndexWidget from so it would be applied to a column with a variable number of rows?
The documentation suggests “setIndexWidget(index, new QLineEdit);”, but where does ‘index’ come from?
The index comes from the model:
- QModelIndex indesForWidget = model->index(row, column, parent);
If you’re working on a table or a list, you can leave out the parent.
I still don’t follow – it seems like you’d still have to call this on each row from outside of the model. This means when the data (and therefore the model) changes, the new rows will not be in the same style (i.e. you’d be responsibly for somehow manually adding these custom widgets to new rows when the data changed). This doesn’t seem to follow the nice normal “the views automatically work how you have specified when the model is changed” idea.
True. So, it will require you to subclass the view itself, and respond to such changes from within that subclassed view. Worse, the combo boxes will also not respond to changes in the data of the model, so it is a very, very incomplete solution.
What sort-of works is a solution that can be found inside the KDE sources: KWidgetItemDelegate [api.kde.org] The code works, but the solution is not very scalable. I am afraid that there is no really good solution to this issue.
I still don’t follow – it seems like you’d still have to call this on each row from outside of the model. This means when the data (and therefore the model) changes, the new rows will not be in the same style (i.e. you’d be responsibly for somehow manually adding these custom widgets to new rows when the data changed).
Of course you have to do that from outside the model — it’s a view issue to have comboboxes there. I still don’t see the problem in, say, subclassing a view, connecting to the model’s signals and call the openPersistentEditor manually.
(I’m completely excluding the way of drawing the combobox manually using QStyle and reimplementing its LnF, as I believe it’s too fragile to be actually useful).
I’ve never used any K* classes – are these portable? I.e. I need this to run on Linux and Windows.
I also don’t understand how this could be so hard? It seems pretty reasonable to want to do this, right?
A lot of KDE code is portable, as it only depends on Qt. This is one example of that. KDE is working to modularize their code better, so code like this becomes available to Qt developers without having to include the parts these developers don’t need.
Why this is hard, is because a the item views are optimized to work on large datasets. Trying to represent large datasets using separate widgets for each cell is never going to be performant. The architecture is geared towards being able to display lists or tables with thousands of items fast, and it works well for that. The view is basically a canvas that is just painted on using delegates. Unfortunately, that has effects on how easy to add more advanced controls (widgets) in that list.