Qt-模型/视图结构

        这是我学习Qt以来碰到的第一个觉得有点难理解的章节,学完一遍了,感觉还是蒙蒙的,但是我有一个理解:模型(Model),是存储数据的,视图(View)是根据Model里的数据来在View上显示的,Model到View是单向的,也就意味着在View上修改数据,并不能直接传输给Model,要通过一个叫代理的东西来传递,代理的存在让Model和View可以双向传输了,当需要在视图上编辑数据时,代理会负责处理视图中的单个项目(item)的显示和编辑,当用户在视图的一个项目上开始编辑时,代理会创建一个编辑器控件(如QLinEdit这个是默认的)并将其显示在视图上,用户在编辑器中修改数据后,代理会将新的数据值传递给Model,Model在更新其内部数据,再通过Model展示在View上

        模型与视图的基本结构包含以下几个部分

源数据(data)是原始数据

视图(View)也被称为视图组件,是界面组件,视图从模型获取数据然后将其显示在界面上,Qt提供一些常用的视图组件,如QListView,QTreeView,QTab了View等。

模型(Model)也被称为数据模型,于源数据通信,并为视图组件提供数据接口,它从源数据提取需要的数据,用于视图组件进行显示和编辑。Qt中有一些预定义的模型类,如QStringListMode是字符串列表模型类,QSqlTableModel是数据库中数据表的模型类。

代理(delegate)为视图和模型之间的交互提供一个临时的编辑器,模型向视图提供数据,但是视图上编辑的数据不能直接提供给模型,要通过一个临时的编辑器,默认是QLineEdit编辑框

        模型索引

        为了确保数据的展示和数据的存取方式分离,模型中引入了模型索引(Model Index)的概念。通过模型能访问的每一个项都有一个模型索引,视图组件和代理都通过模型索引来获取数。

        QModelIndex是表示模型索引的类。模型索引提供访问数据的临时指针,用于通过模型提取或修改数据。因为模型内部组织数据的结构随时改变,所以模型索引是临时的

        行号和列号

        模型的基本形式是用行和列定义的表格数据,但这不意味着底层的数据是用二维数组存储的,使用行和列只是为了组件之间交互方便。一个模型索引包含了行号和列号。要获得一个模型索引,必须提供三个参数:行号,列号,父项的模型索引如

        QModelIndex indexA=model->index(行号,列号,父项);

        父项

        当模型为列表或者表格结构时,使用行号和列号访问数据比较直观,所有项的父项都是顶层项,当模型为树状结构时情况比较复杂(在树形结构中,项一般叫做节点),一个节点有父节点,其也可以是其它节点的父节点,在构造节点的模型索引时必须指定正确的行号,列号和父节点。

        项的角色

        在为模型的一个项设置数据时,可以为项设置不同角色的数据,QAbstractItemModel类定义了设置项的数据的函数setData(),其函数原型定义如下:

bool QAbstractItemModel::setData(const QModelIndex &index,const QVariant &valus,int role=Qt::EditRole)

其中,Index是项的模型索引,value是需要设置的数据,role是设置数据的角色。可以为一个项设置不同角色的数据,角色参数role用枚举类型Qt::ItemDataRole的枚举值表示,枚举类型Qt::ItemDataRole常用的一些枚举值及其含义如下所示

枚举值角色数据类型含义
Qt::DisplayRoleQString界面上显示的字符串,如单元格显示的文字
Qt::DecorationRoleQIcon,QColor在界面上起装饰作用的数据,如图标
Qt::EditRoleQString界面上适合在编辑器中显示的数据,一般是文字
Qt::ToolTipRoleQString项的toolTip字符串
Qt::StatusTipRoleQString项的statusTip字符串(用于在状态栏显示数据)
Qt::FontRoleQFont项的字体,如单元格内文字的字体

还有很多枚举值,需要时再去查文档。在获取一个项的数据时也要指定角色,以获取不同角色的数据。QAbstractItemModel定义了函数Data(),可以返回去一个项的不同角色的数据,其函数原型如下:QVariant QAbstractItemModel::Data(const QModelIndex &Index,int role=Qt::DisplayRole)。

        QAbstractItemModel类

