Проблема с получением `QWidget* editor` для`QModelIndex`

У меня возникли проблемы с расширением стандартного поведения редактирования QTableView, Я хочу следующее поведение при нажатии клавиши Enter:

  1. Начните редактировать текущую ячейку, если она еще не редактируется.
  2. Если ячейка редактируется,
    • 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;
 }
Другие вопросы по тегам