Model sub-class reference
Subclasses of the model need to provide many implementations of virtual functions defined in Qabstractitemmodel . The number of methods you need to implement depends on the style of the subclass you want to create-it provides a simple list view, a tabular view, or a complex hierarchical view. Subclasses inheriting from Qabstractlistmodel and Qabstracttablemodel can directly take advantage of many of the default virtual functions of these two classes.
There are three types of methods that need to be implemented in subclasses:
1. Working with item data: All models need to implement methods to ensure that views and delegates can query the size of the model, detect each item, and return the data in it.
2. Browsing and creating indexes: Hierarchical models need to implement methods that enable views to invoke them to expose the tree structure and get the model index for each item.
3. Support Drag and drop operations and handle MIME type data: Model inheritance methods to control the implementation of internal and external drag behavior. These methods allow item data to be described as other components and MIME types that the application can accept.
Item Data Management
For the data in the model, the model can provide multiple levels of access: read-only, resize, and edit.
Read-only access
A model if you want to implement read-only access to data, these methods must be implemented by the Quilt class:
Flags (): This method is used by other components to obtain information about each item data for the model. The combination of the flag bits should include qt::itemisenabled and qt::itemisselectable.
Data (): Used to provide the item data to the view and delegate. In general, the model only needs to be for Qt::displayrole and other user roles for specific applications. But the data is available to QT::tooltiprole and qt::accessibletextrole and qt :: Accessibledescriptionrole is also a good choice. Refer to the Qt::itemdatarole Enumeration values manual for information about the types of each role.
Headerdata (): Provides a view that can display header information. This information can be obtained by displaying a view of the header information.
RowCount (): Provides the number of rows of data exposed by the model.
These 4 methods must be implemented in any type of model, including the list model, Qabstractlistmodel and its subclasses, and tabular models, that is, Qabstracttablemodel and its subclasses.
In addition, the following methods must be implemented in the direct subclasses of Qabstracttablemodel and Qabstractitemmodel :
ColumnCount (): Provides the number of columns of data exposed by the model, and the list model does not need to provide its implementation because it is already implemented in Qabstractlistmodel .
Editable items
The editable model allows the item data to be changed, or it can provide methods to insert or delete rows and columns. To enable editing, the following methods must be implemented correctly:
Flags (): The correct identity bit combination must be returned for each item. In particular, Qt::itemiseditablemust be included in addition to the values provided to the data items in the read-only model.
SetData (): Used to change the value of an item that is associated with a particular model index. To be able to accept user input from a user interface element, this method must handle data associated with Qt::editrole . This implementation can also accept data associated with other Qt::editrole values. After the modified data is complete, the model must emit a datachanged() signal to notify the other components that the change has taken place.
Setheaderdata (): Used to change the header information for a row or column. After the modification is complete, the model must emit a headerdatachanged() signal to notify the other components that a change has taken place.
Variable size model
All kinds of models support the insertion and deletion of rows. Tabular models and hierarchical models also support the insertion and deletion of columns. It is important to make other components aware of this change before and after the dimension of the model has changed. Therefore, you can change the size of the model by implementing these methods, but the implementations of these methods must ensure that the appropriate methods are called to make the views and delegates associated with the model aware of the changes:
insertrows (): Used to add new rows and new data items to all types of models. The implementation of this method must call the begininsertrows() method before inserting a new row into any underlying data structure, and call the endinsertrows() method immediately after the insertion is complete.
removerows (): Used to delete rows and data items that are contained by any model. The implementation of this method must call the beginremoverows() method before deleting the row from any underlying data structure, and call the endremoverows() method immediately after the deletion is complete.
InsertColumns (): Used to add new columns and new data items to a tabular model or hierarchy model. The implementation of this method must call the begininsertcolumns() method before inserting a new row into any underlying data structure, and call the endinsertcolumns() method immediately after the insertion is complete.
Removecolumns (): Used to delete rows and data items that are contained by a tabular model or hierarchy model. The implementation of this method must call the beginremovecolumns() method before deleting the row from any underlying data structure, and call the endremovecolumns() method immediately after the deletion is complete.
In general, these methods should return true after successful execution. In some cases, however, these behaviors may only be part of the success, for example, the number of rows that can be inserted is less than the number of rows specified. In this case, the model should return false to declare the failure, so that any related components can handle the situation.
The signal emitted by the method that is called during the implementation of the changed-size API gives the component associated with the model an opportunity to take action before any data becomes unavailable. The encapsulation of the insert and Delete methods with the start and end methods also enables the model to correctly handle long-term model indexes .
In general, the start and end methods are able to notify other parts of changes to the underlying data structure of the model. However, for more complex data structure changes, such as the internal reorganization or sequencing, the layoutchanged() signal should be emitted to allow any view to be updated.
Lazy Loading of model data
Lazy loading of model data effectively allows requests for information about the model to be delayed until the view really needs it to be sent.
Some models need to get data from a remote database, or because of the way the data is organized, it must take a very time-consuming action to get the data. To accurately display model data, views typically request data as much as possible, and it is useful to limit the amount of information returned to them to reduce unnecessary data-follow-up requests.
In some hierarchical models, the cost of finding a child for a given item is high. Lazy loading can effectively ensure that the RowCount() method of the model is called only when necessary. In this case, we can implement the HasChildren() method to confirm the existence of the subkey for the view and to provide a low-cost method for the appropriate adornment of the parent under the qtreeview view.
Regardless of whether the HasChildren() method's re-implemented return value is TRUE or FALSE, the view call RowCount() method is not affected to query the number of subkeys. For example, in the qtreeview view, if the parent is not expanded (to show the subkey), then the view does not need to know how many children are in total.
Many items have children and it is sometimes a useful method to have HasChildren() return true at any time. This ensures that each item can check subkeys as late as possible, making it as fast as possible to initialize the project for model data. The only downside to this is that items that have no children may be incorrectly displayed until the user tries to view a subkey that does not exist.
Browsing and creation of model indexes
Hierarchical models need to provide methods so that the view browses the tree structure they are associated with and gets the model index of the project.
Parent and child items
Because the structure associated with a view is determined by the underlying data structure, it is the responsibility of each subclass of the model class to create its own model index by implementing the following methods. :
Index (): The index model for the given parent. This method allows views and delegates to access the subkeys of the item. If the item that corresponds to the row, column, and parent in the parameter cannot be found, the method must return an invalid model index:qmodelindex().
Parent (): Provides a model index of the parent of any given subkey. If this method is called by the top-level project in the model, or if there is no valid parent in the model, this method must return an invalid model index constructed by the empty Qmodelindex() constructor.
Each of the two methods above uses the CreateIndex() factory function to create an index for use by other components. The model typically gives this method a unique identifier to ensure that the model index can be re-associated with the corresponding project later.
Support for drag-and-drop actions and processing of MIME types
The model/view class supports drag-and-drop operations and provides default behavior for many applications. However, we can still customize the way items are encoded in drag-and-drop behavior. For example, by default, whether an item is moved or copied, and how it is inserted into a model that already exists.
In addition, the convenient view class implements a specific approach to the intended purpose of the developer. The Convenience Views section provides an overview of this behavior.
MIME data
By default, built-in models and views use an internal MIME type (application/x-qabstractitemmodeldatalist) to transfer information between model indexes. The MIME type specifically describes the data for items in the list, including the row and column where each item resides, and information about the roles that each item supports.
Data encoded with this MIME type can be obtained by invoking the Qabstractitemmodel::mimedata() method. The data type of the parameter of this method is qmodelindexlist, which contains the items that need to be serialized.
When you implement drag-and-drop support in a custom item, you can export the item's data in a specific format by implementing the following methods:
Mimedata (): This method can be re-implemented to return data that differs from the default application/x-qabstractitemmodeldatalist internal format. Subclasses can get the default qmimedata object from the base class and add data to the object in other formats.
For many models, it is useful to provide the contents of an item in a format that is represented by a common MIME type such as Text/plain and Image/png. Note that through qmimedata::setimagedata(),qmimedata::setcolordata() and Qmimedata ::sethtml() method makes it easy to add pictures, colors, and HTML documents to a qmimedata object.
Receive Drop Data
When a drag-and-drop operation occurs on a view, the underlying model is asked to determine what kind of action it can support and which MIME type it can accept. This information is provided by Qabstractitemmodel::supporteddropactions() and Qabstractitemmodel::mimetypes () method is provided. The Qabstractitemmodel provides an implementation template that supports both the copy operation and the default internal MIME type of the item.
When the serialized data is placed on a view, the data is inserted into the current template by the template's Qabstractitemmodel::dropmimedata() method. The default implementation of this method will not overwrite any data in the model, but will use the item's data as the sibling or child of an item.
To take advantage of the default implementation of Qabstractitemmodel to obtain the built-in MIME type, the new template must provide a re-implementation of the following methods:
insertrows (),insertcolumns(): These two methods allow the model to automatically insert new data using the Qabstractitemmodel::dropmimedata() method.
SetData (): Allows data to be written to new lines and new columns.
SetItemData (): This method provides more effective support for writing new data.
In order to accept other types of data, the following methods must be re-implemented:
supporteddropactions (): Used to return a combination of "drop" actions that indicate which of these drag-and-drop operations the model supports.
mimetypes (): Used to return a collection of MIME types that the model can decode and process. In general, types that can be entered into the model can also be used by external component encodings.
Dropmimedata (): Enables decoding of data transmitted over a drag operation, determines where the data is placed in the model, and inserts new rows and columns when necessary. How this method is implemented in subclasses depends on the data requirements of each model.
If the implementation of the Dropmimedata() method changes the dimension of the model by inserting rows and columns, or if some data items have been modified, be sure to ensure that the relevant signals are emitted. It is useful to simply invoke functions such as setData(),insertrows(),insertcolumns() in the implementation of other methods, as this will ensure that the model works properly.
In order to keep the drag operation running properly, it is important to implement the following methods to remove data from the model.
removerows ()
Removerow ()
Removecolumns ()
Removecolumn ()
For more information about dragging on item views, see Using Drag and drop with itemview.
Convenient View class
The convenient view class (qlistwidget,qtablewidget , and Qtreewidget) overloads the default drag-and-drop method to provide a low-flexibility, high-naturalness drag-and-drop behavior that is suitable for many applications. For example, dragging data into a qtablewidget cell and overwriting the original data is a generic behavior, and the underlying model will reset the data in that cell instead of inserting new rows and columns into the model. For more information on drag-and-drop operations in the handy view class, see Using Drag and drop with itemviews.
Optimized operation for handling large amounts of data
Canfetchmore The () method checks if the parent has more data to obtain and returns TRUE or false based on the result. Fetchmore The () method is used to obtain data from the specified parent. These methods can all be combined, for example, for database queries containing incremental data for mobile Qabstractitemmodel , we can re-implement Canfetchmore() method to query whether there is still data that needs to be moved and to re-implement the Fetchmore() method to move the data on demand.
Another example is the dynamic movement of the tree model, where we re-implement the Fetchmore() method when a branch of the model needs to be extended.
If you add a new row to the model during the re-implementation of your Fetchmore() method, you need to call the begininsertrows() method and the endinsertrows() method. Also, both theCanfetchmore() and the Fetchmore() methods must be re-implemented, because the default implementations of the two methods return false and do nothing.
QT MVC Design Pattern: A method of sub-class abstract model