alexltr的个人主页

http://www.qtcn.org/bbs/u/107032  [收藏] [复制]

alexltr

我不是IT,只是喜欢Qt。 我不是程序员,只是与程序有缘。

  • 26

    关注

  • 60

    粉丝

  • 150

    访客

  • 等级:骑士
  • 身份:论坛版主
  • 总积分:537
  • 男,1976-01-01
  • 广州

最后登录:2024-04-20

更多资料

日志

Model/View Programming 模型与视图编程 -- <5>

2012-04-29 14:16
Handling selections in item views  
项视图的选择处理


Concepts
概念

The selection model used in the item view classesoffers many improvements over the selection model used in Qt 3. It provides amore general description of selections based on the facilities of themodel/view architecture. Although the standard classes for manipulatingselections are sufficient for the item views provided, the selection modelallows you to create specialized selection models to suit the requirements foryour own item models and views.
项视图类中使用的选择模型较Qt3中的选择模型有了很多的改进。它提供了一个基于模型/视图架构的更为通用的选择描述。虽然项视图提供的处理选择的标准类已经是很充足,但是你仍可以建立专门的选择模型以适应你自己的模型和视图的需要。

Information about the items selected in a view isstored in an instance of the QItemSelectionModel class. This maintains model indexes for items in a single model, andis independent of any views. Since there can be many views onto a model, it ispossible to share selections between views, allowing applications to showmultiple views in a consistent way.
视图中关于被选择项的信息存储在QItemSelectionModel类的一个实例中。它保存一个单个模型中项的模型索引,并且独立于任何视图。因为一个模型可以用于很多视图,所以项视图共用选择也是可行的,这样应用程序就可以以一致的方式显示多个视图。

Selections are made up of selection ranges. These efficientlymaintain information about large selections of items by recording only thestarting and ending model indexes for each range of selected items.Non-contiguous selections of items are constructed by using more than oneselection range to describe the selection.
选择由选择范围构成。只要记录选择项范围开始及结束的模型索引,就可以有效地包含大量选择项的信息。非连续选择要使用多个选择范围来进行描述。

Selections are applied to a collection of modelindexes held by a selection model. The most recent selection of items appliedis known as the currentselection. The effects of this selection can bemodified even after its application through the use of certain types ofselection commands. These are discussed later in this section.
选择是指由选择模型来保留模型索引的一个集合。前面我们使用过的项选择就是current selection。通过使用某种类型的选择命令我们甚至可以修改这个选择的效果。这些会在本节的后面讨论。

Currentitem & selected items
当前项和被选择项

In a view, there is always a current item and aselected item - two independent states. An item can be the current item andselected at the same time. The view is responsible for ensuring that there isalways a current item as keyboard navigation, for example, requires a currentitem.
The table below highlights the differences betweencurrent item and selected items.
在一个视图中总是有一个当前项和一个被选择的项—两种独立的状态。一个项可以同时是当前项和被选择项。例如,当使用键盘导航时,视图负责确保当中总是有一个当前项。
下面的表格列出了当前项与被选择项的不同之处。

Current Item当前项
Selected Items被选择项
There can only be one current item.
视图中只能有一个当前项
There can be multiple selected items.
视图中可以有多个被选择的项
The current item will bechanged with key navigation or mouse button clicks.
使用键盘导航或鼠标点击会改变当前项。
The selected state of itemsis set or unset, depending on several pre-defined modes - e.g., singleselection, multiple selection, etc. - when the user interacts with the items.
当用户交互作用于项时,项选择状态的设定或者撤销要看几个预定义的模式而定—如单选,多选等。
The current item will beedited if the edit key, F2,is pressed or the item is double-clicked (provided that editing is enabled).
如果视图允许编辑,当按F2或双击项时,就可以编辑当前项。
The current item can be usedtogether with an anchor to specify a range that should be selected ordeselected (or a combination of the two).
当前项被用作一个支撑点来定义一个选择或反向选择(或两者的混合)的范围。
The current item isindicated by the focus rectangle.
当前项由焦点矩形标注。
The selected items areindicated with the selection rectangle.
被选择的项由选择矩形标注。

