Проблема с получением `QWidget* editor` для`QModelIndex`
У меня возникли проблемы с расширением стандартного поведения редактирования QTableView
, Я хочу следующее поведение при нажатии клавиши Enter:
- Начните редактировать текущую ячейку, если она еще не редактируется.
- Если ячейка редактируется,
- 2а. зафиксируйте данные и закройте редактор. Затем,
- 2b. сделайте ячейку ниже, если она есть, текущей ячейкой.
2a - поведение по умолчанию, а 2b, вероятно, может быть достигнуто с помощью QAbstractItemView::setCurrentIndex()
в повторной реализации QItemDelegate::eventFilter()
(как предлагается здесь в аналогичном контексте).
Проблема в достижении 1. Я перечисляю ниже подходы, которые я пробовал до сих пор.
- Переконфигурируйте "клавишу редактирования платформы". По умолчанию "Редактирование начинается, когда клавиша редактирования платформы была нажата над элементом". (
QAbstractItemView::EditKeyPressed
) Этот ключ - F2 на моей платформе (Ubuntu 12.04). Я мог бы перенастроить ключ редактирования платформы на Enter, но- Изменение настроек платформы по умолчанию кажется плохой идеей.
- Я не мог узнать, как это сделать.
Захватить клавишу ввода, нажмите я использую
QShortCut
сделать это следующим образом:class CourseTable : public QTableView { /* ... */ }; /* ... */ CourseTable::CourseTable(/* ... */) { /* ... */ QShortcut* shortcut = new QShortcut(QKeySequence(Qt::Key_Return), this); connect(shortcut, SIGNAL(activated()), this, SLOT(handleEnter_())); /* ... */ } /* ... */ void CourseTable::handleEnter_() { QModelIndex idx = this->currentIndex(); if (this->state() != QAbstractItemView::EditingState) this->edit(idx); /* else // see below */ }
Это захватывает нажатие клавиши Enter и выполняет 1 (сверху), но теперь 2 не работает. Итак, мне нужно посмотреть в
else
пункт вCourseTable::handleEnter_()
выше, возможно, звонитQAbstractItemView::commitData()
а такжеQAbstractItemView::closeEditor
в этом. Проблема в том, что обе эти функции требуютQWidget *editor
аргумент, который я просто не могу понять, как получить. Я мог бы подклассQAbstractItemDelegate
, добавитьgetEditor()
метод к производному классу, и измените существующий код, чтобы передать экземпляры производного класса делегатаCourseTable::setItemDelegate*()
функции. Но это звучит как слишком много работы.
Итак, есть какие-нибудь идеи, как я могу без проблем переписать код 1 и 2?
1 ответ
Почему вы не можете просто отфильтровать событие и начать редактирование?
Просто обработайте событие, если состояние равно!= QAbstractItemView::EditingState
Возвращение true в этой функции приводит к тому, что событие перестает распространяться на фильтруемый объект.
Если состояние редактирует, вы можете просто вернуть false и разрешить таблице и редактору продолжить обработку события.
Что-то вроде этого:
bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
if (object == tableView && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return && tableView->state() != QAbstractItemView::EditingState) {
// set current cell to edit
return true;
} else
return false;
}
return false;
}