首页 > 其他分享 >【Qt之模型视图】3. 视图类及使用

【Qt之模型视图】3. 视图类及使用

时间:2024-01-18 23:31:37浏览次数:35  
标签:Qt 项目 模型 视图 选择 类及 可以 QItemSelectionModel

1. 概念

在MVC架构中,视图通过与模型交互,将数据项进行显示。在此还需要再一次声明,数据的呈现方式可能与底层存储数据项的数据结构完全不同。 数据和显示能够分离,是因为使用了QAbstractItemModel提供了统一接口,和QAbstarctItemView提供了一个标准视图接口,以及使用模型索引提供了一个通用方法表示数据。 视图从模型获取数据,在界面显示,可以自己渲染数据项,也可以使用委托进行渲染。 在使用视图,需要创建一个视图,然后设置模型,如果不设置模型,也可以使用视图,但没内容。 除了呈现数据,视图还处理项之间的导航和部分项目选择。视图还实现基本的用户界面功能,如上下文菜单和拖放。视图可以为项目提供默认的编辑功能,也可以与委托合作提供自定义编辑器。 视图是可以对数据项进行选择的,以下是视图的选择行为和选择模式: 选择行为: image.png 选择模式:

常量 描述
QAbstractItemView::SingleSelection 1 当用户选择一个项目时,任何已经选择的项目都变为未选择。用户可以取消选择所选项目。
QAbstractItemView::ContiguousSelection 4 当用户以通常的方式选择一个项目时,选中的项目将被清除,新项目将被选中。但是,如果用户在单击项时按Shift键,则当前项和所单击项之间的所有项都将被选中或未选中,具体取决于所单击项的状态。
QAbstractItemView::ExtendedSelection 3 当用户以通常的方式选择一个项目时,选中的项目将被清除,新项目将被选中。但是,如果用户在单击项时按下Ctrl键,则被单击的项被切换,而所有其他项保持不变。如果用户在单击项时按Shift键,则当前项和所单击项之间的所有项都被选中或未选中,具体取决于所单击项的状态。可以通过将鼠标拖动到多个项目上来选择它们。
QAbstractItemView::MultiSelection 2 当用户以通常的方式选择一个项目时,该项目的选择状态被切换,而其他项目保持不变。可以通过将鼠标拖动到多个项目上来切换它们。
QAbstractItemView::NoSelection 无法选择项目。

像QTableView和QTreeView,即可以显示数据,还可以显示表头。表头通过QHeaderView类实现,通过QAbstractItemModel::headerData()函数从模型中获取表头数据,之后使用一个标签显示表头信息。可以通过子类化QHeaderView设置标签的显示。

以下是QAbstractItemView的类图: image.png 但以上都是只能使用规范的格式显示数据,如果需要实现比如条形图或者点图显示数据,需要重新实现视图类。

2. Qt提供的视图类

Qt提供了三个现成可用的视图类,以常见于大多数用户的方式来呈现模型中的数据。QListView可以将模型中的项以简单的列表形式或经典的图标视图形式显示。QTreeView将模型中的项显示为列表的层次结构,可以以紧凑的方式表示深层嵌套的结构。QTableView以类似于电子表格应用程序的布局形式将模型中的项呈现为表格形式。 显示如下: image.png 以上标准视图的默认行为对于大多数应用程序来说足够了使用。它们提供基本的编辑功能,并且可以定制以适应更专业的用户界面的需要。

3. 视图使用模型

视图如果要显示数据,需要给视图设置一个模型,然后将数据设置到模型中,这样就可以显示。 如下:

    QStringList numbers;
    numbers << "好运" << "健康" << "友情" << "理想" << "财富";

    QAbstractItemModel *model = new QStringListModel(numbers);


    QListView *view = new QListView;
    view->setModel(model);

image.png

4. 给多个视图设置同一模型

可以给不同视图设置同一个模型,比如:

    QStringList numbers;
    numbers << "好运" << "健康" << "友情" << "理想" << "财富" << "爱情" << "知识" << "才华" << "修养" << "善良";

    QTableView* pView1 = new QTableView();
    QTableView* pView2 = new QTableView();
    QStandardItemModel* pModel = new QStandardItemModel();
    int n = 0;
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 5; ++j) {
            pModel->setItem(i, j, new QStandardItem(numbers.at(n++)));
        }
    }

    pView1->setModel(pModel);
    pView2->setModel(pModel);

而且,对于许多应用程序来说,共享选择模型是可取的。 显示如下: image.png

5. 项目选择

