alexltr的个人主页

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

alexltr

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

  • 26

    关注

  • 60

    粉丝

  • 150

    访客

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

最后登录:2024-04-20

更多资料

日志

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

2012-05-06 15:57
Using model/view classes
使用模型/视图类


Setting up a view for drag and dropfollows the same pattern used with the convenience views. For example, a QListView canbe set up in the same way as aQListWidget:
建立一个可以拖放的基于模型的视图跟简便类视图是一样的模式。例如,可以用建立QListWidget一样的方法建立一个QListView:

  1. QListView *listView = newQListView(this);
    listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    listView->setDragEnabled(true);
    listView->setAcceptDrops(true);
    listView->setDropIndicatorShown(true);


Since access to the data displayed by the view iscontrolled by a model, the model used also has to provide support for drag anddrop operations. The actions supported by a model can be specified byreimplementing the QAbstractItemModel::supportedDropActions()function. For example, copy and move operations are enabled with the followingcode:
因为视图所显示的数据的存取是由模型控制的,所以模型也要提供对拖放操作的支持。模型支持的动作可以通过重新实现QAbstractItemModel::supportedDropActions()函数来指定。下面的代码实现复制和移动的操作:

  1. Qt::DropActionsDragDropListModel::supportedDropActions() const
    {
         return Qt::CopyAction |Qt::MoveAction;
    }


Although anycombination of values from Qt::DropActions can be given, the model needs to bewritten to support them. For example, to allowQt::MoveAction to be used properly with a list model,the model must provide an implementation of QAbstractItemModel::removeRows(),either directly or by inheriting the implementation from its base class.
虽然可以指定一个Qt::DropActions里的值的任意组合,但是还是要写模型来支持他们。例如,为了让一个列表模型能正确地支持Qt::MoveAction动作,模型必须重新实现QAbstractItemModel::removeRows()函数,不管是直接还是间接从他的基类继承实现。


Enablingdrag &amp drop for items
启用项的拖放
Models indicateto views which items can be dragged, and which will accept drops, byreimplementing the QAbstractItemModel::flags() functionto provide suitable flags.
通过重新实现QAbstractItemModel::flags()函数来提供合适的标识,模型指示视图哪些项可以拖动,哪些项接受放置。
For example, a model which provides a simple listbased on QAbstractListModel can enable drag and drop for each of the items by ensuring that theflags returned contain the Qt::ItemIsDragEnabled and Qt::ItemIsDropEnabled values:
例如:通过确保返回的标识包含Qt::ItemIsDragEnabled 和 Qt::ItemIsDropEnabled 这两个值,一个基于QAbstractListModel的简单列表模型就可以使每个项都可以拖放:

  1. Qt::ItemFlagsDragDropListModel::flags(const QModelIndex &index) const
    {
         Qt::ItemFlags defaultFlags= QStringListModel::flags(index);

         if (index.isValid())
             returnQt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
         else
             returnQt::ItemIsDropEnabled | defaultFlags;
    }


Note that items can be dropped into the top levelof the model, but dragging is only enabled for valid items.
In the above code, since the model is derived from QStringListModel, we obtain a default set of flags bycalling its implementation of the flags() function.
注意,项可以被放置在模型的顶层,而拖动操作只对合法项有效
在以上的代码中,因为这个模型是从QStringListModel,中衍生出来的,所以我们要调用它的flags()函数实现以包含一套默认的标识。

Encodingexported data
导出数据的编码
When items of data are exported from a model in adrag and drop operation, they are encoded into an appropriate formatcorresponding to one or more MIME types. Models declare the MIME types thatthey can use to supply items by reimplementing the QAbstractItemModel::mimeTypes() function,returning a list of standard MIME types.
For example, a model that only provides plain textwould provide the following implementation:
在拖放操作中,当项的数据从一个模型中导出时,它们会被编码成对应一个或多个MIME类型的适当的格式。模型通过重新实现 QAbstractItemModel::mimeTypes()函数返回一个标准MIME类型的列表,来声明它们可以供项使用的MIME类型。
例如,一个只提供纯文字的模型要提供以下的实现:
  1. QStringListDragDropListModel::mimeTypes() const
    {
         QStringList types;
         types <<"application/vnd.text.list";
         return types;
    }


