How does QLineEdit triger QAbstractItemDelegate::commitData



我正在使用QTreeViewQAbstractItemModel开发Qt应用程序。 该模型包含一些异构数据,需要不同的控件进行编辑。我通过有一个自定义委托来实现它,该委托model.data(Qt::EditRole)查询,模型将返回用作编辑器的QWidget

我喜欢它对QLineEdit的工作方式 - 当我按回车键时,delegate::setModelData会自动调用,所以我不必QLineEdit::editingFinished连接到QAbstractItemDelegate::setModelData()这非常方便,因为 QLineEdit 作为QWidget从模型返回给委托,它不必关心它是什么样的小部件。 有了QComboBox,这有点棘手 - 我希望 comboBox 在做出选择后提交,到目前为止我只能通过connect(myComboBox, SIGNAL(activated(QString)), myDelegate, commitData()));来做到这一点 但是,我的委托不知道编辑器小部件的类型,我不想为模型最终传递的每个新编辑器编辑委托的代码。我真的很想强制组合框做与 QLineEdit 相同的事情,当在连接到其activated()信号的插槽中单击输入时。

那么,QLineEdit如何调用代表setModelData? Qt中是否有一种通用的方式,让编辑器说"我完成了编辑,获取数据并将其传递给模型"?

QStyledItemDelegate

(和QItemDelegate)定义了一个事件过滤器,如果您按 Tab 或返回,该过滤器将调用commitData

请参阅以下摘自Qt 4.8.6源代码的摘录:

bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event)
{
QWidget *editor = qobject_cast<QWidget*>(object);
if (!editor)
return false;
if (event->type() == QEvent::KeyPress) {
switch (static_cast<QKeyEvent *>(event)->key()) {
case Qt::Key_Tab:
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
return true;
case Qt::Key_Backtab:
emit commitData(editor);
emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
return true;
case Qt::Key_Enter:
case Qt::Key_Return:
#ifndef QT_NO_TEXTEDIT
if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor))
return false; // don't filter enter key events for QTextEdit
// We want the editor to be able to process the key press
// before committing the data (e.g. so it can do
// validation/fixup of the input).
#endif // QT_NO_TEXTEDIT
#ifndef QT_NO_LINEEDIT
if (QLineEdit *e = qobject_cast<QLineEdit*>(editor))
if (!e->hasAcceptableInput())
return false;
#endif // QT_NO_LINEEDIT
QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor",
Qt::QueuedConnection, Q_ARG(QWidget*, editor));
return false;
case Qt::Key_Escape:
// don't commit data
emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
break;
default:
return false;
}
if (editor->parentWidget())
editor->parentWidget()->setFocus();
return true;
} else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
//the Hide event will take care of he editors that are in fact complete dialogs
if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
QWidget *w = QApplication::focusWidget();
while (w) { // don't worry about focus changes internally in the editor
if (w == editor)
return false;
w = w->parentWidget();
}
#ifndef QT_NO_DRAGANDDROP
// The window may lose focus during an drag operation.
// i.e when dragging involves the taskbar on Windows.
if (QDragManager::self() && QDragManager::self()->object != 0)
return false;
#endif
emit commitData(editor);
emit closeEditor(editor, NoHint);
}
} else if (event->type() == QEvent::ShortcutOverride) {
if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
event->accept();
return true;
}
}
return false;
}

相关内容

  • 没有找到相关文章

最新更新