20

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

我已将组合框委托设置为单元格。单击单元格时,它只会选择它。双击单元格时,QComboBox编辑器被激活但未展开。我希望它只需单击一下就可以展开,就好像我QComboBox通过setCellWidget. QTableWidget通过使用模型-视图-委托,我需要相同的效果。

4

5 回答 5

21

您可以使用此功能 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 组合。

于 2015-07-03T03:33:07.167 回答
17

一键编辑 您可以在您正在使用的视图中重新实现 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,然后单击选择/隐藏,我现在不知道解决方案。

于 2013-09-17T12:53:15.053 回答
4

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

为了单击启动编辑器,我将QAbstractItemView::clicked(const QModelIndex &index)视图的信号连接到QAbstractItemView::edit(const QModelIndex &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,则不需要该插槽。您所要做的就是QComboBox::showPopup使用来自 的排队连接进行呼叫MyDelegate::createEditor。最简单的方法是使用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);
}
于 2016-03-30T09:31:23.940 回答
2

这个解决方案对我来说很完美。单击一个单元格,就会弹出组合。

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;
};
于 2018-11-14T15:53:59.587 回答
0

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

于 2013-09-16T20:25:04.583 回答