- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我的应用程序中,我有一个 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
使模型只读,clicked
来打开/显示 QDialog
而不是委托(delegate),QDataWidgetMapper
将对话框内的控件与模型字段相关联。然后可以重复使用相同的 QDialog
,在使用 exec()
显示之前,您可以使用 QDataWidgetMapper::setCurrentIndex
填充控件以及在用户验证或取消更改后 QDataWidgetMapper::submit()
或 revert()
。
由于 QDataWidgetMapper
和 QTableView
将共享相同的模型,因此 TableView 将自动更新。
关于c++ - 使用委托(delegate)一次编辑多个数据项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9284611/
我正在尝试弄清楚如何将一些数据从手机同步到 Android Wear 设备,并且我已经阅读了 developer.android.com 上关于数据项的文章,但是我仍然不清楚究竟如何使用它们。具体来说
$("selector").data("name", null); console.log($("selector").data("name")); 这将打印未定义。 有没有办法在元素的 jQuery
我使用 LINQ 从 CheckBoxList 控件中检索选中的项目: 这里是 LINQ: IEnumerable allChecked = (from ListItem item in Ch
在尝试为 C 堆栈构建测试平台时,我遇到了如何正确显示它的问题。我已经检查了六本书,它们都有一种将堆栈插入堆栈或从堆栈弹出的方法,但没有一本示例说明您如何实际使用这些例程。谁能告诉我模式,这样我就可以
我尝试在 AppEngine 中使用 urlfetch 将 POST 数据发送到服务器。其中一些 POST 数据项具有相同的名称,但具有不同的值。 form_fields = { "data":
我有以下情况(使用 KendoUI): 我有一个绑定(bind)到数据源的网格。当我在网格中选择一行时,我会调用其“change”事件来让所选的 dataItem e 通过其他 HTML 元素显示其值
我基本上是在构建一个快速而肮脏的类(class)目录,其中包含多个层次类别以及属于不同级别的这些类别的类(class)。 在旧的实现中,每个主要类别都有自己的 HTML 页面,与该类别相关的所有类(c
我是 MVC 和 ASP.NET 的新手,希望学习一些东西,所以我正在尝试制作一些简单的应用程序来学习来龙去脉。 好吧,我正在尝试让一个下拉框显示一个图书列表,它会在其中显示图书的标题,但会发布 bo
此行为导致我的项目出现问题。这是正在发生的事情的简化版本。我想了解为什么会发生这种情况,以及如何避免这种情况。我已将 vue 加载到我的网站头部: 这是 Vue 对象: vueObject = ne
我是一名优秀的程序员,十分优秀!