Qt中的模型-视图

  做GUI应用程序开发的同学想必都知道MVC设计模式,MVC即Model-View-Controller,模型-视图-控制器。现我试图将Qt中的“MVC”讲清楚,先从简单的模型-视图说起。

1. 模型-视图基本概念

  模型-视图中,模型用于数据的存放/管理,视图用于数据的显示。模型-视图的核心思想是将模型和视图解耦,即将二者分离:模型对外提供标准接口,通过接口外界可以存取数据,模型不需要关心数据的显示;视图负责定义数据的显示方式,它不需要知道数据的组织存储。模型-视图从概念图上可以直观的理解为:

这里写图片描述

  Qt中提供了几个现成的模型用于处理数据项,当然了,所谓模型其实就是c++中的类。
  (1) QStringListModel:用于存储简单的QString类型数据的列表项
  (2) QStandardItemModel:用于管理组成树形结构存储的数据项,其中每一个数据项可以是任意类型的数据
  (3) QFileSystemModel:用于管理有关本地文件系统的文件和目录信息

  这些模型类都继承自QAbstractTableModel:

这里写图片描述

  同理,Qt也提供了几个现成的视图用于数据显示:
  (1) QListView:列表形式显示模型中的数据项
  (2) QTableView:表格形式显示模型中的数据项
  (3) QTreeView:树形结构显示模型中的数据项

  这些类都继承自QAbstractItemView:

这里写图片描述

2. 模型-视图的工作机制

  模型-视图的工作,主要依赖于信号与槽机制,
  (1) 当数据发生改变时,模型发出信号以通知视图
  (2) 当用户和视图进行交互时,视图发出信号通知模型以提供交互信息

3. 模型定义的索引

  问:视图如何找到模型中的数据?
  前面讲到模型“对外提供标准接口,通过接口外界可以存取”,这个标准的接口就是索引,视图通过模型提供的索引访问模型中的具体数据,也就是说Qt模型中必须为模型中的每一个数据项提供一个独一无二的索引,这是模型-视图中的关键技术。这个索引接口定义在QAbstractItemModel类中,它是一个虚函数:

virtual QModelIndex index(int row,int column, const QModelIndex &parent = QModelIndex()) const = 0;

  该函数的返回的是一个QModelIndex的对象,QModelIndex是Qt模型中的索引类,它其中包含了具体数据访问的途径和一个指向模型的指针:

QVariant data(int role = Qt::DisplayRole) const;    //获取该索引指向的数据,返回值类型QVariant这个后面说
const QAbstractItemModel* model() const;            //获取该索引所在的模型

这里写图片描述

  该函数的返回值不难理解,难以理解的是3个形参。这个得从Qt模型的索引机制讲起。

  Qt中要获取模型中的某个数据项,需要知道3个量:行号、列号、父节点,这3量合称为三元组。索引在需要时由模型实时创建。
视图的分类主要有:行(List)、列表(Table)和树形(Tree)。对应到模型中的数据项的摆放也主要是这3种结构。下面分别对这3种数据组织模型的存取举例。需要说明,对数据的存取不单单是下面所举例的方法,详细内容可参阅Qt Create提供的帮助文档。

  (1) 行结构数据项模型
这里写图片描述
  行结构的数据项存放于QStringListModel模型中,

//Widget.h
class Widget : public QWidget
{
    Q_OBJECT

public:
    QStringListModel m_model;   //列表模型
    QListView m_listview;       //列表视图

    void initListMode();        //列表模型初始化函数
    void initListView();        //列表视图初始化函数

    QPushButton testBtn;        //按钮,用于测试索引数据

public:
    Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void onTestBtnClick();      //按钮槽函数
};

//Widget.cpp
Widget::Widget(QWidget *parent) : QWidget(parent), testBtn(this)
{
    //初始化按钮并连接信号与槽
    testBtn.move(200, 140);
    testBtn.setText("inedx");
    connect(&testBtn, SIGNAL(clicked()), this, SLOT(onTestBtnClick()));

    //初始化模型和视图
    initListMode();
    initListView();

    //将视图和模型挂接
    m_listview.setModel(&m_model);
}

void Widget::initListMode()
{
     m_model.setParent(this);
     QStringList data;
     data << "Hello" << "World" << "Qt";
     m_model.setStringList(data);
}

void Widget::initListView()
{
    m_listview.setParent(this);

    m_listview.move(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值