【问题标题】:Qt: start editing of cell after one clickQt:单击后开始编辑单元格
【发布时间】:2013-09-20 19:02:22
【问题描述】:

默认情况下,QTableView 中的单元格在双击后开始被编辑。如何改变这种行为。 我需要它一键开始编辑。

我已将组合框委托设置为单元格。单击单元格时,它只会选择它。双击单元格时,QComboBox 编辑器被激活但未展开。我希望它在单击后展开,就好像我通过setCellWidgetQTableWidget 函数添加了QComboBox。通过使用模型-视图-委托,我需要相同的效果。

【问题讨论】:

标签: c++ qt delegates qtableview model-view


【解决方案1】:

这个解决方案对我来说非常有效。单击一个单元格,就会弹出组合。

class GFQtComboEnumItemDelegate : public QStyledItemDelegate
{
    void setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QComboBox* pE = qobject_cast<QComboBox*>(editor);
        ... // init the combo here
        if(m_must_open_box)
        {
            m_must_open_box = false;
            pE->showPopup();
        }
    }


    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
    {
        if (event->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent* pME = static_cast<QMouseEvent*>(event);
            if(pME->button() == Qt::LeftButton)
            {
                QAbstractItemView* pView = qobject_cast<QAbstractItemView*>( const_cast<QWidget*>(option.widget) );
                if(pView != nullptr)
                {
                    emit pView->setCurrentIndex(index);
                    m_must_open_box = true;
                    emit pView->edit(index);
                }
                return true;
            }
        }
        return QStyledItemDelegate::editorEvent(event, model, option, index);
    }
    mutable bool m_must_open_box;
};

【讨论】:

    【解决方案2】:

    根据 Jason 提供的想法,我想出了这个解决方案。

    为了通过单击启动编辑器,我将视图的 QAbstractItemView::clicked(const QModelIndex &amp;index) 信号连接到同一视图的 QAbstractItemView::edit(const QModelIndex &amp;index) 插槽。

    如果你使用Qt4,你需要在你的委托中创建一个槽。将您的组合框作为参数传递给此插槽。在此插槽中,您调用QComboBox::showPopup。所以它看起来像这样:

    void MyDelegate::popUpComboBox(QComboBox *cb)
    {
        cb->showPopup();
    }
    

    但首先我们需要注册QComboBox* 类型。您可以在委托的构造函数中调用它:

    qRegisterMetaType<QComboBox*>("QComboBox*");
    

    我们需要这个插槽的原因是因为我们不能在MyDelegate::createEditor 中直接显示弹出窗口,因为列表视图的位置和矩形是未知的。所以我们要做的是在MyDelegate::createEditor,我们用一个排队的连接来调用这个槽:

    QComboBox *cb = new QComboBox(parent);
    // populate your combobox...
    QMetaObject::invokeMethod(const_cast<MyDelegate*>(this), "popUpComboBox", Qt::QueuedConnection, Q_ARG(QComboBox*, cb));
    

    这将在激活编辑器时正确显示组合框的列表视图。

    现在,如果您使用的是 Qt5,则不需要该插槽。您所要做的就是使用来自MyDelegate::createEditor 的排队连接呼叫QComboBox::showPopup。最简单的方法是使用QTimer

    QTimer::singleShot(0, cb, &QComboBox::showPopup);
    

    对于一些额外信息,您可以通过以下方式绘制组合框,使其始终显示,而不仅仅是在显示编辑器时:

    void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(index.column() == 1) // show combobox only in the second column
        {
            QStyleOptionComboBox box;
            box.state = option.state;
    
            box.rect = option.rect;
            box.currentText = index.data(Qt::EditRole).toString();
    
            QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &box, painter, 0);
            QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &box, painter, 0);
            return;
        }
        QStyledItemDelegate::paint(painter, option, index);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用此函数 setEditTriggers 设置编辑触发器

      C++

      yourView->setEditTriggers(QAbstractItemView::AllEditTriggers)
      

      Python:

      yourView.setEditTriggers(QAbstractItemView.AllEditTriggers)
      

      枚举 QAbstractItemView::EditTrigger 标记 QAbstractItemView::EditTriggers

      此枚举描述将启动项目编辑的操作。

      Constant    Value   Description
      QAbstractItemView::NoEditTriggers   0   No editing possible.
      QAbstractItemView::CurrentChanged   1   Editing start whenever current item changes.
      QAbstractItemView::DoubleClicked    2   Editing starts when an item is double clicked.
      QAbstractItemView::SelectedClicked  4   Editing starts when clicking on an already selected item.
      QAbstractItemView::EditKeyPressed   8   Editing starts when the platform edit key has been pressed over an item.
      QAbstractItemView::AnyKeyPressed    16  Editing starts when any key is pressed over an item.
      QAbstractItemView::AllEditTriggers  31  Editing starts for all above actions.
      

      EditTriggers 类型是 QFlags 的 typedef。它存储 EditTrigger 值的 OR 组合。

      【讨论】:

      • 这有一个特定的行为。单击一个单元格 -> 编辑 -> 退出编辑模式 -> 再次单击同一单元格,将不会进入编辑模式,而只是选择它。在 5.8.x 中观察到。所以,我会简单地 connect(tableView, SIGNAL(clicked(modelIndex), tableView, SLOT(edit(modelIndex))); 工作正常。
      【解决方案4】:

      一键编辑 您可以在您正在使用的视图中重新实现 mousePressEvent

      void YourView::mousePressEvent(QMouseEvent *event)
      {
          if (event->button() == Qt::LeftButton) {
              QModelIndex index = indexAt(event->pos());
              if (index.column() == 0) { // column you want to use for one click
                  edit(index);
              }
          }
          QTreeView::mousePressEvent(event);
      }
      

      编辑时扩展的 QCombobox 您应该在 QItemDelegate 的子类中实现 setEditorData,并在最后调用 showPopup。

      但它有一些意想不到的行为。当鼠标离开它的区域时,QComboBox 消失。但对我来说这是优势。 我可以通过单击和释放来选择不同的项目。

      void IconDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
      {
          Q_UNUSED(index);
          QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
          // Add data
          comboBox->addItem(QIcon(":/icons/information16.png"), "info");
          comboBox->addItem(QIcon(":/icons/warning16.png"), "warning");
          comboBox->addItem(QIcon(":/icons/send16.png"), "send");
          comboBox->addItem(QIcon(":/icons/select16.png"), "select");
          comboBox->showPopup(); // <<<< Show popup here
      }
      

      它们一起工作得很快。 单击并按住选择项目并在发布上提交数据(只需单击并释放)

      如果你想点击显示展开的 qcombobox,然后点击选择/隐藏,我暂时不知道解决方案。

      【讨论】:

        【解决方案5】:

        如果您覆盖QStyledItemDelegate::createEditor(),那么您可以在创建组合框后展开它。

        【讨论】:

        • createEditor() 中,视图不知道足够的信息来展开组合框。例如它的矩形。但是你的想法可能会被使用
        猜你喜欢
        • 2023-01-14
        • 2020-08-18
        • 1970-01-01
        • 2011-03-18
        • 2010-12-17
        • 2018-06-20
        • 2013-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多