Important: Please read the Qt Code of Conduct -

Is it good practice to keep data as a member of model?

  • I think data and model should be independent.
    However, I read some sample code which keep data as a private member of its model class, and its canFetchMore and fetchMore methods depend on that too, is that good practice?

    class FileListModel : public QAbstractListModel

    FileListModel(QObject *parent = 0);

     int rowCount(const QModelIndex &parent = QModelIndex()) const;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;

    void numberPopulated(int number);

    public slots:
    void setDirPath(const QString &path);

    bool canFetchMore(const QModelIndex &parent) const;
    void fetchMore(const QModelIndex &parent);

    QStringList fileList;
    int fileCount;

  • In general: the answer is no.

    You should think of QAbstractDataModel as only a standardized interface to your underlying data store (I avoid the word "model" here on purpose) that is used by your application. It is there only for the purpose of providing an interface so that item views may display data from your data store. In principle, the model should not expose API to manipulate the actual data other than through the QAIM interface.

    See my "note": in the Model view programming docs.

  • You can however add some caching to the model if the source data access is expensive. If that is the case, you could consider adding the caching to the actual source data as well. That approach is even supported by the submit() and revert() slots available in the model interface.

  • [quote]However, I read some sample code which keep data as a private member of its model class, and its canFetchMore and fetchMore methods depend on that too, is that good practice?[/quote]

    The problem, as Andre pointed out, is that approach does not scale with the complexity of the model. As long as we're dealing with trival, self-contained models (like a stringlist based one) then indeed you may think of putting the actual data storage inside the model itself. But when you have to deal with a more complex data layout and storage it's much better to use a different set of classes for managing the underlying data, and a custom QAbstractItemModel as a "standard" interface to it.

  • Since I'm a newbie messing around with these stuff, I will go with the more inconvenient way: separate data and model class :)

  • Please note that it generally does not work to just separate the actual data from the model. You will need a proper data store object in your application in order for this to work. The reaon is, that the Qt container classes (which are most often used for the storage of data in applications) are not QObjects, and hence do not signal data modifications that you could use for your model to work properly.

    If you build a data store object that manages access and modifications to your data, you can then properly interact with the QAIM so the visualization stays synchronized with the state of the data store. Note that for non-trivial data structures, this quickly becomes a complicated business. It might take some iterations to get right :-)

  • Moderators

    I think, though, that there are some notable exceptions. For instance, if I'm writing a quick-and-dirty app where I need to expose fairly simple C++-related data to QML or something, I don't have a problem with including data in the model itself. However, this is generally only in the cases where it's not a huge project, and when I don't expect scalability or maintenance to become a major factor.

    It kind of depends on the application itself, I think.

Log in to reply