When manipulating selections, it is often helpfulto think of QItemSelectionModel as a record of the selection state of all the items in an itemmodel. Once a selection model is set up, collections of items can be selected,deselected, or their selection states can be toggled without the need to knowwhich items are already selected. The indexes of all selected items can beretrieved at any time, and other components can be informed of changes to the selectionmodel via the signals and slots mechanism.
在处理选择时,考虑使用QItemSelectionModel来记录一个项模型中所有项的选择状态是很有帮助的。只要建立一个选择模型,项的集合就可以选择,撤销选择,或者反向选择,而不需要知道哪些项已经被选择。任何时候都可以提取所有被选择项的索引,同时通过信号和槽机制,其他的部件也可以知道选择模型的变动。

Using a selection model
使用选择模型

The standard view classes provide defaultselection models that can be used in most applications. A selection modelbelonging to one view can be obtained using the view's selectionModel() function, and shared between many views with setSelectionModel(), so theconstruction of new selection models is generally not required.
标准视图类提供了大多数应用程序都可以使用的默认选择模型。一个视图所使用的选择模型可以通过视图的selectionModel()函数取得,用setSelectionModel()函数可以在多个视图中共用同一选择模型,所以一般不需要构造新的选择模型。

A selection is created by specifying a model, anda pair of model indexes to a QItemSelection. This uses the indexes to refer toitems in the given model, and interprets them as the top-left and bottom-rightitems in a block of selected items. To apply the selection to items in a modelrequires the selection to be submitted to a selection model; this can beachieved in a number of ways, each having a different effect on the selectionsalready present in the selection model.
指定一个模型,同时为QItemSelection指定一对模型索引,就可以建立一个选择。它使用索引指向指定模型中的项,并把它们解释成一个选择项方块中左上角和右下角的项。要把这个选择应用于模型里的项,必须把这个选择提交给选择模型;它可以通过多种方法实现,每一种方法在显示选择模型的选择都有不同的效果。

Selecting items  
选择项

To demonstrate some of the principal features ofselections, we construct an instance of a custom table model with 32 items intotal, and open a table view onto its data:
为了演示选择的一些基本特征,我们构造了一个共有32个项的自定义表格模型的实例,并且用一个表格视图显示它的数据。
    
  1.      TableModel *model = newTableModel(8, 4, &app);
         QTableView *table = newQTableView(0);
        table->setModel(model);
         QItemSelectionModel*selectionModel = table->selectionModel();

The table view's default selection model isretrieved for later use. We do not modify any items in the model, but insteadselect a few items that the view will display at the top-left of the table. Todo this, we need to retrieve the model indexes corresponding to the top-leftand bottom-right items in the region to be selected:
提取视图的默认选择模型以备后用。我们不修改模型里的任何项,而是选择一些显示在视图左上角的项。要达到这个效果,我们要提取选择区域中左上角及右下角相应的模型索引:

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


To select these items in the model, and see thecorresponding change in the table view, we need to construct a selection objectthen apply it to the selection model:
要选择模型中的这些项,并看到视图上相应的变化,我们需要构造一个选择对象,并把它应用于选择模型:

  
  1.   QItemSelectionselection(topLeft, bottomRight);
      selectionModel->select(selection,QItemSelectionModel::Select);



The selection is applied to the selection modelusing a command defined by a combination of selection flags. In this case,the flags used cause the items recorded in the selection object to be includedin the selection model, regardless of their previous state. The resultingselection is shown by the view.
通过使用一个selectionflag组合定义的命令就可以将选择应用于选择模型。在这个例子中,不管项的原来的状态是怎样,它使用的flags标识会使选择对象记录的项都包含在这个选择模型中。选择的结果由视图显示。


The selection of items can be modified usingvarious operations that are defined by the selection flags. The selection thatresults from these operations may have a complex structure, but it isrepresented efficiently by the selection model. The use of different selectionflags to manipulate the selected items is described when we examine how toupdate a selection.
项的选择可以通过由选择标识定义的不同操作进行修改。由此而产生的选择结果可能有一个复杂的结构,但是它能通过选择模型被有效地呈现。使用不同选择标识来处理选择项的内容将在如何更新选择这一小节中讲解。

