0

Since Qt 5.6 we can finally write code like this:

ListView {
    id: list
    model: MyModel
    delegate: TextInput {
         text: display
         onEditingFinished: {
                model.edit = displayText
         }
}

i.e. model.edit will call MyModel's setData() with Qt::EditRole and display value from the TextInput. Great, was headache for a long time.

However even if using QAbstractItemModel is the recommended practice for more complex C++ based models I still have the feeling that all of it is meant only for read only models, i.e. that a qml view can read the number of rows, columns etc but it was never meant as a way for adding or removing rows (for clean implementation of QAbstractItemModel::setData the row must be already present).

It feels really dirty to reimplement all the insert/remove functions with Q_INVOKABLE and qml's ListModel is far too simple for anything serious.

What would you recommend for a qml based widget which should add/remove rows, edit items and yet have a C++ model?

Miro Kropacek
  • 2,742
  • 4
  • 26
  • 41
  • 2
    Possible duplicate of [Adding and removing items from a C++ list in QML/QT 5.7](https://stackoverflow.com/questions/41617677/adding-and-removing-items-from-a-c-list-in-qml-qt-5-7) – Mark Ch Jul 18 '17 at 04:31
  • 1
    I'd recommend using a generic object model, which is not bound to any particular data schema and is extremely powerful and flexible to work with. This way you can completely avoid having to keep on implementing C++ models for each and every specific purpose model: https://stackoverflow.com/questions/35160909/how-to-create-a-generic-object-model-for-use-in-qml/35161903#35161903 – dtech Jul 18 '17 at 07:35

2 Answers2

1

Reimplementing the insertRows() and removeRows() for your new subclass of QAbstractListModel or QAbstractItemModel is not dirty, it's normal!

Notice that insertRows() and removeRows() are marked virtual in the base class, indicating just that.

The base class does not know how to manipulate your data structure, as it could be a QList, or it could be something much more complicated like a SQL database or a 3rd party library.

In your class definition you can either mark the methods as Q_INVOKABLE or as public slots. Note also that several functions in Qt models classes - both virtual and non - are already marked as invokable, see e.g. here.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
Mark Ch
  • 2,840
  • 1
  • 19
  • 31
  • Of course, those functions are supposed to override. But you can't call them from QML directly, can you (imagine you want to specify QModelIndex to something different than the default). So you end up with a wrapper calling either setData() and/or insertRows() anyway. – Miro Kropacek Jul 18 '17 at 05:03
  • 1
    QML doesnt currently have any view Item capable of showing a hierarchical or tree-based model, so there shouldn't be any need to set QModelIndex parameter to anything other than default.... of course you are right, these models originated from Widgets. There is a large piece of ongoing work to rework the whole QML model-view interaction, with a view to ultimately providing a new faster QML TableView in Qt Quick 2. You can see its progress here: http://code.qt.io/cgit/qt/qtdeclarative.git/log/?h=wip/itemviews – Mark Ch Jul 18 '17 at 05:09
  • 1
    Well, there is [`TreeView`](https://doc.qt.io/qt-5/qml-qtquick-controls-treeview.html) in Qt Quick Controls 1 – GrecKo Jul 18 '17 at 08:12
  • @MarkCh thank you for additional information, I think your answer + comment are most useful. – Miro Kropacek Jul 18 '17 at 08:54
  • @GrecKo of course you are right there, but we've been told quite a few times not to use Quick Controls 1 because of its performance due to being implemented in QML rather than C++ – Mark Ch Jul 18 '17 at 12:45
  • Well, you *should* still cite `TreeView` as @GrecKo said, at least because it's the only option right now. While I just split my acid over QCC even today at my company, a viable option is still a viable option, isn't it? :) Just make sure to highlight the drawbacks (performance, bugs, visual issues on mobile, etc.) – BaCaRoZzo Jul 18 '17 at 12:52
  • @BaCaRoZzo it's hard to fit TreeView info into the answer because it doesn't really relate to the question, but there are ways of generating QModelIndex objects in QML, so I will try to add some info – Mark Ch Jul 18 '17 at 21:06
  • Yeah, sorry I should have explained myself better. I meant that, even if something is deprecated you should cite that if it is a viable solution. Granted that you highlight the shortcomings of a deprecated/not adviced solution. Sorry for the misunderstanding. :) What I would add it's the comment you made, which the OP found valuable. If it is valuable for the OP maybe it is valuable also for any other reader. Up to you to extend the answer or not. – BaCaRoZzo Jul 19 '17 at 06:18
0

I recommend you to override insertRows() and removeRows() methods which are Q_INVOKABLE and takes index as integer and invokes actual insertRows() and removeRows() methods.
So you can use both widget and qml UI approaches.
I think it is not dirty because you just make that ready for different usage and also override is normal.

S.M.Mousavi
  • 5,013
  • 7
  • 44
  • 59