emit dataChanged (createIndex (1,1), createIndex (1,1)) приводит ко многим вызовам :: data - PullRequest
4 голосов
/ 23 марта 2012

У меня есть QTableView и соответствующий экземпляр потомка QAbtractTableModel.

Я был удивлен, увидев, что если мой экземпляр табличной модели испускает dataChanged, именуя одну ячейку, то среда Qt выдаст большойколичество вызовов функции-члена моей модели таблицы: data ().Диапазон строк / столбцов этих вызовов, кажется, покрывает весь диапазон того, что на экране + некоторые дополнительные.

Это больше, чем я ожидал.Я бы подумал, что dataChanged (), который называет одну ячейку, приведет только к вызовам :: data (), запрашивающим данные для этой ячейки.В конце концов, это единственная ячейка, которая, по словам моей модели стола, была изменена.Но фреймворк Qt, кажется, очень общительный и спрашивает обо всех ячейках.

У меня явно неправильное понимание намерения сигнала dataChanged ().

Есть ли способ сообщить QTableView обновить только одну ячейку и одну ячейку без всякой дополнительной болтовни, отправленной в мою модель таблицы?

ОБНОВЛЕНИЕ: включая пример кода Примером здесь является заголовок, источник и кусок кода для создания таблицы.Для меня таблица отображается с 12 столбцами и 29 строками.После вызова «issueEmit» в конце, :: data будет вызываться 1044 раза из-за сигнала dataChanged () для отдельной ячейки.

// 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();

1 Ответ

1 голос
/ 24 марта 2012

QVariant QStandardItem :: data (int role = Qt :: UserRole + 1) const [виртуальный]

Возвращает данные элемента для данной роли или недопустимый QVariant, если существуетнет данных для роли.


Аргумент - действительно интересная вещь здесь.Каждый элемент в модели содержит несколько QVariants, эти QVariants содержат различную информацию об элементе.

Всем этим вариантам назначены роли .Каждый раз, когда вы изменяете данные, модель должна перерисовывать элемент.Чтобы перерисовать элемент, он должен просмотреть множество различных фрагментов данных (небольшой фрагмент включен ниже)

Роли, описывающие внешний вид и метаданные (со связанными типами):
Значение константы Описание
Qt :: FontRole6 Шрифт, используемый для элементов, отображаемых с делегатом по умолчанию.(QFont)
Qt :: TextAlignmentRole 7 Выравнивание текста для элементов, отображаемых с делегатом по умолчанию.(Qt :: AlignmentFlag)
Qt :: BackgroundRole 8 Фоновая кисть, используемая для элементов, отображаемых с делегатом по умолчанию.(QBrush)

...