gpt4 book ai didi

c++ - 使用委托(delegate)一次编辑多个数据项

转载 作者:太空狗 更新时间:2023-10-29 23:19:22 27 4
gpt4 key购买 nike

在我的应用程序中,我有一个 QSqlTableModel,其中填充了一个来自 MySQL 连接的表。为了显示它的内容,我使用了一个QTableView;为了编辑和显示它,我继承了 QStyledItemDelegate

我需要能够编辑整行模型。为实现这一点,我使用 QModelIndex::sibling 方法来检索/设置该行中的所有值,而不管哪对(行/列)“激活”了委托(delegate)。

有了它,我可以构建一个 QDialog 子类(我的委托(delegate)编辑器)并用所选行的当前值填充它。然后让用户编辑内容,并在提交更改或放弃更改后,取决于用户是单击“保存”还是“取消”。

问题是:我使用 QAbstractItemModel::setData 将更改保存回模型中。但在某些情况下(仍然未知),此方法调用 QAbstractItemDelegate::setEditorData,它会覆盖 QDialog 子类中的新内容,以替换当前存在于模型。

发生这种情况时,任何下一次调用 QAbstractItemModel::setData 都会写入模型中包含的内容本身,而不是用户选择的新值,因为上一次调用 >QAbstractItemDelegate::setEditorData 使 QDialog 子类丢失了用户选择的所有信息,来自与引起问题的 QAbstractItemModel::setData 对应的列.

有谁知道如何防止这个问题的发生?

部分代码:

QWidget *MedicationDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&       /*option*/, const QModelIndex& /*index*/) const
{
EditMedicationDialog *editor = new EditMedicationDialog(parent);
editor->setAttribute(Qt::WA_DeleteOnClose, true);
editor->setModal(true);

connect(editor, SIGNAL(accepted()), this, SLOT(editorAccepted()));
connect(editor, SIGNAL(rejected()), this, SLOT(editorRejected()));

return editor;
}

void MedicationDelegate::setEditorData(QWidget *uncastedEditor, const QModelIndex& index) const
{
int currentRow = index.row();

QModelIndex drugClassIndex = index.sibling(currentRow, MedicationModel::DrugClass);
QModelIndex drugIndex = index.sibling(currentRow, MedicationModel::Drug);
QModelIndex dosageIndex = index.sibling(currentRow, MedicationModel::Dosage);
QModelIndex amountIndex = index.sibling(currentRow, MedicationModel::Amount);
QModelIndex scheduleIndex = index.sibling(currentRow, MedicationModel::Schedule);
QModelIndex frequencyIndex = index.sibling(currentRow, MedicationModel::Frequency);

QString drugClass = index.model()->data(drugClassIndex, Qt::DisplayRole).toString();
QString drug = index.model()->data(drugIndex, Qt::DisplayRole).toString();
QString dosage = index.model()->data(dosageIndex, Qt::DisplayRole).toString();
QString amount = index.model()->data(amountIndex, Qt::DisplayRole).toString();
QString schedule = index.model()->data(scheduleIndex, Qt::DisplayRole).toString();
QString frequency = index.model()->data(frequencyIndex, Qt::DisplayRole).toString();

EditMedicationDialog *editor = qobject_cast<EditMedicationDialog*>(uncastedEditor);

// these methods sets the current row values in the editor
editor->setDrugClass(drugClass);
editor->setDrug(drug);
editor->setDosage(dosage);
editor->setAmount(amount);
editor->setSchedule(schedule);
editor->setFrequency(frequency);
}

void MedicationDelegate::setModelData(QWidget *uncastedEditor, QAbstractItemModel *model, const QModelIndex& index) const
{
int currentRow = index.row();

QModelIndex drugClassIndex = index.sibling(currentRow, MedicationModel::DrugClass);
QModelIndex drugIndex = index.sibling(currentRow, MedicationModel::Drug);
QModelIndex dosageIndex = index.sibling(currentRow, MedicationModel::Dosage);
QModelIndex amountIndex = index.sibling(currentRow, MedicationModel::Amount);
QModelIndex scheduleIndex = index.sibling(currentRow, MedicationModel::Schedule);
QModelIndex frequencyIndex = index.sibling(currentRow, MedicationModel::Frequency);

EditMedicationDialog *editor = qobject_cast<EditMedicationDialog*>(uncastedEditor);

model->setData(drugClassIndex, editor->drugClass());
model->setData(drugIndex, editor->drug()); // HERE
model->setData(dosageIndex, editor->dosage());
model->setData(amountIndex, editor->amount());
model->setData(scheduleIndex, editor->schedule());
model->setData(frequencyIndex, editor->frequency());
}

带有“HERE”注释的行导致了问题(根据调试)。

编辑(新信息): 我刚刚意识到 QAbstractItemModel::setData 总是在导致“编辑”的列被保存之后调用。我总是在“药物”栏中点击两次。因此,QAbstractItemDelegate::setEditorData 在该版本之后被调用。

谢谢。

最佳答案

您可以使用 bool 值来防止递归执行函数体。

一个更简单的解决方案是

  • 通过将编辑触发器设置为 QAbstractItemView::NoEditTriggers 使模型只读,
  • 例如,使用 View 的信号 clicked 来打开/显示 QDialog 而不是委托(delegate),
  • 并使用 QDataWidgetMapper 将对话框内的控件与模型字段相关联。

然后可以重复使用相同的 QDialog,在使用 exec() 显示之前,您可以使用 QDataWidgetMapper::setCurrentIndex 填充控件以及在用户验证或取消更改后 QDataWidgetMapper::submit()revert()

由于 QDataWidgetMapperQTableView 将共享相同的模型,因此 TableView 将自动更新。

关于c++ - 使用委托(delegate)一次编辑多个数据项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9284611/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com