2

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

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

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

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

我如何提供自己的EndEditHint输入closeEditor()信号?

4

1 回答 1

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

于 2016-04-15T08:02:01.850 回答