Моя проблема в том, что при использовании
QStandarditemmodel::setData(const QModelIndex &index, const QVariant &value, int role)
создается впечатление, что роль никогда не испускается.
Пример:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QStandardItemModel *model = new QStandardItemModel();
QList<QStandardItem*> itemList;
itemList.append(new QStandardItem());
model->appendRow(itemList);
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(myslot_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
model->item(0,0)->setData("supercool value", Qt::DisplayRole); // // should emit 1 role, but 0 are arriving
model->item(0,0)->setData("another supercool value", Qt::UserRole); // // should emit 1 role, but 0 are arriving
QVector<int> roles;
roles.append(Qt::DisplayRole);
roles.append(Qt::UserRole);
emit model->dataChanged(model->index(0,0), model->index(0,0), roles); // works. roles.count() == 2
}
MainWindow::myslot_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
qDebug() << roles.count();
}
учитывая Вывод:
0
0
2
Ожидаемый результат:
1
1
2
Я знаю, что роли QVector в сигнале необязательны.Может ли быть так, что Qt опускает роли и просто использует роли по умолчанию?Может быть, я должен использовать правильный сигнал (НЕ те, где вы можете опустить роли ...) явно, но я не знаю, как.
Извините за плохой английский, и спасибо за помощь!;)
Редактировать 1: Дальнейшие исследования:
Я пролистал источники Qt и нашел это в qstandarditemmodel.cpp
void QStandardItem::setData(const QVariant &value, int role)
{
Q_D(QStandardItem);
role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
QVector<QStandardItemData>::iterator it;
for (it = d->values.begin(); it != d->values.end(); ++it) {
if ((*it).role == role) {
if (value.isValid()) {
if ((*it).value.type() == value.type() && (*it).value == value)
return;
(*it).value = value;
} else {
d->values.erase(it);
}
if (d->model)
d->model->d_func()->itemChanged(this);
return;
}
}
d->values.append(QStandardItemData(role, value));
if (d->model)
d->model->d_func()->itemChanged(this);
}
При использовании setData функция itemChangedиспользуется который не заботится о ролях.Кажется, что параметр role в dataChanged является для вас необязательным и никогда не используется нативными функциями Qt.
Редактировать 2: еще больше исследований ...
Я прошел через функцию setData.Вот фрагмент кода, когда setData вызывает itemChanged ():
void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
{
Q_Q(QStandardItemModel);
Q_ASSERT(item);
if (item->d_func()->parent == 0) {
// Header item
int idx = columnHeaderItems.indexOf(item);
if (idx != -1) {
emit q->headerDataChanged(Qt::Horizontal, idx, idx);
} else {
idx = rowHeaderItems.indexOf(item);
if (idx != -1)
emit q->headerDataChanged(Qt::Vertical, idx, idx);
}
} else {
// Normal item
QModelIndex index = q->indexFromItem(item);
emit q->dataChanged(index, index);
}
}
Как упоминалось в предыдущих исследованиях, setData вызывает itemChanged
, что, в свою очередь, вызывает emit q->dataChanged(index, index);
Там мы видим, что dataChanged пропускает параметр роли.Это означает, что мое предыдущее предположение о том, что нативные функции Qt не используют роли, похоже, подтвердилось.