无法为`QModelIndex`获取`QWidget * editor`

时间:2012-09-15 14:09:57

标签: qt qt4 qtableview model-view

我无法扩充QTableView的默认编辑行为。按下Enter键时我想要以下行为:

  1. 如果当前单元格尚未编辑,则开始编辑它。
  2. 如果正在编辑单元格,
    • 2a上。提交数据并关闭编辑器。然后,
    • 2B。将当前单元格放在下面(如果存在)。
  3. 2a是默认行为,可以通过在QAbstractItemView::setCurrentIndex()的重新实现中使用QItemDelegate::eventFilter()来实现2b(在类似的上下文中建议为here)。

    问题在于实现1.我在下面列出了我迄今为止尝试过的方法。

    • 重新配置“平台编辑密钥”默认情况下,“在项目上按平台编辑键时开始编辑”。 (QAbstractItemView::EditKeyPressed)这个密钥在我的平台上是F2(Ubuntu 12.04)。我可以将平台编辑键重新配置为Enter但是
      • 改变平台默认值似乎是一个坏主意。
      • 我找不到怎么做。
    • 按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 个答案:

答案 0 :(得分:2)

为什么你只是为了开始编辑而过滤事件?

如果状态为!= QAbstractItemView :: EditingState

,则只处理事件

在此函数中返回true会使事件停止传播到已过滤的对象。

如果state是Editing,你可以返回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;
 }