Qt之模型-视图编程(处理项目视图的选择)

简述

项目视图类使用选择模型提供一种对选择行为的通用描述。

项目的选择状态信息被存储在QItemSelectionModel类的实例中。

QItemSelectionModel维护着选择实体(QItemSelection),选择实体由选择范围构成,一个选择范围只需要起点(start index)和终点(end index)便可唯一确定。非连续的选择选择范围则需要多个选择范围来描述。

提示: 当进行选择操作时,可以将项目视图中使用的选择模型(QItemSelectionModel)看做是项目模型中项目的选择状态监控器

当前项目和被选择的项目

在一个视图中,总有两种独立状态:当前项目、被选择的项目。一定要将两者清楚地区分开。

下面是二者的不同:

当前项目 被选择的项目
只能有一个当前项目 可以有多个被选择的项目
当前项目可以通过键盘按键或者鼠标点击来改变 当用户与项目进行交互时,根据几种预定义模式(例如,单选,多选等)来设置或取消设置项目的选定状态。
如果按下编辑键F2或双击该项目,则当前项目将被编辑(前提是启用了编辑)。 当前项目可与锚点一起使用,以指定应选择或取消选择的范围(或两者的组合)。
当前项目由焦点矩形指示。 所选项目用选择矩形表示。

使用选择模型

标准视图类为大多数应用提供了默认的选择模型。可以通过selectionModel()来获取视图的模型,可以通过setSelectionModel()来设置新的选择模型

通过将一对模型索引传递给QItemSelection来创建一个选择。这对模型索引中,一个表示选择起点,一个表示选择终点。为了将选择应用到项目上,我们还需要将创建的选择提交给选择模型。根据提交时附加的选择模式,最终会出现特定的选择效果。使用方法如下:

    //设置选择起始点
	topLeft = model->index(1, 1, QModelIndex());
    bottomRight = model->index(2, 2, QModelIndex());
	//创建选择
    QItemSelection selection(topLeft, bottomRight);
	//将选择提交给选择模型
    selectionModel->select(selection, QItemSelectionModel::Select);

效果如下:

常见操作

读取选择状态

可以通过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);
      }

效果

通过遍历所有选中的项目,对这些项目进行赋值。

当选择状态改变的时候,选择模型会发出信号来指示这种变化,可以编写相应的槽函数来处理这个信号。下面的代码展示了这样一个槽函数。

void Widget::updateSelection(const QItemSelection &selected,
                             const QItemSelection &deselected) {
    QModelIndex index;
    QModelIndexList items = selected.indexes();

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

    items = deselected.indexes();

    foreach (index, items)
        model->setData(index, "");
}

信号槽绑定:

    connect(selectionModel, &QItemSelectionModel::selectionChanged,this,
            &Widget::updateSelection);

效果

多模式选择

我们通过如下命令来对特定的区域执行特定的操作:

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

其中的QItemSelectionModel::Select来自QItemSelectionModel::SelectionFlag,这个枚举类型定义了像清除、选择、取消选择、反选、整行选择、整列选择等等,这些枚举值也可以进行组合使用,下面举两个例子来说明:

反选操作

      QItemSelection toggleSelection;

      topLeft = model->index(2, 1, QModelIndex());
      bottomRight = model->index(7, 3, QModelIndex());
      toggleSelection.select(topLeft, bottomRight);

      selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);

整行整列选择

      QItemSelection columnSelection;

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

      columnSelection.select(topLeft, bottomRight);

      selectionModel->select(columnSelection,
          QItemSelectionModel::Select | QItemSelectionModel::Columns);

      QItemSelection rowSelection;

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

      rowSelection.select(topLeft, bottomRight);

      selectionModel->select(rowSelection,
          QItemSelectionModel::Select | QItemSelectionModel::Rows);

效果

虽然我们只选择了四个条目,但是这四个条目所在的整行整列都被选取了。

全选操作

全选是一种十分常见的操作,实现方法如下:

      QModelIndex parent = QModelIndex();
      QModelIndex topLeft = model->index(0, 0, parent);
      QModelIndex bottomRight = model->index(model->rowCount(parent)-1,
          model->columnCount(parent)-1, parent);
      QItemSelection selection(topLeft, bottomRight);
      selectionModel->select(selection, QItemSelectionModel::Select);

对于层级结构,hasChildren()函数被用来判断给定的项目是否是另一些项目的父代。

引用

[1] Qt助手

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章