QT系列教程(18) MVC结构之QItemSelectionModel模型介绍

devtools/2025/3/14 15:47:21/

视频教程

https://www.bilibili.com/video/BV1FP4y1z75U/?vd_source=8be9e83424c2ed2c9b2a3ed1d01385e9

QItemSelectionModel

Qt的MVC结构支持多个View共享同一个model,包括该model的选中状态等。我们可以通过设置QItemSelectionModel,来更改View的选中效果和显示效果。我们创建一个Qt Application项目,在MainWindow的头文件中添加一个QTbaleView*类型的成员 _table_view。然后在构造函数中为这个_table_view设置model

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);QStandardItemModel * model = new QStandardItemModel(7,4,this);for(int row=0; row < 7; row++){for(int column = 0; column < 4; column++){QStandardItem * item = new QStandardItem(QString("%1").arg(row*4+column));model->setItem(row, column, item);}}_table_view = new QTableView;_table_view->setModel(model);setCentralWidget(_table_view);this->resize(800,800);
}

我们创建了一个QStandardItemModel对象,然后为其设置几个Item,最后将这个model设置到tableview中。
我们可以为TableView设置选择的项目,接下来继续在构造函数中补充

    //获取视图的项目选择模型QItemSelectionModel * selection_model =  _table_view->selectionModel();//定义左上角和右下角的索引QModelIndex topLeft;QModelIndex bottomRight;//根据上面两个索引选择项目//第1行1列topLeft = model->index(1,1,QModelIndex());//第5行2列bottomRight = model->index(5,2,QModelIndex());//设置选择区域QItemSelection selection(topLeft, bottomRight);//将选择的区域设置给选择模型, 设置 为选中状态selection_model->select(selection, QItemSelectionModel::Select);

我们从tableview中获取选择模型,然后从根节点下选择第1行1列作为左上索引,选择第5行2列作为右下索引。然后创建选择区域QItemSelection,最后将选择区域这只给选择模型。接下来为了我们为工具栏添加两个动作,为动作绑定两个槽函数,在MainWindow声明文件中添加两个函数的声明

public slots:void getCurrentItemData();void toggleSelection();

在构造函数中将动作和槽函数绑定起来

    ui->mainToolBar->addAction(tr("当前项目"), this, &MainWindow::getCurrentItemData);ui->mainToolBar->addAction(tr("切换选择"), this, &MainWindow::toggleSelection);

实现这两个槽函数, getCurrentItemData获取当前条目的数据信息,toggleSelection实现切换选择的条目

void MainWindow::getCurrentItemData(){auto currentData = _table_view->selectionModel()->currentIndex().data().toString();qDebug() <<tr("当前项目的内容") << currentData;
}void MainWindow::toggleSelection(){//找到根节点下第0行0列的item的索引QModelIndex topLeft = _table_view->model()->index(0,0,QModelIndex());//获取根节点下最大的行号auto max_row = _table_view->model()->rowCount(QModelIndex());//获取根节点下最大的列号auto max_column = _table_view->model()->columnCount(QModelIndex());//根据列号和行号获取最右下角的item的索引QModelIndex bottomRight = _table_view->model()->index(max_row-1, max_column-1, QModelIndex());//设置选择区域QItemSelection curSelection(topLeft, bottomRight);_table_view->selectionModel()->select(curSelection, QItemSelectionModel::Toggle);
}

通过点击切换选择,可以实现选择区域的切换,因为我们设置选择的类型为Toggle,系统会将选中的变为取消选中,将取消选中的变为选中。
切换前
https://cdn.llfc.club/1671529103099.jpg
切换后
https://cdn.llfc.club/1671529287147.jpg
因为默认当前的条目是第1行1列,所以getCurrentItemData会打印他的信息。每一个model都有当前条目和选择条目两个属性。

捕获选择条目的变化

当我们点击鼠标选择一个条目时,当前条目就变为该条目,选择的条目也变为该条目。我们可以通过选择模型发出的selectionChanged信号,获取选择了那些条目的索引,以及取消选择了哪些条目的索引。我们可以通过currentChanged获取当前的条目索引以及变化之前的条目索引。现在MainWindow中添加两个槽函数的声明

public slots:void updateSelection(const QItemSelection& selected, const QItemSelection& deselected);void changeCurrent(const QModelIndex& current, const QModelIndex& previous);

两个槽函数的参数和信号的参数匹配。我们实现changeCurrent,当选择模型的当前索引变化时,打印变化前后的索引行号,列号。

void MainWindow::changeCurrent(const QModelIndex& current, const QModelIndex& previous){qDebug() << tr("move(%1, %2) to (%3, %4)").arg(previous.row()).arg(previous.column()).arg(current.row()).arg(current.column());
}

然后我们实现选择模型的选择条目变化时更新条目的数据

