Completion for a QLineEdit with multiple models/categories

361 views Asked by At

I'd like to build a completion for a QLineEdit which can take several completion models and organizes them as categories.

I have a working solution based on a QSortFilterProxyModel and a tree model for the items:

completion

The root items in the model show up as category, and the children of each root-item show up as filtered items. Then there's a customized QTreeView so this is displayed properly, tabbing ignores categories, etc.

This works fine - however it makes it very hard to write new completions (e.g. for the possible values for a setting).

Each completion needs to be a tree model with all categories in it. I'd prefer to write simple list models for each category, and then being able to combine them to a QTreeModel, i.e. something like this (pseudo-ish Python code):

commands = CommandListModel()
settings = SettingListModel()

completion.setModels([('commands', commands), ('settings', settings)])

There are some different solutions I had in mind, but I'm not sure what route to go, as all of them feel non-trivial to implement:

  • Write a QAbstractProxyModel-like class (or a custom model) which combines several list models to one tree model, and leave the view part as-is.

Writing custom tree models in Python is hard however (and typically segfaults if you do anything wrong), and I've had performance issues with it in the past (compared to a QStandardItemModel, as there are some thousand items in the underlying models).

  • Write functions for each model which fill a tree model (given a category and a list of items).

This makes it harder to write dynamic models rather than just having a list of static items.

  • Use several list models, and adjust the view to be a QVBoxLayout of QListViews.

This sounds the most promising to me so far. However, implementing tabbing through the completion and filtering so it works right might be troublesome as well, and resizing the sub-views appropriately too.

Is there some easier way to do this I haven't considered? Which approach is likely to be the least painful down the road?

0

There are 0 answers