• (转)Qt Model/View 学习笔记 (六)——在views中选择数据项


    在views中选择数据项

    概念

    用于新的view类中的选择模型比Qt3中的模型有了很大的改进。它为基于model/view架构的选择提供了更为全面的描述。尽管对提供了的views来说,负责操纵选择的标准类已经足以应付,但是你也可以创建特定的选择模型来满足你特殊的需求。

    关于在view被选择的数据项的信息保持在QItemSelectionModel类的实例中。它也为每个独立的model中的数据项维护model indexes信息,与任何views都关联关系。既然一个model可用于多个views,那么在多个views之间共享选择信息也是可以做到的,这使得多个views可以以一致的方式进行显示。

    选择由多个选择范围组成。通过仅仅记录开始model indexes与结束model indexes,最大化地记录了可以选择的范围。非连续选择数据项由多个选择范围来描述。选择模型记录model indexes的集合来描述一个选择。最近选择的数据项被称为current selection。应用程序可以通过使用某种类型的选择命令来修改选择的效果。

    在进行选择操作时,可以把QItemSelectionModel看成是model中所有数据项选择状态的一个记录。一旦建立一个选择模型,所有项的集合都可以选择,撤消选择,或者选择状态进行切换而不需要知道哪个数据项是否已经被选择过。所有被选择的项的indexes在任何时候都可以得到,通过信号槽机制可以通知别的组件发生的变化。

    使用选择模型

    标准view类提供了缺省的选择模型,它们可以在大次数程序中使用。一个view中的选择模型可以通过调用view的函数selectionModel()取得,也可以通过setSelectionModel()在多个views之间共享选择模型,因此总的来说构建一个新的模型一般情况不太必要。

    通过给QItemSelection指定一个model,一对model indexes,可以创建一个选择。indexes的用法依赖于给定的model,这两个indexes被解释成选择的区块中的左上角项和右下角项。model中的项的选择服从于选择模型。

    选择项

    构建一个table model ,它有32个项,用一个table view进行显示:

         TableModel *model = new TableModel(8, 4, &app);

         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);

    结果如下:

    QTreeView - zhengjiu_520 - !snows snowy world!

    读取选择状态

    存储在选择模型中indexes可以用selectionIndexes()函数来读取。它返回一个未排序的model indexes列表,我们可以遍历它,如果我们知道他们关联于哪个model的话。

        QModelIndexList indexes = selectionModel->selectedIndexes();

         QModelIndex index;

         foreach(index, indexes) {

             QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());

             model->setData(index, text);

         }

    选择模型在选择发生变化时会发出信号。这用于通知别的组件包括整体与当前焦点项所发生的变化。我们可以连接selectionChanged()信号到一个槽,检查当信号产生时哪些项被选择或被取消选择。这个槽被调用时带有两个参数,它们都是QItemSelection对象,一个包含新被选择的项,另一个包含新近被取消选择的项。下面的代码演示了给新选择的项添加数据内容,新近被取消选择的项的内容被清空。

    void MainWindow::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, "");

     }

    也可以通过响应currentChanged()信号来跟踪当前焦点项.对应的槽就有两个接收参数,一个表示之前的焦点,另一个表示当前的焦点。

    void MainWindow::changeCurrent(const QModelIndex &current,

         const QModelIndex &previous)

     {

         statusBar()->showMessage(

             tr("Moved from (%1,%2) to (%3,%4)")

                 .arg(previous.row()).arg(previous.column())

                 .arg(current.row()).arg(current.column()));

     }

    更新选择

    选择指令是通过选择标志提供的,它被定义在QItemSelectionModel::SelectionFlag中。常用的有Select标记,Toggle标记,Deselect标记,Current标记,Clear标记,其意义一目了然。沿上面例子的结果执行以下代码:

         QItemSelection toggleSelection;

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

         bottomRight = model->index(7, 3, QModelIndex());

         toggleSelection.select(topLeft, bottomRight);

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

    结果如下:

    QTreeView - zhengjiu_520 - !snows snowy world!

    缺省情况下,选择指令只针对单个项(由model indexes指定)。然而,选择指令可以通过与另外标记的结合来改变整行和整列。举例来说,假如你只使用一个index来调用select(),但是用Select标记与Rows标记的组合,那么包括那个项的整行都将被选择。看以下示例:

         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);

    结果如下

    QTreeView - zhengjiu_520 - !snows snowy world!

    选择模型中所有项

    为了选择model中的所有项,必须先得创建一个选择,它包括当前层次上的所有项:

         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);

    顶级index可以这样:

    QModelIndex parent = QModelIndex();

    对具有层次结构的model来说,可以使用hasChildren()函数来决定给定项是否是其它项的父项。

  • 相关阅读:
    Python3练习题 026:求100以内的素数
    【Python3练习题 025】 一个数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同
    Python3练习题 022:用递归函数反转字符串
    Python3练习题 021:递归方法求阶乘
    【Python3练习题 020】 求1+2!+3!+...+20!的和
    【Python3练习题 019】 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
    Python3练习题 018:打印星号菱形
    Python3练习题 006 冒泡排序
    【Python3练习题 017】 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比。请编程序找出三队赛手的名单。
    【Python3练习题 016】 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
  • 原文地址:https://www.cnblogs.com/takeaction/p/3662273.html
Copyright © 2020-2023  润新知