📜 ⬆️ ⬇️

Using Qt Models

Over the past year, I had to work quite a bit with the Qt Framework / View framework. It was necessary to write both own models, and to redo existing ones. And so, after contemplating the next creation, I decided to present to the public some developments.

Let's start with the obvious:

Do not use widgets

All of these QTableWidget , QListWidget and QTreeWidget are not for you.
')
Using the MVC framework is not a problem. In the simplest case, you can use ready-made models that Qt provides. The amount of code and its complexity does not grow, but it is possible to avoid all sorts of growth problems. Separating the model and the display from the very beginning makes it easy to add such things as sorting or filtering without rewriting half the code.

Some advantages and disadvantages, however, are not noticed.

Use the standard interface for working with models.

In general, the second point follows directly from the first.

See what functions QAbstractItemModel provides you. Only their and must use your code that works with the model. This interface is more than enough. No amateur performance. QStandardItemModel , for example, contains such a wonderful function as
 QStandardItem * item ( int row, int column = 0 ) const 

Do not use it. All operations in which Item s appear should be only operations of filling the model with data.

If you are going to find out the text of the element 5 5th row 3 3rd column, do not write
 QString text = model->item(5, 3)->text(); 

Use the standard model interface for this:
 QModelIndex index = model->index(5, 3); QString text = index.data(Qt::DisplayRole).toString(); 

This saves a lot of effort later when you want to put a proxy model that performs sorting between the model and the display component, and suddenly find that it does not contain such a wonderful item() function.

Avoid QStandardItemModel

Perhaps this is the most difficult and unobvious point to explain.

The QStandardItemModel model provides a universal interface, so that with its help you can quickly make any kind of data presentation structure.

However, there are significant drawbacks to its use.

First, Qt provides several ready-made simple models for some cases: QStringListModel , QDirModel , QFileSystemModel , QSqlQueryModel with its relatives - at your service!

Unfortunately, in most cases they are not very suitable. So, develop your own models for each case?

Indeed, at first glance, this task looks quite complicated. In fact, everything is not so scary. But before moving on to the practical part of writing a model, let's look at a few conceptual questions.

How does working with data look like when using QStandardItemModel ?

Looks not so bad? Not here it was!

First, if the amount of data is large, then the construction of the model will take a lot of time. Moreover, since the model must be fully prepared before we can show it to the user, you will have to read all the data.

Secondly, we get, in fact, two data models - one is the data source and the second is the standard Qt model. And these models need to be synchronized. This task is not as simple as it seems at first glance.

For example, the user has changed some value in the cell. We try to write this value to the source, but nothing comes out (for example, the connection to the data source is lost). Now it is necessary to return the old value in order not to break the consistency of the data. But it still needs to be taken from somewhere! That is, you have to store another, backup, data set.

In fact, the whole variety of problems arises from one sad fact: as soon as you start using the standard model, you no longer control your data . You are already confronted with the facts that have happened, you are forced to correct the mistakes made in the structure of your data, but you cannot avoid them . You cannot hang any integrity constraints.

Therefore, I propose to abandon the standard model for most cases. In fact, you do not even need to develop your model. Because your data is your model. She is ready. You only need to write a thin wrapper that matches the interface of your model with the interface of Qt MVC models.

This will help you standard Qt presets : QAbstractListModel , QAbstractTableModel . Adapting them for specific cases is usually very simple. You need to implement only a few functions, and their implementation is usually trivial.

In this case, you at once get rid of many problems.

Last tip


What do you think, what function of the model will be called most often? That's right, this is the index() function. It is called really often. No, not as often as you thought. Much more often. And the index() function will most likely call the rowCount() and columnCount() functions. This triple should work quickly, especially if there is a lot of data in the model.

But the request to update the data, the data() call, will occur only when this data is really needed. For example, in order to show them to the user. If part of the data is not visible in the window, then it will not be requested.

PS If it is interesting, I can tell about anything in more detail on the topic of working with models. Proposals are accepted.

At the request of workers, removed KDPV.

Source: https://habr.com/ru/post/171443/


All Articles