Introduction to Qt—Model/View Framework

1. Introduction to Model/View framework

1. The core idea of ​​the Model/View framework

The core idea of ​​the Model/View framework is that the model (data) is separated from the view (display) . The model provides a standard interface to access data and does not care how the data is displayed. The view customizes the display method of the data and does not care how the data is organized and stored. That is, data storage and rendering are separated .

The separation of data and display in the Model/View framework allows the use of different interfaces to display the same data, and the ability to add new display interfaces without changing the data. To handle user input, a delegate is introduced. The advantage of introducing delegates is that the rendering and editing of data items can be customized.

 

By providing the appropriate data for each role, the model can tell the view and delegate how to display content to the user. Different types of views can choose to ignore data they don't need, or add extra data they need. In each item, each data role corresponds to a piece of data, and the data is set for the specified data role through the setData() method. The setItemData() method is to set the same data for all data roles.

The benefits of this article, free to receive Qt development learning materials package, technical video, including (C++ language foundation, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓See below↓↓Click on the bottom of the article to receive the fee↓↓ 

3. View

  In the Model/View architecture, the view is the path of data from the model to the end user. Data is displayed to users through views, but usually the display of data is completely different from the storage of the underlying data.

  QAbstractItemModel provides a standard model interface , and QAbstractItemView provides a standard view interface , which can separate the data from the display layer and use the model index mentioned above in the view. The view manages the layout of the data from the model: either rendering the data itself directly, or rendering and editing the data through a delegate.

  Views are used not only to display data, but also to navigate between and select data items. In addition, the view also needs to support many basic user interface features, such as right-click menus and drag and drop. A view can provide data editing functions, or delegate the editing functions to a delegate. A view can be created without a model, but a model must exist before it can be displayed. Multiple views can be independent or shared at the user's choice.

QT has built-in QListView, QTreeView, and QTableView view classes. QListView displays the data items in the model in the form of a simple list, or in the form of a classic icon view. QTreeView displays the data items in the model as a list with a hierarchical structure, allowing for display in a compact deeply nested structure. QTableView displays the data items in the model in the form of a table.

4. Delegate

  The delegation is for the view to implement some advanced editing functions . Model/View does not completely separate the user interaction part. In general, views present data to the user and handle common input. However, for some special requirements (such as the requirement here that numbers must be entered), it is entrusted to complete . These components provide input functionality as well as rendering certain special data items. The delegated interface is defined by QAbstractItemDelegate .

  QAbstractItemDelegate renders user content through the two functions of paint() and sizeHint() (the renderer must be drawn by itself). Starting from QT4.4, QT provides component-based subclasses: QItemDelegate and QStyledItemDelegate. The default delegate is QStyledItemDelegate. QItemDelegate differs from QStyledItemDelegate in the way it draws and provides editors to views. QStyledItemDelegate draws with the current style and can use Qt Style Sheet. It is recommended to use QStyledItemDelegate as the base class when customizing the delegate .

  Custom delegate classes inherited from QStyledItemDelegate or QItemDelegate need to rewrite and implement the following functions: 

  • Create an editor [createEditor], as the editor used by the user to edit data, accept data from the model, and return the data modified by the user .
[virtual] QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
  • Set editor data [setEditorData]
[virtual] void setEditorData(QWidget *editor, const QModelIndex &index) const
  • Write data to model【setModelData】
[virtual] void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
  • Update editor layout [updateEditorGeometry]
[virtual] void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const

5. Select the model

1. Introduction to QItemSelectionModel

  Selection is a commonly used operation in the view. In the list, tree or table, an item can be selected by clicking the mouse, and the selected item will become highlighted or reversed . In QT, selection also uses a model . In the Model/View architecture, the selection model provides a more general description of the selection operation. For general applications, QT's built-in selection model is sufficient, but QT also allows you to create your own selection model to achieve some special operations.

  QT uses the QItemSelectionModel class to obtain the selection of data items in the view. QItemSelectionModel can keep track of the data items selected in the view. Information about the data items selected in the view is stored in a QItemSelectionModel instance. The model index of the selected data item is independent of all views. When a model sets multiple views, the same selection model can be shared between multiple views to achieve the purpose of synchronous operation. There is always a current data item and a selected data item in the view, they can be the same data item.

  A selection consists of a selection area . The model only records the index positions of the start and end of the selection to ensure good performance for large selections . A non-contiguous selection consists of multiple contiguous selections.

  The standard view classes (QListView, QTreeView, QTableView) provide a default selection model that is sufficient for most applications. A view's selection model can be obtained through the selectionModel() function, and then shared with other views using setSelectionModel(). Therefore, it is generally not necessary to create a new selection model.

  If you need to create a selection area, you need to specify a model and a pair of indexes, and use these data to create a QItemSelection object. Indexes point to the data in the given model, and serve as indices to the upper left and lower right corners of a block selection. In order to apply a selection to a model, the selection needs to be submitted to the selection model. There are several implementations of this operation, with different effects on the existing selection model.

2. Select model application

A. Build a standard data item model and set the setting data

 //构建7行4列的项目模型
QStandardItemModel *model = new QStandardItemModel(7,4,this);
for (int row=0; row < 7; row++)
{
    for (int col=0; col < 4; col++)
    {
        QStandardItem* item = new   QStandardItem(QString("%1").arg(row*4+col));
         //为项目模型添加项目
         model->setItem(row,col,item);
     }
 }

B. Add a view and set the model

//添加视图,并将视图放在窗体中央
QTableview *view = new QTableView;
view->setModel(model);//为视图添加模型
setCentralWidget(view);

C. Get the data item selection model of the view

 QItemSelectionModel * selectionModel = view->selectionModel();

D. Set the selected data item

//定义左上,右下的索引,然后使用这两个索引创建选择
QModelIndex topLeft;
QModelIndex rightBottom;
QModelIndex parentIndex = QModelIndex();
topLeft = model->index(1,1,parentIndex);
rightBottom = model->index(5,2,parentIndex);
//设置被选择的数据项
QItemSelection selection(topLeft, rightBottom);

E. Set selection mode

selectionModel->select(selection,QItemSelectionModel::Select);
QItemSelectionModel::Select:选择所有指定的选区
QItemSelectionModel::Toggle:反向操作
QItemSelectionModel::Deselect:取消指定的已选选区
QItemSelectionModel::Rows:选择行
QItemSelectionModel::Columns:选择列
QItemSelectionModel::Current:将当前选区替换为新的选区
QItemSelectionModel::Clear:取消全部已有选区

F. The choice of the choice model changes the signal

  • Trigger a signal when the selection changes. Will send selected QItemSelection and unselected QItemSelection
[signal] void QItemSelectionModel::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
  • Trigger a signal when the current data item changes. Will send the currently selected QModelIndex and the previous QModelIndex.
[signal] void QItemSelectionModel::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)

