2

我正在尝试从 QTableView 编写一些继承类(我们称之为 A),并希望覆盖插槽

无效编辑 ( const QModelIndex & index )

来自 QAbstractItemView。我知道这个功能可以触发编辑模式,但这是我的问题:我希望每当编辑模式由这个类 A 中的用户触发时,程序可以进入被覆盖的插槽A::edit内。

但是,似乎只有直接调用A::edit时,程序才能进入。

由于 QTableView 来自 QAbstractItemView,如果编辑模式被其他方式触发(如鼠标双击),程序将运行默认的QAbstractItemView::edit而不是A::edit

我试图连接“激活”信号,但显然它不是触发编辑模式的正确信号。每次触发编辑器时,无论如何都要做一些事情吗?

另外,当编辑模式结束时,我想通过按 Enter 或 ESC 或鼠标单击其他位置来做一些事情。同样的情况也发生在插槽

void editorDestroyed (QObject * editor)

谁能帮我解决这个问题?我会很感激的,谢谢!

4

1 回答 1

5

QAbstractItemView::edit(const QModelIndex& index) 不是virtual,所以这就是为什么当你直接调用它时你会得到你的子类的行为,但是当现有的代码调用它时,它们会得到基类的行为。如果这没有响起,请阅读该链接;Qt 有很多虚拟和非虚拟功能,知道它们之间的区别会为您省去很多麻烦。

但是,QAbstractItemView::edit(const QModelIndex& index, EditTrigger trigger, QEvent* event) 虚拟的,因此您可以覆盖它。我还没有验证过,但想必非虚拟的edit()调用了这个edit(),所以应该有同样的效果。

QAbstractItemView::editorDestroyed(QObject* editor) 也是虚拟的,所以我不确定它为什么不起作用。但是,还有QAbstractItemView::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint)也是虚拟的,因此您可能想尝试在您的子类中重新实现它。closeEditor() 文档还建议 commitData(),它也是虚拟的。Qt 项目视图有很多类似的方法,所以不要假设你看到的第一个会完全按照你的意愿/期望做。

仅供参考,如果您不习惯在子类中重新实现虚拟方法,确保您的实现被调用的最快/最简单的方法是执行以下操作:

class A : public QTableView {
    void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) {
        qDebug("my closeEditor was called!");
        // call the real implementation so that the base class continues to work properly
        QTableView::closeEditor(editor, hint);
    }
};

您可以使用 edit()、editorDestroyed()、closeEditor() 和 commitData() 来执行此操作,以查看何时调用了哪些。

于 2012-09-12T02:32:03.883 回答