QStyledItemDelegate: зафиксировать значение QComboBox для моделирования по клику
Я устанавливаю QStyledItemDelegate
на моей модели для определенного поля, и возвращая QComboBox
от QStyledItemDelegate::createEditor
QComboBox* createEditor(QWidget* parent)
{
QComboBox* cb = new QComboBox(parent);
cb->addItem("UNDEFINED");
cb->addItem("TEST");
cb->addItem("OSE");
cb->addItem("TSE");
return cb;
}
void setEditorData(QWidget* editor, const QModelIndex& index)
{
QComboBox* cb = qobject_cast<QComboBox*>(editor);
if (!cb)
throw std::logic_error("editor is not a combo box");
QString value = index.data(Qt::EditRole).toString();
int idx = cb->findText(value);
if (idx >= 0)
cb->setCurrentIndex(idx);
cb->showPopup();
}
Это работает нормально, и когда я выбираю рассматриваемое поле, мне отображается поле со списком.
Когда я выбираю опцию из выпадающего списка, выпадающий список закрывается, и рядом с ним отображается выпадающий значок:
На данный момент я хотел бы QStyledItemDelegate::setModelData
вызываемая функция, так что выбор элемента в списке фиксирует данные в модели.
Тем не менее, я должен сначала нажать Enter, чтобы зафиксировать данные (при этом исчезает раскрывающийся значок)
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)
{
QComboBox* cb = qobject_cast<QComboBox*>(editor);
if (!cb)
throw std::logic_error("editor is not a combo box");
model->setData(index, cb->currentText(), Qt::EditRole);
}
Вопрос:
Как я могу настроить свой QComboBox
для автоматической фиксации данных, когда пользователь выбирает элемент в списке и закрывается список со списком, вместо того, чтобы требовать дополнительного нажатия кнопки Enter
?
1 ответ
Вы должны выдать сигнал commitData
а также closeEditor
когда элемент выбран, как показано в следующем примере:
#include <QApplication>
#include <QStandardItemModel>
#include <QListView>
#include <QStyledItemDelegate>
#include <QComboBox>
class ComboBoxDelegate: public QStyledItemDelegate{
public:
using QStyledItemDelegate::QStyledItemDelegate;
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const{
Q_UNUSED(option)
Q_UNUSED(index)
QComboBox* editor = new QComboBox(parent);
connect(editor, QOverload<int>::of(&QComboBox::activated),
this, &ComboBoxDelegate::commitAndCloseEditor);
editor->addItems({"UNDEFINED", "TEST", "OSE", "TSE"});
return editor;
}
void setEditorData(QWidget *editor, const QModelIndex &index) const{
QComboBox* cb = qobject_cast<QComboBox*>(editor);
if (!cb)
throw std::logic_error("editor is not a combo box");
QString value = index.data(Qt::EditRole).toString();
int idx = cb->findText(value);
if (idx >= 0)
cb->setCurrentIndex(idx);
cb->showPopup();
}
private:
void commitAndCloseEditor(){
QComboBox *editor = qobject_cast<QComboBox *>(sender());
emit commitData(editor);
emit closeEditor(editor);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QListView view;
QStandardItemModel model;
for(int i=0; i<10; i++){
model.appendRow(new QStandardItem("UNDEFINED"));
}
view.setItemDelegate(new ComboBoxDelegate(&view));
view.setModel(&model);
view.show();
return a.exec();
}