在视图中处理选择项的机制是由QItemSelectionModel类提供的。默认情况下,所有的标准视图都构造自己的选择模型,并以正常的方式与它们交互。视图使用的选择模型可以通过selectionModel()函数获得,替换的选择模型可以通过setSelectionModel()指定。当我们希望为相同的模型数据提供多个一致的视图时,控制视图所使用的选择模型的能力非常有用。 一般来说,除非要对模型或视图进行子类化,否则不需要直接操作选择的内容。但是,如果需要,可以访问选择模型的接口,这在Item视图中的处理选择中进行了探讨。 视图中选定项的信息存储在QItemSelectionModel类的实例中。这个类维护了一个单个模型中项的模型索引,并且与任何视图无关。由于可以有多个视图与一个模型关联,因此可以在视图之间共享选择,允许应用程序以一致的方式显示多个视图。 选择由选择范围指定。通过仅记录所选项的每个范围的起始和结束模型索引,这些范围可以高效地维护有关大量项的信息。通过使用多个选择范围来描述选择,可以构建非连续的项选择。 选择应用于由选择模型保存的模型索引集合。应用的最新项选择被称为当前选择。即使在应用选择之后,通过使用某些类型的选择命令,仍然可以修改选择的效果。

5.1 当前项和选择项

在视图中,总是有一个当前项和一个选定项——两个独立的状态。一个项目可以同时是当前项目和被选中的项目。视图负责确保总是有一个当前项,例如键盘导航需要一个当前项。 以下截图于文档,显示了当前项和选定项的不同: image.png 翻译过来就是: 当前项:

  • 只能有一个当前项目。
  • 通过键导航或单击鼠标按钮可以更改当前项目。
  • 如果按下编辑键F2或双击该项目(如果启用了编辑功能),将编辑当前项目。
  • 当前项目由焦点矩形指示。

选择项:

  • 可以有多个选择项。
  • 当用户与项目交互时,项目的选择状态是设置或不设置的,这取决于几个预定义的模式-例如,单选择,多选择等。
  • 当前项可以与锚点一起使用,以指定应该选择或取消选择的范围(或两者的组合)。
  • 选定的项目用选择矩形表示。

在操作选择时,可以将QItemSelectionModel视为项目模型中所有项目的选择状态的记录。一旦设置了选择模型,就可以选择、取消选择项目集合,或者切换它们的选择状态,而不需要知道哪些项目已经被选中。可以随时检索所有选定项的索引,并且可以通过信号和槽机制通知其他组件选择模型的更改。

5.2 使用选择模型

标准视图类提供了默认的选择模型,可用于大多数应用程序。可以使用视图的selectionModel()函数获取属于该视图的选择模型,并使用setSelectionModel()在多个视图之间共享,因此通常不需要构建新的选择模型。 如下:

    QStandardItemModel *model = new QStandardItemModel(8, 4, this);

    QTableView *table = new QTableView(0);
    table->setModel(model);

    QItemSelectionModel *selectionModel = table->selectionModel();

    QModelIndex topLeft;
    QModelIndex bottomRight;

    topLeft = model->index(0, 0, QModelIndex());
    bottomRight = model->index(5, 2, QModelIndex());

    QItemSelection selection(topLeft, bottomRight);
    selectionModel->select(selection, QItemSelectionModel::Select);

    setCentralWidget(table);

首先获取视图的选择模型selectionModel,要使用选择模型来选择视图中的项,需要指定QItemSelection 和 QItemSelectionModel::SelectionFlag. QItemSelection 是一个选择块,需要指定其左上角和右下角模型索引。要将选择应用于模型中的项,需要将选择提交给选择模型。 image.png

以下是选择标志: QItemSelectionModel::NoUpdate : 不会进行选择。 QItemSelectionModel::Clear : 完整选择将被清除。 QItemSelectionModel::Select : 将选择所有指定的索引。 QItemSelectionModel::Deselect : 将取消选择所有指定的索引。 QItemSelectionModel::Toggle : 根据当前状态选择或取消选择(相反)所有指定的索引。 QItemSelectionModel::Current : 将更新当前选择。 QItemSelectionModel::Rows : 选择指定项所在行的所有项。 QItemSelectionModel::Columns : 选择指定项所在列的所有项。 QItemSelectionModel::SelectCurrent : 为方便起见提供的选择和当前的组合。 QItemSelectionModel::ToggleCurrent : 为方便起见提供的切换和当前的组合。 QItemSelectionModel::ClearAndSelect : 为方便起见提供的清除和选择的组合。

下面代码将显示选择为第三列所有项,如下:

    QStandardItemModel *model = new QStandardItemModel(8, 4, this);

    QTableView *table = new QTableView(0);
    table->setModel(model);

    QItemSelectionModel *selectionModel = table->selectionModel();


    QModelIndex topLeft;
    QModelIndex bottomRight;

    topLeft = model->index(1, 2, QModelIndex());
    bottomRight = model->index(5, 2, QModelIndex());

    QItemSelection selection(topLeft, bottomRight);
    selectionModel->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Columns);

