我有自己的QAbstractTableModel
子表模型。它安装在我的视图中(从QTableView
继承)。在视图中,我正在使用委托类(来自QItemDelegate
的子类)来编辑项目。
我想设置以下行为:当我使用我的委托完成数据编辑时,模型中的下一个项目(下一行和同一列中的项目)应该可以编辑。
文档说它是由QAbstractItemDelegate::EditNextItem
提示提供的,它以closeEditor()
信号发送。但默认情况下,此信号与QAbstractItemDelegate::NoHint
参数一起发送。问题是我在重新实现基本QItemDelegate
虚函数时不必显式调用此信号,例如setModelData()
。
文档还说,此信号由内部事件过滤器发送,该过滤器在调用QAbstractItemDelegate()
构造函数时安装在项目委托上。
我怎样才能在EndEditHint
信号中提供自己的closeEditor()
?
答案 0 :(得分:1)
完成编辑后,代理会发送带有closeEditor()
提示的SubmitModelCache
信号。您必须保持此行为才能正确更新模型。
要在提交上一次编辑的数据后立即在下一个单元格中打开编辑器,您可以重新实现QItemDelegate::eventFilter()
,但我发现重新实现QAbstractItemView::closeEditor()
方法会更容易:
void CMyTableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
{
QTableView::closeEditor(editor, hint);
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier);
if (!index.isValid())
return;
QPersistentModelIndex persistent(index);
selectionModel()->setCurrentIndex(persistent, flags);
// currentChanged signal would have already started editing
if (index.flags() & Qt::ItemIsEditable && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
edit(persistent);
}
更简单的解决方案是(我不确定,但绝对值得一试):
void CMyTableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
{
QTableView::closeEditor(editor, hint);
QTableView::closeEditor(nullptr, QAbstractItemDelegate::EditNextItem);
}
moveCursor()
方法返回下一列和同一行的索引。如果要更改此行为,请重新实现它:
QModelIndex CMyTableView::moveCursor(CursorAction action, Qt::KeyboardModifiers modifiers)
{
if (action == QAbstractItemView::MoveNext)
action = QAbstractItemView::MoveDown;
else if (action == QAbstractItemView::MovePrevious)
action = QAbstractItemView::MoveUp;
// Next row, same column.
return QTableView::moveCursor(action, modifiers);
}
顺便说一下:当您按 Tab 键时,默认的QTableView
行为是关闭当前编辑器,保存数据和下一个单元格已编辑。
所以,也许你唯一需要做的就是重新实现QTableView::moveCursor()
方法。