QAbstractItemModel是所有模型类的直接或间接父类,它定义了模型的通用接口函数,同时它也是抽象类,不能直接创建对象实例,各个具体的模型类实现了这些接口函数,以下是常用的接口函数

        1.行数和列数

rowCount()返回行数,columnCount()返回列数,函数原型如下

int rowCount (QModelIndex &parent = QModelIndex());

int columnCount (QModelIndex &parent = QModelIndex());

参数parent,这是父项的模型索引,对于列表模型和表格模型,parent使用默认值即可,得到的行数和列数就是模型的行数和列数,对于树状模型,parent需要设置为父节点的模型索引,函数返回的是父节点下的节点的行数和列数。

        2.插入和删除行

可以用以下的函数在模型中插入或删除一个或者多个数据行。

bool insertRow (int row , const QModelIndex &parent=QModelIndex())

bool insertRows (int row , int count , const QModelIndex &parent=QModelIndex())

bool removeRow (int row , const QModelIndex &parent=QModelIndex())

bool removeRows (int row , int count , const QModelIndex &parent=QModelIndex())

参数parent,这是父项的模型索引,对于列表模型和表格模型,parent使用默认值即可,对于树状模型,parent需要设置为父节点的模型索引。

        3.插入和删除列

可以用以下的函数在模型中插入或删除一个或者多个数据列。

bool insertColumn(int column , const QModelIndex &parent=QModelIndex())

bool insertColumns(int column , int count , const QModelIndex &parent=QModelIndex())

bool removeColumn(int column , const QModelIndex &parent=QModelIndex())

bool removeColumns(int column , int count , const QModelIndex &parent=QModelIndex())

        4.移动行或列

函数moveRow()可以移动一个行,函数moveColumn可以移动一个列。使用这两个函数可以实现表格的行或列的移动以及目录树中的节点移动等操作。

bool moveRow(const QModelIndex &soourceParent , int sourceRow , const QModelIndex &destinationParent , int destinationChild)

bool moveColumn(const QModelIndex &soourceParent , int sourceRow , const QModelIndex &destinationParent , int destinationChild)

        5.数据排序

函数sort()将数据按某一列排序,可以指定排序方式,默认是升序排序

void sort (int column , Qt::SortOrder order=Qt::AscendingOrder)

        6.设置和读取数据

函数setData ()为一个项设置数据,函数data ()返回一个项的数据

bool setData (const QModelIndex &index , const QVariant &value , int role=Qt :: EditRole)

QVariant data (const QModelIndex &index , int role=Qt :: EditRole)

这两个函数都用于模型索引定位项,都需要指定数据的角色。

        7.清楚一个项的数据

函数clearItemData () 用于清楚一个项的所有角色的数据

bool clearItemData (const QModelIndex &index)

QAbstractItemModel 的这些函数一般都是虚函数,子类会重新实现其需要用到的函数,已符合模型类的具体操作。

QAbstractItemView类

        QAbstractItemView 是所有视图组件的父类,它定义了视图组件类共有的一些接口。

        1,关联数据模型和选择模型

需要为视图组件设置数据模型才能构成完整的模型和视图结构,相关函数定义如下;

void setModel (QAbstractItemModel *model)         //设置数据模型

QAbstractItemModel * model()                        //返回关联的数据模型对象指针

不同的视图使用不同类型的模型,QListView组件一般使用QStringListModel 对象作为数据模型,用于编辑字符串列表,QTableView 一般使用QStandardItemModel对象作为数据模型,用于编辑表格数据

提示! 模型用于表示模型和视图结构中的概念,数据模型一般用于表示模型类的具体对象。

视图组件还可以设置选择模型,在界面上选择的项发生变化时,通过选择模型可以获取所有被选择项的模型索引,列如QTableView在允许选择多个单元格时,使用QItemSelectionModel 类对象作为选择模型就比较有用,可以获得所有被选单元格的模型索引,从而能方便地对所选择的项进行处理,相关函数定义如下:

void setSelectionModel (QItemSelectionmodel* selectionModel)  //设置选择模型

