拉不拉稀肚拉稀 发表于 2024-3-4 20:52:34

C++ Qt开发:TableView与TreeView组件联动

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableView与TreeView组件联动的常用方法及灵活运用。
本章我们继续实现表格的联动效果,当读者点击TableView或TreeView中的某一行时,我们让其实现自动跟随功能,且当用户修改行中特定数据时也让其动态的跟随改变,首先绘制一个主界面如图,分别放置两个组件框,底部保留两个按钮,按钮1用于该表表格的行列个数,按钮2则用于设置TableView表格表头参数,整个表格我们将其设置为可编辑状态。
https://img2023.cnblogs.com/blog/1379525/202312/1379525-20231227140204354-480684471.png
在函数中我们需要定义一个QStandardItemModel模型,这个模型的作用在之前的文章中有具体介绍,它是一个灵活且功能强大的模型类,适用于需要自定义数据结构、支持编辑、表头等功能的场景。通常用于与视图组件(如 QTableView、QTreeView 等)一起使用。它提供了一个表格结构,可以包含行和列,每个单元格可以存储一个 QStandardItem 对象。
这里的QStandardItemModel只适用于将两个不同类型的组件进行关联,简单点来说就是将两个组件指向同一个数据容器内,这样当用户修改任意一个组件内的数据另一个组件也会同步发生变更,但要想实现联动则还需要使用QItemSelectionModel模型,它负责跟踪哪些项被选中,以及在模型中项的选择状态发生变化时发出信号。
以下是 QItemSelectionModel 的一些重要特性和方法:

[*]选择项: 负责管理模型中的项的选择状态,可以单独选择项、选定范围内的项或清除所有选择项。
[*]信号: 当选择状态发生变化时,QItemSelectionModel 会发出相应的信号,如 selectionChanged 信号。
[*]选择模式: 提供多种选择模式,包括单选、多选、扩展选择等,可通过设置 SelectionMode 进行配置。
[*]选择策略: 提供多种选择策略,用于定义选择行为,如 SelectItems、SelectRows、SelectColumns 等。
[*]与视图的集成: 通常与 QTableView、QTreeView 等视图组件结合使用,以实现对视图中项的选择操作。
该组件是实现模型-视图架构中选择的关键组件。通过它,可以轻松管理和操作模型中的项的选择状态,实现各种灵活的用户交互。下面是 QItemSelectionModel 类的一些主要方法:
方法描述QItemSelectionModel(QAbstractItemModel *model, QObject *parent = nullptr)构造函数,创建一个与指定模型关联的 QItemSelectionModel 对象。QModelIndexList selectedIndexes() const获取当前被选中的项的索引列表。void clear()清除所有的选择项。void setSelectionMode(QItemSelectionModel::SelectionFlags mode)设置选择模式,可以选择多个项、单个项等。void setSelectionBehavior(QItemSelectionModel::SelectionBehavior behavior)设置选择策略,如选择单个项、选择整行、选择整列等。void select(const QModelIndex &topLeft, const QModelIndex &bottomRight, QItemSelectionModel::SelectionFlags command)在指定范围内进行选择操作,使用 SelectionFlags 定义选择操作。void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)当选择状态发生变化时发出的信号,可以通过连接这个信号来处理选择状态变化的事件。bool hasSelection() const判断是否有选中的项。上述方法提供了管理选择项的一些基本操作,包括清除选择、获取选中项的索引、设置选择模式和策略,以及在指定范围内进行选择操作。
在MainWindow构造函数中,我们以此执行如下关键部分,来实现对主界面的初始化工作;
创建模型和选择模型
首先创建一个包含4行5列的 QStandardItemModel 模型,并为其创建了一个 QItemSelectionModel 选择模型。
model = new QStandardItemModel(4, 5, this);
selection = new QItemSelectionModel(model);关联到 tableView 和 treeView
将模型和选择模型关联到 tableView 和 treeView 上,这样它们会共享同一份数据模型,也就是无论两个组件哪一个发生变化均会影响双方组件中的内容。
ui->tableView->setModel(model);
ui->tableView->setSelectionModel(selection);

ui->treeView->setModel(model);
ui->treeView->setSelectionModel(selection);添加表头与初始化数据
创建一个包含列名的 HeaderList 字符串列表,并将其设置为模型的水平表头标签。继续创建一个包含三个字符串列表的数组 DataList,每个列表代表一行数据。然后使用嵌套的循环遍历数组,将数据逐个添加到模型中。
QStringList HeaderList;
HeaderList << "序号" << "姓名" << "年龄" << "性别" << "婚否";
model->setHorizontalHeaderLabels(HeaderList);

QStringList DataList;
QStandardItem *Item;

DataList << "1001" << "admin" << "24" << "男" << "是";
DataList << "1002" << "lyshark" << "23" << "男" << "否";
DataList << "1003" << "lucy" << "37" << "女" << "是";运行程序,并点击左侧第一个按钮,此时我们可以将表格设置为6*6的矩阵,如下图所示;
https://img2023.cnblogs.com/blog/1379525/202312/1379525-20231227151806804-648412780.png
DIalogHead.ui
对于第二个按钮on_pushButton_2_clicked的功能实现与第一个按钮完全一致,该按钮主要实现对父窗体中TableView的表头进行重新设置,在弹出对话框之前,需要将当前表头元素复制到strList列表容器内,并通过使用子对话框中的ptr->setHeaderList将其拷贝到子对话框中,并通过QDialog::Accepted等待对话框按下修改按钮,如下代码所示;
int Array_Length = DataList->length();               // 获取每个数组中元素数
int Array_Count = sizeof(DataList) / sizeof(DataList);      // 获取数组个数

for(int x=0; x<Array_Count; x++)
{
    for(int y=0; y<Array_Length; y++)
    {
      Item = new QStandardItem(DataList);
      model->setItem(x, y, Item);
    }
}当读者按下了修改按钮之后,由于通过ui->listView->setModel(model)已经与父窗体建立了关联,则此时通过model->setStringList(headers)就可以实现对父窗体中数据的修改,代码如下所示;
void MainWindow::on_pushButton_clicked()
{
    // //模态对话框,动态创建,用过后删除
    DialogSize *ptr = new DialogSize(this);   // 创建一个对话框
    Qt::WindowFlags flags = ptr->windowFlags(); // 需要获取返回值
    ptr->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint);// 设置对话框固定大小
    ptr->setRowColumn(model->rowCount(),model->columnCount());      // 对话框数据初始化

    int ref = ptr->exec();             // 以模态方式显示对话框
    if (ref==QDialog::Accepted)      // OK键被按下,对话框关闭
    {
      // 当BtnOk被按下时,则设置对话框中的数据
      int cols=ptr->columnCount();
      model->setColumnCount(cols);

      int rows=ptr->rowCount();
      model->setRowCount(rows);
    }

    // 最后删除释放对话框句柄
    delete ptr;
}程序运行后,读者可以先将表格的行与列修改为7*7,接着再通过设置表头的方式更新表头,效果如下;
https://img2023.cnblogs.com/blog/1379525/202312/1379525-20231227153043123-552772770.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: C++ Qt开发:TableView与TreeView组件联动