void MainWindow::updateSelection(const QItemSelection& selected, const QItemSelection& deselected){QModelIndex index;QModelIndexList list = selected.indexes();//为现在的选择项目设置值for(int i =0; i < list.size(); i++){QString text = QString("(%1, %2)").arg(list[i].row()).arg(list[i].column());_table_view->model()->setData(list[i], text);}list = deselected.indexes();foreach(index, list){_table_view->model()->setData(index,"");}
}

在MainWindow的构造函数中添加信号和槽函数的链接

    //选择模型的选择条目更改后触发updateSelection函数connect(selection_model, &QItemSelectionModel::selectionChanged, this, &MainWindow::updateSelection);//选择模型的当前项目更改后,关联changeCurrent函数connect(selection_model, &QItemSelectionModel::currentChanged, this, &MainWindow::changeCurrent);

点击某个条目,其他条目的数据都变为空,这个条目被选中,内容修改为行列号
https://cdn.llfc.club/1671530820828.jpg

多个View共享模型

MVC结构最大的好处就是可以通过多个View共享同一个model,这个model的选中状态改变时,多个View的显示效果一致。
在构造函数中添加另一个QTableView

    QTableView * tableView2;tableView2 = new QTableView();tableView2->setWindowTitle("tableView2");tableView2->resize(400,300);tableView2->setModel(model);tableView2->setSelectionModel(selection_model);tableView2->show();

可以看到两个View显示的选中状态是一致的
https://cdn.llfc.club/1671531054879.jpg

源码链接

源码链接
https://gitee.com/secondtonone1/qt-learning-notes


http://www.ppmy.cn/devtools/167060.html

相关文章

双指针算法介绍+算法练习(2025)

一、介绍双指针算法 双指针&#xff08;或称为双索引&#xff09;算法是一种高效的算法技巧&#xff0c;常用于处理数组或链表等线性数据结构。它通过使用两个指针来遍历数据&#xff0c;从而减少时间复杂度&#xff0c;避免使用嵌套循环。双指针算法在解决诸如查找、排序、去重…

详细解析 ListView_GetEditControl()

书籍&#xff1a;《Visual C 2017从入门到精通》的2.3.8 Win32控件编程 环境&#xff1a;visual studio 2022 内容&#xff1a;【例2.28】支持主项可编辑的列表视图控件 说明&#xff1a;以下内容大部分来自腾讯元宝。 ​函数原型 HWND ListView_GetEditControl(HWND hwndL…

不同材质的亚克力材质如何选择?

亚克力的材质根据不同的生产流程、加工&#xff0c;实现不同的效果。 材质的选择是根据设备的使用场景、用户需求、设计效果和功能要求来决定的。 立创面板共提供6种的亚克力&#xff08;PMMA&#xff09;类型可供选择。下面&#xff0c;我们一同看看不同亚克力材质间的区别吧…

用SpringBoot做一个web小案例实现登录

我们在login.html页面输入用户名和密码点击登录&#xff0c;请求访问到/login&#xff0c;然后在login方法里获取User对象&#xff0c;在到UserService的login方法中判断登录&#xff0c;来依照这个逻辑&#xff0c;来完成剩下的功能&#xff1a; <div style"color:re…

基于单片机的智能电表设计(论文+源码)

1 系统整体方案设计 本课题为基于单片机的电子式单项智能电表&#xff0c;在此设计如图2.1所示的系统总体架构&#xff0c;其采用STM32单片机作为主控制器&#xff0c;搭配外设HLW8032模块实现对电压&#xff0c;电流&#xff0c;功率因数&#xff0c;电能消耗等参数进行检测&…

Linux笔记之通配符和正则表达式的区别

Linux笔记之通配符和正则表达式的区别 code review! 参考笔记 1.Linux笔记之通配符和正则表达式的区别 2.C++笔记之C语言中的换行符和转义符 文章目录 Linux笔记之通配符和正则表达式的区别1.通配符概念2.通配符和正则表达式的区别3.C++或C语言中有没有通配符?4.Linux Bash脚…

什么是WMS仓库系统?企业如何选择WMS?浩方动力科技

浩方动力科技-浩方软件认为&#xff0c;仓库管理系统&#xff08;WMS&#xff09;是一个用于管理仓库运营的软件系统。在现代企业的仓库运营中起着至关重要的作用&#xff0c;它是实现仓库高效管理、降低成本、提高服务质量的重要工具。而浩方WMS仓库管理系统列位于浩方企业erp…

【社区投稿】深入再谈智能指针、AsRef引用与Borrow借用

深入再谈智能指针、AsRef引用与Borrow借用 这是一个具有深度的技术主题。每次重温其理论知识&#xff0c;都会有新的领悟。大约 2 年前&#xff0c;我曾就这一技术方向撰写过另一篇短文《从类型转换视角&#xff0c;浅谈Deref<Target T>, AsRef<T>, Borrow<T&g…