Emit dataChanged (createIndex (1,1), createIndex (1,1)) leads to multiple :: data calls

I have a QTableView and the corresponding instance of a child QAbtractTableModel.

I was surprised to see that if an instance of my table model emits the name of the DataChanged data item for one cell, the Qt structure will then produce a large number of calls to my model: data () function. The range of rows / columns of these calls seems to cover the entire range of what is on the screen + some additional ones.

This is more than I expected. I would think that dataChanged (), which calls a single cell, would result in a call to :: data () requesting data for that cell. In the end, the only cell my table model talked about was changed. But the Qt structure looks very sociable and asks about all the cells.

I obviously have a broken understanding of the intent of the dataChanged () signal.

Is there a way to tell QTableView to update one cell and one cell only without the extra pass passed to my table model?

UPDATE: including sample code An example here is the header, source, and code snippet to create a table. For me, the table displays 12 columns and 29 rows. After calling "issueEmit" at the end, :: data will be called 1044 times because of the dataChanged () signal for one cell.

// Declaration #include <QAbstractTableModel> class SimpleModel : public QAbstractTableModel { Q_OBJECT private: bool _post_emit; public: explicit SimpleModel(QObject *parent=0); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; void issueEmit(); }; // Implementation #include <stdlib.h> #include <stdio.h> #include "simplemodel.h" SimpleModel::SimpleModel(QObject *parent) : QAbstractTableModel(parent), _post_emit(false) { } int SimpleModel::rowCount(const QModelIndex &parent) const { return 100; } int SimpleModel::columnCount(const QModelIndex &parent) const { return 100; } QVariant SimpleModel::data(const QModelIndex &index, int role) const { if (role==Qt::DisplayRole) { if (_post_emit) { static unsigned s_calls=0; s_calls++; printf("Data calls: %d\n",s_calls); } return ((rand()%10000)/1000.00); } return QVariant(); } void SimpleModel::issueEmit() { _post_emit=true; emit dataChanged(createIndex(1,1),createIndex(1,1)); } // Usage QTableView *table=new QTableView; table->setMinimumSize(1200,900); SimpleModel *model=new SimpleModel; table->setModel(model); table->show(); model->issueEmit(); 
+4
source share
1 answer

QVariant QStandardItem :: data (int role = Qt :: UserRole + 1) const [virtual]

Returns item data for this role or invalid QVariant if no data is available for this role.


The argument is really interesting. Each element in the model contains several QVariants; these QVariants support different information about the element.

All of these options are assigned roles . Each time you select this data, the model must redraw the element. To redraw an element, it must look at many different pieces of data (a small excerpt below).

Roles describing the appearance and metadata (with associated types):
Constant value Description
Qt :: FontRole 6 Font used for elements provided by the delegate by default. (QFont)
Qt :: TextAlignmentRole 7 Text alignment for elements processed by the default delegate. (Qt :: AlignmentFlag)
Qt :: BackgroundRole 8 The background brush used for items displayed by the default delegate. (QBrush)

+1
source

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


All Articles