Readingthe selection state
读取选择状态

The model indexes stored in the selection modelcan be read using the selectedIndexes() function. This returns an unsorted list of model indexes that we caniterate over as long as we know which model they are for:
储存在选择模型里的模型索引可以通过 selectedIndexes()函数读取。它返回一个未排序的模型索引列表,只要我们知道这些模型索引属于哪一个模型,就可以历遍这些选择项。

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

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




The above code uses Qt's convenient foreachkeyword toiterate over, and modify, the items corresponding to the indexes returned bythe selection model.
以上代码使用Qt便捷的foreach关键字来历遍及修改选择模型返回的索引所对应的项。

The selection model emits signals to indicatechanges in the selection. These notify other components about changes to boththe selection as a whole and the currently focused item in the item model. Wecan connect the selectionChanged() signal to a slot, and examine the items in the model that areselected or deselected when the selection changes. The slot is called with two QItemSelection objects: one contains a list of indexes that correspond to newlyselected items; the other contains indexes that correspond to newly deselecteditems.
选择模型发射信号以表明选择的变动。这些信号通知其它部件关于项模型中整体选择及当前焦点项的改变。我们可以把selectionChanged()信号连接到一个槽,当选择改变时,就可以检查模型中被选择或撤销选择的项。这个槽的呼叫要用到两个QItemSelection对象:一个包含新选择项对应的索引列表,另一个包含新撤销选择项的对应索引列表。

In the following code, we provide a slot thatreceives the selectionChanged() signal, fills in the selected items with a string, and clears thecontents of the deselected items.
以下代码我们提供一个接受selectionChanged() 信号的槽,用一个字符串填满选择的项,并清除撤销选择项的内容。

  1. void MainWindow::updateSelection(constQItemSelection &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, "");
    }



We can keep track of the currently focused item byconnecting the currentChanged() signal to a slot that is called with two model indexes. Thesecorrespond to the previously focused item, and the currently focused item.
将 currentChanged()信号连接到一个引用两个模型索引的槽函数,我们就能够保持对当前焦点项的跟踪。这两个索引分别对应前一个焦点项和当前焦点项。
In the following code, we provide a slot thatreceives the currentChanged() signal, and uses the information provided to update the status barof aQMainWindow:
下面的代码我们提供一个接受currentChanged()的槽,并使用提供的信息更新QMainWindow的状态栏:

  1. voidMainWindow::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()));
    }



Monitoring selections made by the user is straightforward with these signals, but we can also update the selection modeldirectly.
用户通过这些信号对选择进行监控,但是我们也可以直接更新选择模型。

Updating aselection  
更新选择

Selection commands are provided by a combinationof selection flags, defined by QItemSelectionModel::SelectionFlag.Each selection flag tells the selection model how to update its internal recordof selected items when either of the select() functions are called. The most commonly used flag is the Select flag which instructs the selection model to record the specifieditems as being selected. The Toggle flag causes the selection model to invert the state of the specifieditems, selecting any deselected items given, and deselecting any currentlyselected items. The Deselect flag deselects all the specified items.
选择是通过QItemSelectionModel::SelectionFlag定义的一个选择标识组合来执行的。当任何一个select()函数被呼叫时,每一个选择标识就会通知选择模型应怎样更新选择项的内部记录。最常用的标识就是Select,它指示选择模型把指定的项记录为被选中的状态。Toggle标识使选择模型转换指定项的状态,选择原来没有选中的项,撤销对当前选择项的选择。Deselect标识撤销对指定项的选择。

Individual items in the selection model areupdated by creating a selection of items, and applying them to the selectionmodel. In the following code, we apply a second selection of items to the tablemodel shown above, using the Toggle command to invert the selection state of the items given.
选择模型里的单个项可以通过建立一个选择项,然后把这些选择项应用到选择模型来更新。在下面的代码中,我们把第二个选择项应用于前面的表格模型,然后用Toggle 指令来转换指定项的选择状态。

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

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


