我有一个QTableView,它的模型中有一些基于QString的项目。 我在表模型中实现了 setData,因此编辑是有效的(我可以更改单元格中的数据,调用 setData 来更新模型,并且表已正确更新)。
目前,只有在用户完成编辑时才会调用 setData,例如,在他们按 Enter 或单击文本输入框以完成文本输入之后。 我想在用户键入/编辑文本编辑控件时更新表的其他部分,而不是在完成并最终确定编辑的内容之后。
我想要的一个简单示例是让下一个表格单元格显示已输入到正在编辑的单元格中的字符数,但在用户键入/编辑单元格内容时执行此操作,而不仅仅是在编辑完成并调用 setData 之后。
有什么指示指向我应该寻找什么吗? 谢谢!
您可以子类化QStyledItemDelegate
并在发生更改时提交数据,然后使用 QAbstractItemView::setItemDelegate
为视图设置该委托。
class MyDelegate : public QStyledItemDelegate {
QSignalMapper *mapper;
public:
MyDelegate(QObject*parent = 0)
: QStyledItemDelegate(parent)
, mapper(new QSignalMapper(this))
{
connect(mapper, SIGNAL(mapped(QWidget*)), SIGNAL(commitData(QWidget*)));
}
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option,
const QModelIndex & index ) const
{
QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
if(qobject_cast<QLineEdit*>(editor)) {
connect(editor, SIGNAL(textChanged(QString)), mapper, SLOT(map()));
mapper->setMapping(editor, editor);
}
return editor;
}
};
当我需要一个持久的答案时,@alexisdm提供的答案对我不起作用编辑器由 QAbstractTableModel::setPersistentEditor(QModelIndex())
启用。
下面解决了这个问题:
class Delegate : public QStyledItemDelegate
{
Q_OBJECT
public:
// ... omitted for brevity
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
auto *editor = static_cast<QLineEdit*>(
QStyledItemDelegate::createEditor(parent, option, index));
if (editor) {
connect(editor,
&QLineEdit::textChanged,
[=] (const QString &)
{
const_cast<Delegate*>(this)->commitData(editor);
});
}
return editor;
}
// ... omitted for brevity
};
我们只是从this
中转换恒常性,并使其为编辑器提交数据。
请注意,在 lambda 中,我们按值[=]
捕获editor
变量,否则,当函数超出范围时,使用引用捕获将使editor
的值未定义。