Qt mode/view全解一

        作为Qt的业余使用人员,对Qt一直一知半解;最近做个小玩意,要显示一个类似微信好友列表的东东,才发现对mode/view框架完全不懂,在此对MCV模型做一次全面学习,以此记录!

        学习实例来源与Qt自带的例子,目录:Qt5.9.0\Examples\Qt-5.9\widgets\tutorials\modelview。

        =============================================================================================

1.对比标准控件 

标准控件QListWidget、QTreeWidget、QTableWidget,直接存储文本信息等内容(如其他Qt自带标准控件),数据是通过QStandarditem类型一项项添加上去的

Qt mode/view全解一_第1张图片

mod/view模型,实现显示和数据的分离:

     Qt mode/view全解一_第2张图片

这样的好处是用mode来组织数据(其实mode也不存储数据),不同的view都可以展示数据,而且数据是一致的,即只要改变数据,所有的view会自动更新。

1.1.mode/view关系

数据可以是通过各种方式提供的,是底层的;mode对底层数据进行了封装,各种view直接调用mode即可实现数据的显示。

mode的基类是QAbstractItemModel,Qt已经实现了一些类:

    QStringListModel 用于存储简单的QString项目列表。

    QStandardItemModel管理更复杂的树型结构数据项,每项都可以包含任意数据。

    QFileSystemModel提供本地文件系统中的文件与目录信息。

    QSqlQueryModel、QSqlTableModel、QSqlRelationTableModel用来访问数据库。

但是更多的情况,我们需要继承基类,自定义我们自己的类。

1.2.实例一

程序目录结构如下:

Qt mode/view全解一_第3张图片

mymodel.h

#include 

class MyModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    MyModel(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const override ;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};

继承QAbstractTableModel基类,只需实现这三个纯虚函数:

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

mymode.cpp实现这三个方法:

#include "mymodel.h"

MyModel::MyModel(QObject *parent)
    :QAbstractTableModel(parent)
{
}

int MyModel::rowCount(const QModelIndex & /*parent*/) const
{
   return 2;
}

int MyModel::columnCount(const QModelIndex & /*parent*/) const
{
    return 3;
}

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole)
    {
       return QString("Row%1, Column%2")
                   .arg(index.row() + 1)
                   .arg(index.column() +1);
    }
    return QVariant();
}

main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTableView tableView;
    MyModel myModel(0);
    tableView.setModel( &myModel );
    tableView.show();
    return a.exec();
}

main函数定义一个QTableView,只需setMode设置mode即可,mode就是我们自定的mymode。

mymode中的rowCount()告诉view有几行,columnCount()告诉view有几列,data()告诉view要显示的数据!这些都是MV框架自动做的,我们只需要实现这几个函数就行.

运行结果:

Qt mode/view全解一_第4张图片

1.3.data()函数

其中最重要的就是实现data()函数。

每个单元格都会调用data()获取内容,本例6个单元格,但实际上每个单元格都调用了7次data(),为何会调用7次?是因为data()的参数role有7个取值,本例只是显示,是用的Qt::DisplayRole.

关于role:

view中数据格式用mode的角色进行控制,角色是枚举型的enum Qt::ItemDataRole,其中mode使用其中的7中角色(这也是为何每个单元格要调用7次data(),每次调用都是对单元格进行相应的控制),分别是枚举enum Qt::ItemDataRole中的:6、7、9、10、1、0、8

Qt::FontRole     字体

Qt::TextAlignmentRole 对其方式

Qt::ForegroundRole/Qt::TextColorRole 字体颜色

Qt::CheckStateRole  复选框是否选择

Qt::DecorationRole 图像

Qt::DisplayRole 显示

Qt::BackgroundRole/Qt::BackgroundColorRole 背景

具体含义及用法,希望后续会涉及!

第二章会介绍其中几个的用法事例!

 

 

 

你可能感兴趣的:(Qt)