The results of this operation are displayed in thetable view, providing a convenient way of visualizing what we have achieved:
这个操作的结果显示在下面的表格视图中,它直观地显示了我们达到的效果:

By default, the selection commands only operate onthe individual items specified by the model indexes. However, the flag used todescribe the selection command can be combined with additional flags to changeentire rows and columns. For example if you call select() with only one index, but with a command that is a combination of Select and Rows, the entire row containing the item referred tois selected. The following code demonstrates the use of the Rowsand Columns flags:
默认情况下,选择指令只对模型索引指定的单个项进行操作。然而,用于描述选择指令的标识可以跟额外的标识搭配使用,以改变整行和整列的选择。例如,如果你用一个索引呼叫select(),但是跟一个有Select和Rows组合的指令使用,该项所在的整行都会被选择。下面的代码演示了Rows和 Columns的使用:

  
  1.    QItemSelectioncolumnSelection;

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

        columnSelection.select(topLeft, bottomRight);

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

         QItemSelectionrowSelection;

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

        rowSelection.select(topLeft, bottomRight);

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


Although only four indexes are supplied to theselection model, the use of the Columns and Rows selection flags means that two columns and two rows are selected.The following image shows the result of these two selections:
虽然只指定了四个索引给选择模型,但Columns 和 Rows 选择标识的使用意味着选择了两列和两行。下图显示了这两个选择的结果:

The commandsperformed on the example model have all involved accumulating a selection ofitems in the model. It is also possible to clear the selection, or to replacethe current selection with a new one.
应用于本例模型的命令全部都是涉及累积模型中项的选择的。其实它还可以清除选择,或者是以新的选择替换当前的选择。

To replace the current selection with a newselection, combine the other selection flags with the Current flag. A command using thisflag instructs the selection model to replace its current collection of modelindexes with those specified in a call to select(). To clear all selections before you startadding new ones, combine the other selection flags with the Clear flag. This has the effect of resetting the selection model'scollection of model indexes.
要用一个新选择替换当前的选择,就要用Current标识跟其它选择标识搭配使用。使用这个标识的指令通知选择模型用select()函数里指定的模型索引集合来替换当前的模型索引集合。在开始增加新的选择前,如果要清除所有的选择,就要用Clear标识跟其它选择标识搭配使用。它有重设选择模型的索引集合的效果。

Selectingall items in a model  
选择模型的所有项

To select all items in a model, it is necessary tocreate a selection for each level of the model that covers all items in thatlevel. We do this by retrieving the indexes corresponding to the top-left andbottom-right items with a given parent index:
为了选择模型里的所有项,必须为模型的每一层建立一个选择,以涵盖该层的所有项。我们通过一个给定的父索引并提取左上角和右下角相应的索引来实现这个操作。

  
  1.      QModelIndex topLeft =model->index(0, 0, parent);
         QModelIndex bottomRight =model->index(model->rowCount(parent)-1,
            model->columnCount(parent)-1, parent);


A selection is constructed with these indexes andthe model. The corresponding items are then selected in the selection model:
以这些索引和模型构造一个选择,这样相应的项就会在选择模型中被选中。


  1.      QItemSelectionselection(topLeft, bottomRight);
        selectionModel->select(selection, QItemSelectionModel::Select);



This needs to be performed for all levels in themodel. For top-level items, we would define the parent index in the usual way:
对模型所有的层都要执行这样的操作,对于顶层项,我们以通常的方法定义父项索引

  
  1.    QModelIndex parent =QModelIndex();


For hierarchicalmodels, the hasChildren() function is used to determine whetherany given item is the parent of another level of items.
对于等级层次类型的模型,使用hasChildren() 函数可以确定一个指定的项是否是另一层次项的父项。


分类:默认分类|回复:0|浏览:2365|全站可见|转载
 

Powered by phpwind v8.7 Certificate Copyright Time now is:04-29 00:29
©2005-2016 QTCN开发网 版权所有 Gzip disabled