Model Subclassing Reference
IntroductionModel subclasses need to provide implementations of many of the virtual functions defined in the QAbstractItemModel base class. The number of these functions that need to be implemented depends on the type of model - whether it supplies views with a simple list, a table, or a complex hierarchy of items. Models that inherit from QAbstractListModel and QAbstractTableModel can take advantage of the default implementations of functions provided by those classes. Models that expose items of data in tree-like structures must provide implementations for many of the virtual functions in QAbstractItemModel. The functions that need to be implemented in a model subclass can be divided into three groups:
For more information, see the "Item View Classes" Chapter of C++ GUI Programming with Qt 4. Item Data HandlingModels can provide varying levels of access to the data they provide: They can be simple read-only components, some models may support resizing operations, and others may allow items to be edited. Read-Only AccessTo provide read-only access to data provided by a model, the following functions must be implemented in the model's subclass:
These four functions must be implemented in all types of model, including list models (QAbstractListModel subclasses) and table models (QAbstractTableModel subclasses). Additionally, the following functions must be implemented in direct subclasses of QAbstractTableModel and QAbstractItemModel:
Editable ItemsEditable models allow items of data to be modified, and may also provide functions to allow rows and columns to be inserted and removed. To enable editing, the following functions must be implemented correctly:
Resizable ModelsAll types of model can support the insertion and removal of rows. Table models and hierarchical models can also support the insertion and removal of columns. It is important to notify other components about changes to the model's dimensions both before and after they occur. As a result, the following functions can be implemented to allow the model to be resized, but implementations must ensure that the appropriate functions are called to notify attached views and delegates:
Generally, these functions should return true if the operation was successful. However, there may be cases where the operation only partly succeeded; for example, if less than the specified number of rows could be inserted. In such cases, the model should return false to indicate failure to enable any attached components to handle the situation. The signals emitted by the functions called in implementations of the resizing API give attached components the chance to take action before any data becomes unavailable. The encapsulation of insert and remove operations with begin and end functions also enable the model to manage persistent model indexes correctly. Normally, the begin and end functions are capable of informing other components about changes to the model's underlying structure. For more complex changes to the model's structure, perhaps involving internal reorganization or sorting of data, it is necessary to emit the layoutChanged() signal to cause any attached views to be updated. Lazy Population of Model DataLazy population of model data effectively allows requests for information about the model to be deferred until it is actually needed by views. Some models need to obtain data from remote sources, or must perform time-consuming operations to obtain information about the way the data is organized. Since views generally request as much information as possible in order to accurately display model data, it can be useful to restrict the amount of information returned to them to reduce unnecessary follow-up requests for data. In hierarchical models where finding the number of children of a given item is an expensive operation, it is useful to ensure that the model's rowCount() implementation is only called when necessary. In such cases, the hasChildren() function can be reimplemented to provide an inexpensive way for views to check for the presence of children and, in the case of QTreeView, draw the appropriate decoration for their parent item. Whether the reimplementation of hasChildren() returns true or false, it may not be necessary for the view to call rowCount() to find out how many children are present. For example, QTreeView does not need to know how many children there are if the parent item has not been expanded to show them. If it is known that many items will have children, reimplementing hasChildren() to unconditionally return true is sometimes a useful approach to take. This ensures that each item can be later examined for children while making initial population of model data as fast as possible. The only disadvantage is that items without children may be displayed incorrectly in some views until the user attempts to view the non-existent child items. Navigation and Model Index CreationHierarchical models need to provide functions that views can call to navigate the tree-like structures they expose, and obtain model indexes for items. Parents and ChildrenSince the structure exposed to views is determined by the underlying data structure, it is up to each model subclass to create its own model indexes by providing implementations of the following functions:
Both functions above use the createIndex() factory function to generate indexes for other components to use. It is normal for models to supply some unique identifier to this function to ensure that the model index can be re-associated with its corresponding item later on. Drag and Drop Support and MIME Type HandlingThe model/view classes support drag and drop operations, providing default behavior that is sufficient for many applications. However, it is also possible to customize the way items are encoded during drag and drop operations, whether they are copied or moved by default, and how they are inserted into existing models. Additionally, the convenience view classes implement specialized behavior that should closely follow that expected by existing developers. The Convenience Views section provides an overview of this behavior. MIME DataBy default, the built-in models and views use an internal MIME type (application/x-qabstractitemmodeldatalist) to pass around information about model indexes. This specifies data for a list of items, containing the row and column numbers of each item, and information about the roles that each item supports. Data encoded using this MIME type can be obtained by calling QAbstractItemModel::mimeData() with a QModelIndexList containing the items to be serialized. When implementing drag and drop support in a custom model, it is possible to export items of data in specialized formats by reimplementing the following function:
For many models, it is useful to provide the contents of items in common format represented by MIME types such as text/plain and image/png. Note that images, colors and HTML documents can easily be added to a QMimeData object with the QMimeData::setImageData(), QMimeData::setColorData(), and QMimeData::setHtml() functions. Accepting Dropped DataWhen a drag and drop operation is performed over a view, the underlying model is queried to determine which types of operation it supports and the MIME types it can accept. This information is provided by the QAbstractItemModel::supportedDropActions() and QAbstractItemModel::mimeTypes() functions. Models that do not override the implementations provided by QAbstractItemModel support copy operations and the default internal MIME type for items. When serialized item data is dropped onto a view, the data is inserted into the current model using its implementation of QAbstractItemModel::dropMimeData(). The default implementation of this function will never overwrite any data in the model; instead, it tries to insert the items of data either as siblings of an item, or as children of that item. To take advantage of QAbstractItemModel's default implementation for the built-in MIME type, new models must provide reimplementations of the following functions:
To accept other forms of data, these functions must be reimplemented:
If the implementation of the dropMimeData() function changes the dimensions of a model by inserting or removing rows or columns, or if items of data are modified, care must be taken to ensure that all relevant signals are emitted. It can be useful to simply call reimplementations of other functions in the subclass, such as setData(), insertRows(), and insertColumns(), to ensure that the model behaves consistently. In order to ensure drag operations work properly, it is important to reimplement the following functions that remove data from the model: For more information about drag and drop with item views, refer to Using Drag and Drop with Item Views. Convenience ViewsThe convenience views (QListWidget, QTableWidget, and QTreeWidget) override the default drag and drop functionality to provide less flexible, but more natural behavior that is appropriate for many applications. For example, since it is more common to drop data into cells in a QTableWidget, replacing the existing contents with the data being transferred, the underlying model will set the data of the target items rather than insert new rows and columns into the model. For more information on drag and drop in convenience views, you can see Using Drag and Drop with Item Views. Performance Optimization for Large Amounts of DataThe canFetchMore() function checks if the parent has more data available and returns true or false accordingly. The fetchMore() function fetches data based on the parent specified. Both these functions can be combined, for example, in a database query involving incremental data to populate a QAbstractItemModel. We reimplement canFetchMore() to indicate if there is more data to be fetched and fetchMore() to populate the model as required. Another example would be dynamically populated tree models, where we reimplement fetchMore() when a branch in the tree model is expanded. Note: Both functions must be reimplemented as the default implementation of canFetchMore() returns false and fetchMore() does nothing. [Previous: Proxy Models] [Contents] |
Publicité
Best OfActualités les plus luesSemaine
Mois
Année
Le Qt Labs au hasardLe moteur de rendu OpenGLLes Qt Labs sont les laboratoires des développeurs de Qt, où ils peuvent partager des impressions sur le framework, son utilisation, ce que pourrait être son futur. Lire l'article.
CommunautéRessources
Liens utilesContact
Qt dans le magazine |
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.3 | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com