默认情况下,双击后,QTableView
中的单元格开始编辑。如何改变这种行为。 我需要它才能在点击一下后开始编辑。
我已将组合框委托设置为单元格。单击单元格时,它只选择它。双击单元格时,QComboBox
编辑器已激活但未展开。我希望它只需点击一下即可展开,就像我QComboBox
setCellWidget
QTableWidget
函数一样。我使用model-view-delegate需要相同的效果。
答案 0 :(得分:16)
您可以设置编辑触发器使用此功能setEditTriggers
C ++
yourView->setEditTriggers(QAbstractItemView::AllEditTriggers)
的Python:
yourView.setEditTriggers(QAbstractItemView.AllEditTriggers)
枚举QAbstractItemView :: EditTrigger flags 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组合。
答案 1 :(得分:12)
点击一下后修改 您可以在使用
的视图中重新实现mousePressEventvoid 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的子类中以及在结束时调用showPopup来复制setEditorData。
但它有一些意想不到的行为。当鼠标离开其区域时,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,然后点击选择/隐藏,我现在不知道解决方案。
答案 2 :(得分:2)
基于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);
}
答案 3 :(得分:0)
如果您覆盖QStyledItemDelegate::createEditor()
,则可以在创建后展开组合框。
答案 4 :(得分:0)
此解决方案对我来说是完美的。单击一个单元格,然后弹出组合框。
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;
};