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
?
- Get data from an external source.
- Fill the model with the received data.
- After this process is complete, you can display the model.
- To synchronize the changes made by the user, we subscribe to signals (for example,
itemChanged()
)
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.
- No need to "build" a model. The model is ready after it is created. In order to start working with it, you do not even need data. You need only meta-information that you entered into the model at the design stage. All the rest you need only when asked about it.
At the same time, if the amount of data in the model is large, then most of them will not be asked, probably never. - You can use all the features of Qt MVC technology, such as dynamically loading data or quickly moving rows.
- You can impose integrity constraints on your data and prevent the user from destroying them.
- You can use automatically computed data and default values.
Just try using QStandardItemModel
so that cells with odd values are displayed with a green background color, and cells with even values are displayed with a red one. These cells, of course, can be changed by the user.
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.