QItemDelegate,如何在closeEditor()信号中提供我自己的EndEditHint?

时间:2016-04-11 14:53:39

标签: c++ qt qitemdelegate

我有自己的QAbstractTableModel子表模型。它安装在我的视图中(从QTableView继承)。在视图中,我正在使用委托类(来自QItemDelegate的子类)来编辑项目。

我想设置以下行为:当我使用我的委托完成数据编辑时,模型中的下一个项目(下一行和同一列中的项目)应该可以编辑。

文档说它是由QAbstractItemDelegate::EditNextItem提示提供的,它以closeEditor()信号发送。但默认情况下,此信号与QAbstractItemDelegate::NoHint参数一起发送。问题是我在重新实现基本QItemDelegate虚函数时不必显式调用此信号,例如setModelData()

文档还说,此信号由内部事件过滤器发送,该过滤器在调用QAbstractItemDelegate()构造函数时安装在项目委托上。

我怎样才能在EndEditHint信号中提供自己的closeEditor()

1 个答案:

答案 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()方法。