The model must also provide code to encode data inthe advertised format. This is achieved by reimplementing the QAbstractItemModel::mimeData() function toprovide a QMimeData object, just as in any other drag and drop operation.
The following code shows how each item of data,corresponding to a given list of indexes, is encoded as plain text and storedin a QMimeData  object.
模型同时还要提供对advertised格式的数据进行编码的代码。这个可以通过重新实现QAbstractItemModel::mimeData()函数提供一个QMimeData对象来实现,就像在其它的拖放操作里一样:
  1. QMimeData*DragDropListModel::mimeData(const QModelIndexList &indexes) const
    {
         QMimeData *mimeData = newQMimeData();
         QByteArray encodedData;

         QDataStreamstream(&encodedData, QIODevice::WriteOnly);

         foreach (QModelIndexindex, indexes) {
             if (index.isValid()){
                 QString text =data(index, Qt::DisplayRole).toString();
                 stream <<text;
             }
         }

        mimeData->setData("application/vnd.text.list",encodedData);
         return mimeData;
    }


Since a list of model indexes is supplied to thefunction, this approach is general enough to be used in both hierarchical andnon-heirarchical models.
Note that custom datatypes must be declared as metaobjects  and that stream operators must be implemented for them. See the QMetaObject class description for details.
因为为这个函数提供了一个模型索引的链表,所以在层次结构和非层次结构中使用这种方法一般来说是足够了的。
注意,自定义的数据类型必须声明为meta objects,并且要为它们实现流操作。详细内容请看QMetaObject类里的描述。

Insertingdropped data into a model
将放下的数据插入到模型中
The way that any given model handles dropped datadepends on both its type (list, table, or tree) and the way its contents islikely to be presented to the user. Generally, the approach taken toaccommodate dropped data should be the one that most suits the model'sunderlying data store.
任何指定模型处理放下数据的方法要看它的类型(列表,表格或树形)以及它向用户显示其内容的方法而定。一般情况下,容纳放下数据的方法应该要是最适合模型底层数据存储的方法。

Different types of model tend to handle droppeddata in different ways. List and table models only provide a flat structure inwhich items of data are stored. As a result, they may insert new rows (andcolumns) when data is dropped on an existing item in a view, or they mayoverwrite the item's contents in the model using some of the data supplied.Tree models are often able to add child items containing new data to theirunderlying data stores, and will therefore behave more predictably as far asthe user is concerned.
不同类型的模型会用不同的方法处理放下的数据。列表和表格模型只提供一个存储项的平面结构。因此,当数据被放下到视图中的一个现有的项上面时,它们可以插入新的行(和列),或者以所提供的某些数据覆盖掉模型里这个项的内容。树形模型一般是向他们的底层数据增加包含新数据的子项,因此它的行为会比用户所能想到的更有可预见性。

Dropped data is handled by a model'sreimplementation of QAbstractItemModel::dropMimeData(). For example, amodel that handles a simple list of strings can provide an implementation thathandles data dropped onto existing items separately to data dropped into thetop level of the model (i.e., onto an invalid item).
放下数据的处理通过重新实现模型的QAbstractItemModel::dropMimeData()函数来实现。例如,一个处理简单字符串列表的模型可以提供一个实现来分别处理放置于现有项之上的数据以及放置于模型顶层的数据(例如,放置到一个无效的项上面)。

