8.1 概述

8.1 概述

  本节将简要的介绍Qt中的模型视图框架中的模型-视图-代理框架的基本概念,并以一个简单的使用示例来讲解它们。

8.1.1 基本概念

  1.模型(Model)

  Qt中的模型-视图架构中的模型有很多,但无一例外这些模型都基于一个叫做QAbstractItemModel类的类,此类又有QProxyModel、QAbstractListModel、QAbstractTableModel、QAbstractProxyModel、QDirModel、QFileSystemModel、QHelpContentModel和QStandardItemModel这些类来继承。其中QAbstractListModel和QAbstractTableModel则是后面我们将会常常用到的列表模型和表格模型的抽象的基类,如果我们要去实现列表或表格,那么我们就需要继承自这两个类来实现我们自己的类。而完成QStringList存储的QStringListModel继承自QAbstractListModel类(也就是说,QStringList内部的存储实际上是通过QStringListModel来实现的存储的,但QStringListModel又是基于QAbstractListModel类),另外我们的数据库中用到的QSqlQueryModel则是基于QAbstractTableModel来实现的(这也很好理解,因为数据库的模型基本上都是以表作为基础的,而数据库中存储的形式都是用的表来存储的)。而QAbstractProxyModel则是以代理模型的抽象类;QDirModel则是以描述文件和目录的存储的模型。后面我们将以一些例子来介绍这些类的基本使用。

  QAbstractItemModel

  QAbstractListModel

  QAbstractTableModel

  QAbstractProxyModel

  QProxyModel

  QStandradItemModel

  QDirModel

  QFileSystemModel

  QSqlQueryModel

  ...

  2.视图(View)

  视图是Qt的MVC架构中的另外一种重要的角色,而该框架中的所有的视图都基于QAbstractItemView类,此类会派生出例如QColumnView、QHeaderView、QListView、QTableView、QTreeView等类,而QListView是继承自我们所熟知的QUndoView和QListWidget。而QTableView则是继承自QTableWidget;QTreeView则继承自QTreeWidget。而通过我们前面的学习已经知道,形如QListWidget、QTableWidget、QTreeWidget这些类中实际上已经包含了数据的部分,因此可以理解为是模型和视图集成在一起的类。

  QAbstractItemView

  QHeaderView

  QColumnView  

  QListView

  QTableView

  QTreeView

  QUndoView

  3.代理(Delegate)

  同样的,Qt的MVC框架的另一个角色——代理(Delegate)则起到了操作模型中的数据的作用,并且它还能接受来自视图的一些信号,并对其进行响应。而QAbstractItemDelegate类就是所有的MVC架构中的代理类的最基础的抽象类。而QItemDelegate和QStyledItemDelegate就是基于QAbstractItemDelegate类的。而数据库中的QSqlRelationalDelegate又是继承自QItemDelegate的。

  QAbstractItemDelegate

  QItemDelegate

  QStyledItemDelegate

  QSqlRelationalDelegate

8.1.2 模型/视图类

  MVC框架中提供了一些可以直接使用模型类和视图,常见的模型有QStandradItemModel、QDirModel、QFileSystemModel等。而视图则有QColumnView、QHeaderView、QListView、QTableView和QTreeView等。

  案例:使用DirModel并结合QTreeView、QListView、QTableView来实现一个简单的文件浏览器

  (1)新建Qt的GUI项目,项目名称就为DirModelEx。不需要创建UI文件

    (2) 直接在main.cpp中写上以下的代码 

#include "mainwindow.h"

#include <QApplication>
#include <QDirModel>
#include <QListView>
#include <QTreeView>
#include <QTableView>
#include <QSplitter>
#include <QAbstractItemModel>
#include <QAbstractItemView>
#include <QItemSelectionModel>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //1.准备一个Dir的模型
    QDirModel model;//创建一个QDirModel对象,为数据访问做准备,这个DirModel还可以设置过滤器,即只有符合条件的文件或目录才能被访问
    //2.准备着三个视图
    QTreeView treeView;
    QListView listView;
    QTableView tableView;
    //3.将DIR的模型设置到视图上面
    treeView.setModel(&model);
    listView.setModel(&model);
    tableView.setModel(&model);
    //4.设置三种视图对应的可选数据的模型
    treeView.setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);//选择方式为多选,其实还有其他的方式来选择,比如单选
    listView.setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
    tableView.setSelectionMode(listView.selectionMode());
    /*
     * enum SelectionMode {
        NoSelection,//不允许选择项目
        SingleSelection,//用户只能单选一个项目,且当选择一个项目后,其他的项目都会被取消选择的状态,当用户按下Ctrl并单击已经选择的项目时,该项目会被取消其选择状态
        MultiSelection,//支持用户多选多个项目
        ExtendedSelection,//当用户以普通的方式选择一个项目时,原先被选中的项目会被取消其选择状态,并且选择到新项目上,若同时按下Ctrl键,那么只对已经当前所正在选择的项目取消其选中状态,其他已选中的项目不受影响。若按下Shift键,则当前正在选择的项目不会改变其选中状态,而会改变其他已经被选中的项目的选中状态。另外这种模式下支持用户拖动鼠标的方式来选择多个项目
        ContiguousSelection//当用户选择一个项目时,假设该项目已经被选中,那么将会取消该项目的选择并选择其他项目,若用户在选择了当前项目的同时还按下了Shift键,那么用户当前选中的选项的状态会改变,并且其他被选择的项目也会改变(改变会由原来的状态往新的状态改变)
    };
    */
    //5.连接这些视图和视图之间的信号和槽的关系
    QObject::connect(&treeView,&QTreeView::doubleClicked,&listView,&QListView::setRootIndex);
    QObject::connect(&treeView,&QTreeView::doubleClicked,&tableView,&QTableView::setRootIndex);
    //6.布局
    QSplitter*mainSplitter = new QSplitter;//QSplitter默认就是水平布局的
    mainSplitter->addWidget(&treeView);//由于View也是继承自Widget的,所以理所应当可以使用布局器
    mainSplitter->addWidget(&listView);
    mainSplitter->addWidget(&tableView);
    mainSplitter->setWindowTitle(QObject::tr("Model/View Demo"));
    mainSplitter->show();
    return a.exec();
}

  (3)运行后如图所示

  本节项目代码:https://files.cnblogs.com/files/blogs/792763/DirModelEx.zip?t=1719138443&download=true

posted @ 2024-06-23 18:27  蜡笔小新Pointer  阅读(12)  评论(0)    收藏  举报