image.png

5.3 遍历选择模型

可以使用selectedIndexes()函数读取存储在选择模型中的模型索引。这将返回一个未排序的模型索引列表,但只要知道它们是为哪个模型而使用,就可以对其进行迭代:

      QModelIndexList indexes = selectionModel->selectedIndexes();
      QModelIndex index;

      foreach(index, indexes) {
          QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
          model->setData(index, text);
      }

标签:Qt,项目,模型,视图,选择,类及,可以,QItemSelectionModel
From: https://blog.51cto.com/u_16417016/9321223

相关文章

  • Qt中支持暗色主题
    在Qt6.5及更高版本中,为了支持暗色主题(darktheme),Qt引入了一些新的特性和概念。主要是通过使用QStyleHints的新属性colorScheme,这个属性可以根据用户的系统偏好设置为Qt::ColorScheme::Light、Qt::ColorScheme::Dark或Qt::ColorScheme::Unknown。这允许应用程序根据用户......
  • QTreeWidget
    一、双击编辑1、定义连接connect(m_treeWidget,&QTreeView::doubleClicked,this,&FileViewPanelCreator::onItemDoubleClicked);connect(m_treeWidget->itemDelegate(),&QAbstractItemDelegate::closeEditor,this,&FileViewPanelCreator::onCloseEd......
  • QT程序多平台下可执行文件的打包方式
    一、简述QT项目开发完成后,需要打包发布程序,在实际生产中不可能把源码发给别人,所以需要将源码打包正可执行文件或者安装程序。二、设置应用图标把ico文件放到源代码目录下,在QT项目中的'.pro'文件中添加自己准备好的ico文件(使用QT默认生成的图标时,可以跳过这一步)  RC......
  • QT之静态函数发送信号
    一、简介由于博主本人是初学者对QT的机制不了解,所以遇到了一个比较大的坑,特此记录一下。我遇到的问题是无法在静态函数中向另外一个类发送信号。解决办法:先将信号发送给同类中的普通函数,然后在从普通函数中发送信号给外部类。二、C与C++中static的用法这里不是介绍QT静态函数信......
  • QT之ARM平台的移植
      在开发板中运行QT程序的基本条件是具备QT环境,那么QT的移植尤为重要,接下载我将和小伙伴们一起学习QT的移植。一、准备材料tslib源码qt-everywhere-src-5.12.9.tar.xz源码arm开发版二、获取安装包tslib源码的git获取地址是:https://github.com/libts/tslib。qt-everywh......
  • python pyqt6 QComboBox 圆角边框
    圆角边框周围显示黑色直角QComboBox 新增如下设定即可xxx_source.view().window().setWindowFlag(Qt.WindowType.NoDropShadowWindowHint)xxx_source.view().window().setWindowFlag(Qt.WindowType.FramelessWindowHint)xxx_source.view().window().setAttribute(Qt.Widge......
  • Qt/C++自定义界面大全/20套精美皮肤/26套精美UI界面/一键换肤/自定义颜色/各种导航界
    一、前言这个系列对应自定义控件大全,一个专注于控件的编写,一个专注于UI界面的编写,程序员有两大软肋,一个是忌讳别人说自己的程序很烂很多bug,一个就是不擅长UI,基本上配色就直接rgb,对于第一点,只要放松心态,直面自己的不足,不断改进,才能问鼎武林至尊。至于第二点,因为程序员擅长的是逻辑......
  • python pyqt6 颜色弹窗 QColorDialog
     defsetColor(self):#避免窗口置顶后,Dialog被主窗口覆盖,所以需要传递self#设定默认颜色使用getColor的第一个参数(使用setCurrentColor不生效)#"选择颜色"为Dialog弹窗的标题#设定QColorDialog.ColorDialogOption.ShowAlphaChanne......
  • vxe-column 表头顺序:数据中改变后,但视图位置不更新
    问题在左树右表的页面中,左侧点击不同的节点,右侧表头会改变。但在某些情况下,数据中表头顺序改变了,但视图中表头位置却没变。如下图所示:尝试数据变了但视图未更新,猜测是vue更新机制导致的,于是把表头数组的赋值改为$set,无效;猜测是右侧表格组件复用导致数据未更新,(但其实vue-de......
  • CH395实现MQTT应用(补充说明)
    本文是对该篇文章的补充CH395+EMQX实现MQTT应用(Windows系统)-lqlq123-博客园(cnblogs.com)1.切换中文版在设置中可以选择EMQX使用语言及样式主题 2.监控主题及消息数据第一种方法:点击左侧监控,下拉可以直接看到所有客户端的数据详情第二种方法:想要监控特......