QItemSelectionmodel* selectionModel ()       //返回关联的选择模型对象的指针

        2.常用属性

QAbstractItemView 类定义了一些属性,这些属性是子类QListView和QTableView共有的

(1)editTriggers 属性。表示视图组件是否可以被编辑数据,以及进入编辑状态的方式,设置和读取该属性的函数定义如下:

void setEditTriggers (QAbstractItemView :: EditTriggers triggers)

QAbstractItemView::EditTriggers editTriggers()

该属性值是标准类型QAbstractItemView::EditTriggers ,是枚举类型QAbstractItemView::EditTriggers 的枚举值的组合,各枚举值的含义如下。

视图组件类和模型类都没有readonly属性,如果要设置数据是只读的,用函数setEditTriggers()设置视图组件不允许编辑即可

(2)alIternatingRowColors属性。这个属性设置各行是否交替使用不同的背景色,如果设置为true,会使用系统默认的一种颜色,如果要自定义背景色,需要用Qt的样式表。

(3)selectionModel属性,这个属性表示在视图组件上选择项的操作模式,对于QTab了View比较有意义。这个是属性值是枚举类型QAbstractItemView::SelectionMode,有以下几种枚举值

1. SingleSelection(单选模式)

  • 值: 1
  • 描述: 当用户选择一个项目时,任何已经选中的项目都会被取消选择。用户可以通过在点击已选项目时按下 Ctrl 键来取消选择所选项目。

2. ContiguousSelection(连续选择模式)

  • 值: 4
  • 描述: 当用户像通常那样选择一个项目时,选择会被清除,新项目会被选中。但是,如果用户在点击项目时按下 Shift 键,那么当前项目和点击项目之间的所有项目都会根据所选项目的状态被选中或取消选中。

3. ExtendedSelection(扩展选择模式)

  • 值: 3
  • 描述: 当用户像通常那样选择一个项目时,选择会被清除,新项目会被选中。但如果用户在点击项目时按下 Ctrl 键,那么点击的项目会被切换状态,而其他项目保持不变。如果用户在点击项目时按下 Shift 键,那么当前项目和点击项目之间的所有项目都会根据所选项目的状态被选中或取消选中。通过拖动鼠标可以在多个项目上进行选择。

4. MultiSelection(多选模式)

  • 值: 2
  • 描述: 当用户像通常那样选择一个项目时,该项目的选择状态会被切换,而其他项目保持不变。多个项目可以通过拖动鼠标进行切换。

5. NoSelection(无选模式)

  • 值: 0
  • 描述: 物品不能被选择。

最常用的模式是SingleSelection(单选模式)和ExtendedSelection(扩展选择模式)。

(4)selectionBehavior属性,这个属性表示点击鼠标时选择操作的行为,对于QTab了View比较有意义。这个是属性值是枚举类型QAbstractItemView::SelectionBehavior,有以下几种枚举值

  1. QAbstractItemView::SelectItems(默认值):

    • 描述:选择单个项目。用户可以通过点击来选择单个项目,或者使用Shift或Ctrl键来选择多个项目。
  2. QAbstractItemView::SelectRows

    • 描述:选择整行。用户的选择会扩展到整个行,而不是单个项目。
  3. QAbstractItemView::SelectColumns

    • 描述:选择整列。用户的选择会扩展到整个列,而不是单个项目。

        3. 常用接口

QModelIndex CurrentIndex()          //返回当前项的模型索引

void setCurrentIndex(const QModelIndex & Index)  //设置模型索引为index的项为当前项

void selectAll()           //选择视图中所有项

void clearSelection()     //清除所有选项

        4.常用信号

QAbstractItemView定义了几个信号,常用的几个信号定义如下,信号触发条件见注释

void clicked (const QModelIndex &index)               //点击某个项时

void doubleClicked (const QModelIndex &index)   //双击某个项时

void entered (const QModelIndex &index)     //鼠标移动到某个项上时

void pressed (const QModelIndex &index)    //鼠标左键或右键被按下时

这些信号函数都传递了一个模型索引 index ,这是信号触发时的项的模型索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值