QT mvc入门 4 可以编辑的模型

#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;

    Qt::ItemFlags flags(const QModelIndex &index) const;
          bool setData(const QModelIndex &index, const QVariant &value,
                       int role = Qt::EditRole);

private:
    QStringList stringList;
};

#endif // STRINGLISTMODEL_H


#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 || role == Qt::EditRole)
          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);
  }

Qt::ItemFlags StringListModel::flags(const QModelIndex &index) const
  {
      if (!index.isValid())
          return Qt::ItemIsEnabled;

      return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
  }

bool StringListModel::setData(const QModelIndex &index,
                                const QVariant &value, int role)
  {
      if (index.isValid() && role == Qt::EditRole) {

          stringList.replace(index.row(), value.toString());
          emit dataChanged(index, index);
          return true;
      }
      return false;
  }

//test code
    QStringList datas;
    datas << "111" << "222" << "333" << "444" << "555";

    StringListModel model(datas);

    QListView *view = new QListView;
    view->setModel(&model);
    view->show();

文章取自Qt官方帮助文档:检索model/view programming

Creating New Models

The separation of functionality between the model/view components allows models to be created that can take advantage of existing views. This approach lets us present data from a variety of sources using standard graphical user interface components, such as QListView, QTableView, and QTreeView.

The QAbstractItemModel class provides an interface that is flexible enough to support data sources that arrange information in hierarchical structures, allowing for the possibility that data will be inserted, removed, modified, or sorted in some way. It also provides support for drag and drop operations.

The QAbstractListModel and QAbstractTableModel classes provide support for interfaces to simpler non-hierarchical data structures, and are easier to use as a starting point for simple list and table models.

In this section, we create a simple read-only model to explore the basic principles of the model/view architecture. Later in this section, we adapt this simple model so that items can be modified by the user.

For an example of a more complex model, see the Simple Tree Model example.

The requirements of QAbstractItemModel subclasses is described in more detail in the Model Subclassing Reference document.

Designing a model

When creating a new model for an existing data structure, it is important to consider which type of model should be used to provide an interface onto the data. If the data structure can be represented as a list or table of items, you can subclass QAbstractListModel or QAbstractTableModel since these classes provide suitable default implementations for many functions.

However, if the underlying data structure can only be represented by a hierarchical tree structure, it is necessary to subclass QAbstractItemModel. This approach is taken in the Simple Tree Model example.

In this section, we implement a simple model based on a list of strings, so the QAbstractListModel provides an ideal base class on which to build.

Whatever form the underlying data structure takes, it is usually a good idea to supplement the standard QAbstractItemModel API in specialized models with one that allows more natural access to the underlying data structure. This makes it easier to populate the model with data, yet still enables other general model/view components to interact with it using the standard API. The model described below provides a custom constructor for just this purpose.

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:

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.

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.

An editable model

The read-only model shows how simple choices could be presented to the user but, for many applications, an editable list model is much more useful. We can modify the read-only model to make the items editable by changing the data() function we implemented for read-only, and by implementing two extra functions: flags() and setData(). The following function declarations are added to the class definition:

Making the model editable

A delegate checks whether an item is editable before creating an editor. The model must let the delegate know that its items are editable. We do this by returning the correct flags for each item in the model; in this case, we enable all items and make them both selectable and editable:

Note that we do not have to know how the delegate performs the actual editing process. We only have to provide a way for the delegate to set the data in the model. This is achieved through the setData() function:

In this model, the item in the string list that corresponds to the model index is replaced by the value provided. However, before we can modify the string list, we must make sure that the index is valid, the item is of the correct type, and that the role is supported. By convention, we insist that the role is the EditRole since this is the role used by the standard item delegate. For boolean values, however, you can use Qt::CheckStateRole and set the Qt::ItemIsUserCheckable flag; a checkbox is then used for editing the value. The underlying data in this model is the same for all roles, so this detail just makes it easier to integrate the model with standard components.

When the data has been set, the model must let the views know that some data has changed. This is done by emitting the dataChanged() signal. Since only one item of data has changed, the range of items specified in the signal is limited to just one model index.

Also the data() function needs to be changed to add the Qt::EditRole test:

猜你喜欢

转载自blog.csdn.net/a1317338022/article/details/81736021
qt4