Qt mvc框架入门 3 自定义模型

A read-only example model

The model implemented here is a simple, non-hierarchical, read-only data model based on the standard QStringListModel class. It has a QStringList as its internal data source, and implements only what is needed to make a functioning model. To make the implementation easier, we subclass QAbstractListModel because it defines sensible default behavior for list models, and it exposes a simpler interface than the QAbstractItemModel class.

When implementing a model it is important to remember that QAbstractItemModel does not store any data itself, it merely presents an interface that the views use to access the data. For a minimal read-only model it is only necessary to implement a few functions as there are default implementations for most of the interface. The class declaration is as follows:

#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H

#include <QAbstractListModel>
#include <QModelIndex>
#include <QStringList>


class StringListModel : public QAbstractListModel
{
    Q_OBJECT

public:
    StringListModel(const QStringList &strings, QObject *parent = 0)
        : QAbstractListModel(parent), stringList(strings) {}

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

private:
    QStringList stringList;
};

#endif // STRINGLISTMODEL_H

Apart from the model's constructor, we only need to implement two functions: rowCount() returns the number of rows in the model and data() returns an item of data corresponding to a specified model index.

Well behaved models also implement headerData() to give tree and table views something to display in their headers.

Note that this is a non-hierarchical model, so we don't have to worry about the parent-child relationships. If our model was hierarchical, we would also have to implement the index() and parent() functions.

#include "stringlistmodel.h"

int StringListModel::rowCount(const QModelIndex &parent) const
  {
      return stringList.count();
  }

QVariant StringListModel::data(const QModelIndex &index, int role) const
  {
      if (!index.isValid())
          return QVariant();

      if (index.row() >= stringList.size())
          return QVariant();

      if (role == Qt::DisplayRole)
          return stringList.at(index.row());
      else
          return QVariant();
  }

QVariant StringListModel::headerData(int section, Qt::Orientation orientation,
                                       int role) const
  {
      if (role != Qt::DisplayRole)
          return QVariant();

      if (orientation == Qt::Horizontal)
          return QString("Column %1").arg(section);
      else
          return QString("Row %1").arg(section);
  }

The list of strings is stored internally in the stringList private member variable.

Dimensions of the model

We want the number of rows in the model to be the same as the number of strings in the string list. We implement the rowCount() function with this in mind:

Since the model is non-hierarchical, we can safely ignore the model index corresponding to the parent item. By default, models derived from QAbstractListModel only contain one column, so we do not need to reimplement the columnCount() function.

Model headers and data

For items in the view, we want to return the strings in the string list. The data() function is responsible for returning the item of data that corresponds to the index argument:

We only return a valid QVariant if the model index supplied is valid, the row number is within the range of items in the string list, and the requested role is one that we support.

Some views, such as QTreeView and QTableView, are able to display headers along with the item data. If our model is displayed in a view with headers, we want the headers to show the row and column numbers. We can provide information about the headers by subclassing the headerData() function:

Again, we return a valid QVariant only if the role is one that we support. The orientation of the header is also taken into account when deciding the exact data to return.

Not all views display headers with the item data, and those that do may be configured to hide them. Nonetheless, it is recommended that you implement the headerData() function to provide relevant information about the data provided by the model.

An item can have several roles, giving out different data depending on the role specified. The items in our model only have one role, DisplayRole, so we return the data for items irrespective of the role specified. However, we could reuse the data we provide for the DisplayRole in other roles, such as the ToolTipRole that views can use to display information about items in a tooltip.

猜你喜欢

转载自blog.csdn.net/a1317338022/article/details/81735524