По умолчанию ячейка в QTableView
начинает редактироваться после двойного щелчка. Как изменить это поведение. Мне нужно, чтобы начать редактирование после одного клика.
Я установил делегат со списком в ячейку. При нажатии на ячейку он только выбирает ее. При двойном щелчке по ячейке QComboBox
Редактор активирован, но не расширен. Я хочу, чтобы он расширился после одного клика, как будто я добавил QComboBox
от setCellWidget
функция QTableWidget
, Мне нужен тот же эффект, используя модель-представление-делегат.
Редактировать после одного клика
Вы можете переопределить 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 при редактировании
Вы должны реализовать setEditorData в вашем подклассе QItemDelegate и в конце вызова 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, а затем нажмите, чтобы выбрать / скрыть, я пока не знаю решения.
Вы можете просто установить триггер редактирования, используя эту функцию setEditTriggers
C ++
yourView->setEditTriggers(QAbstractItemView::AllEditTriggers)
Python:
yourView.setEditTriggers(QAbstractItemView.AllEditTriggers)
enum 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 — это typedef для QFlags. Он хранит комбинацию ИЛИ значений EditTrigger.
Основываясь на идее, предложенной Джейсоном, я придумал это решение.
Чтобы запустить редактор одним кликом, я подключил 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);
}
Если вы переопределите QStyledItemDelegate::createEditor()
затем вы можете развернуть поле со списком после его создания.
Это решение прекрасно работает для меня. Один щелчок по ячейке, и всплывающее меню.
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;
};