Qt中Model/View结构

Qt中Model/View结构

Model/View框架的核心思想是模型(数据)与视图(显示)相分离,模型对外提供标准接口存取数据,不关心数据如何显示,视图自定义数据的显示方式,不关心数据如何组织存储。

Model/View框架中数据与显示的分离,可以允许使用不同界面显示同一数据,也能够在不改变数据的情况下添加新的显示界面。为了处理用户输入,引入了委托(delegate)。引入委托的好处是可以自定义数据项的渲染和编辑。

模型必须为每一个数据提供独一无二的索引,视图通过索引访问模型中的数据。

模型与数据源进行交互,为框架中其它组件提供接口。交互的本质在于数据源的类型以及模型的实现方式。视图从模型获取模型索引,通过将模型索引反向传给模型,视图又可以从数据源获取数据。在标准视图中,委托渲染数据项;在需要编辑数据时,委托使用直接模型索引直接与模型进行交互。

Model/View架构分为三部分:模型、视图和委托。每一个组件都由一个抽象类定义,抽象类提供了基本的公共接口以及一些默认实现。

模型、视图和委托使用信号槽进行交互:

A、底层维护的数据发生改变时,模型发出信号通知视图

B、当用户与视图进行交互时,视图发出信号提供了有关用户与界面进行交互的信息

C、当用户编辑数据项时,委托发出信号用于告知模型和视图编辑器的状态。

所有的模型都是QAbstractItemModel的子类。QAbstractItemModel类定义了供视图和委托访问数据的接口。模型并不一定存储数据本身。QAbstractItemModel提供的接口足够灵活,足以应付以表格、列表和树的形式显示的数据。如果要为列表或者表格设计自定义的模型,直接继承QAbstractListModel和QAbstractTableModel类会更好,因为这两个类已经实现了很多通用函数。

QT内置了多种标准模型:

QStringListModel:存储简单的字符串列表

QStandardItemModel:可以用于树结构的存储,提供了层次数据

QFileSystemModel:本地系统的文件和目录信息

QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel:存取数据库数据

代码示例:

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QSplitter splitter;

    QStandardItemModel listModel;
    QStandardItem *rootItem = listModel.invisibleRootItem();
    for (int row = 0; row < 4; ++row) {
        QStandardItem *item = new QStandardItem(QString("%0").arg(row) );
        rootItem->appendRow( item );
    }
    QListView listView;
    listView.setModel ( & listModel );
    splitter.addWidget( & listView );

    QStandardItemModel tableModel(4, 4);
    for (int row = 0; row < 4; ++row) {
        for (int column = 0; column < 4; ++column) {
            QStandardItem *item = new QStandardItem(QString("%0,%1").arg(row).arg(column));
            tableModel.setItem(row, column, item);
        }
    }
    QTableView tableView;
    tableView.setModel( & tableModel );
    splitter.addWidget( & tableView );

    QStandardItemModel treeModel;
    QStandardItem *parentItem = treeModel.invisibleRootItem();
    for (int i = 0; i < 4; ++i) {
        QStandardItem *item = new QStandardItem(QString("%0").arg(i));
        parentItem->appendRow(item);
        parentItem = item;
    }
    QTreeView treeView;
    treeView.setModel( & treeModel );
    splitter.addWidget(& treeView );

    splitter.show();
    return app.exec();
}

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

你可能感兴趣的:(Qt开发,qt)