G. Select the slot function that changes the signal

  • Select the slot function after the model change
void updateSelection(QItemSelection &selected,QItemSelection &deselected);
void updateSelection(QItemSelection &selected, QItemSelection &deselected)
{
    QModelIndex index;
    QModelIndexList indexList = selected.indexes();
    foreach (index, indexList)
    {
        QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
        view->model()->setData(index,text);
    }
    indexList = deselected.indexes();
    //清空上一次选择的项目内容
    foreach (index, indexList)
    {
        view->model()->setData(index,"");
    }
}
  • Displays the data changes of the current selection
void changeCurrent(const QModelIndex ¤t,const QModelIndex &previous);
void changeCurrent(const QModelIndex ¤t, const QModelIndex &previous)
{
    qDebug() << QString("move(%1,%2)to(%3,%4)")
                .arg(previous.row()).arg(previous.column())
                .arg(current.row()).arg(current.column());
}

H. Connection of signal and slot function

connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),  this,SLOT(updateSelection(QItemSelection&,QItemSelection&)));

connect(selectionModel,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this,SLOT(changeCurrent(QModelIndex,QModelIndex)));

I. Share selection model between views

    QTableView *view2 = new QTableView;
    view2->setWindowTitle("TableView2");
    view2->setModel(model);//设置模型
    view2->setSelectionModel(selectionModel);//设置共同的选择模型
    view2->show();

The article is transferred from the blog garden (Dou ZhanFa Monkey King): Introduction to Model/View Framework-Qt - Fight ZhanFa Monkey King- Blog Garden

The benefits of this article, free to receive Qt development learning materials package, technical video, including (C++ language foundation, introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓See below↓↓Click on the bottom of the article to receive the fee↓↓ 

Guess you like

Origin blog.csdn.net/QtCompany/article/details/132216882