The model first has to make sure that theoperation should be acted on, the data supplied is in a format that can beused, and that its destination within the model is valid:
模型首先要确保操作应该作用于的数据是以可用的格式提供的,并且它在模型里的目标是有效的:

  1. bool DragDropListModel::dropMimeData(const QMimeData *data,
         Qt::DropAction action,int row, int column, const QModelIndex &parent)
    {
         if (action ==Qt::IgnoreAction)
             return true;

         if (!data->hasFormat("application/vnd.text.list"))[/font]
             return false;
         if (column > 0)
             return false;

A simple one column string list model can indicatefailure if the data supplied is not plain text, or if the column number givenfor the drop is invalid.
如果提供的数据不是纯文字,或给出的用于放下的列号是无效的,则这个简单的单列字符串列表模型可以将此操作标志为失败。

The data to be inserted into the model is treateddifferently depending on whether it is dropped onto an existing item or not. Inthis simple example, we want to allow drops between existing items, before thefirst item in the list, and after the last item.
根据数据是否被放置在一个现有的项上面作为判断,插入模型的数据将作不同的处理。在这个简单例子中,我们允许把数据放在现有项之间,列表第一个项之前,和最后一个项之后。

When a drop occurs, the model index correspondingto the parent item will either be valid, indicating that the drop occurred onan item, or it will be invalid, indicating that the drop occurred somewhere inthe view that corresponds to top level of the model.
当一个放下操作发生时,如果父项相对应的模型索引是有效的,意味着放下操作发生在一个项上面,如果是无效的,则意味着放下操作发生在视图中对应于模型顶层的某个位置。

  1.      int beginRow;

         if (row != -1)
             beginRow = row;



We initially examine the row number supplied tosee if we can use it to insert items into the model, regardless of whether theparent index is valid or not.
我们先检查指定的行号看它是否可以用来将项插入到模型中,不管父项的索引是否有效:

  1.      else if (parent.isValid())
             beginRow =parent.row();

If the parent model index is valid, the dropoccurred on an item. In this simple list model, we find out the row number ofthe item and use that value to insert dropped items into the top level of themodel.
如果父项索引是有效地,则放下操作发生在一个项上。在这个简单的列表模型中,我们找出项的行号,并用这个值把放下的项插入到模型的顶层。

  1.      else
             beginRow =rowCount(QModelIndex());



When a drop occurs elsewhere in the view, and therow number is unusable, we append items to the top level of the model.
In hierarchical models, when a drop occurs on anitem, it would be better to insert new items into the model as children of thatitem. In the simple example shown here, the model only has one level, so thisapproach is not appropriate.
当放下动作发生在视图的某个位置,同时行号又是不可使用的,那我们就把项添加在模型的顶层项。
在层次结构模型中,当放下动作发生在一个项上时,把要插入的项作为该项的子项插入到模型中会更好。在这里讲的简单例子中,模型只要一层,因此这个方法是不适合的。



Decodingimported data
对导入数据的解码
Each implementation of dropMimeData() mustalso decode the data and insert it into the model's underlying data structure.
For a simple string list model, the encoded itemscan be decoded and streamed into a QStringList:

每个dropMimeData()的实现同时也必须对数据进行解码, 并把它插入到模型的底层数据结构中。
对应一个简单的字符串列表模型,编码后的项可以被解码并汇入到 QStringList::
  1.      QByteArray encodedData =data->data("application/vnd.text.list");
         QDataStreamstream(&encodedData, QIODevice::ReadOnly);
         QStringList newItems;
         int rows = 0;

         while (!stream.atEnd()) {
             QString text;
             stream >> text;
             newItems <<text;
             ++rows;
         }



The strings can then be inserted into the underlying data store.For consistency, this can be done through the model's own interface:
这样字符串就可以插入到底层数据。为了保持一致性,可以通过模型自己的接口实现:

  1.     insertRows(beginRow,rows, QModelIndex());
         foreach (QString text,newItems) {
             QModelIndex idx =index(beginRow, 0, QModelIndex());
             setData(idx, text);
             beginRow++;
         }

         return true;
    }



Note that the model will typically need to provideimplementations of the QAbstractItemModel::insertRows()and QAbstractItemModel::setData()functions.
注意,模型通常要提供 QAbstractItemModel::insertRows()函数和 QAbstractItemModel::setData()函数的实现。

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

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