QStyledItemDelegate: зафиксировать значение QComboBox для моделирования по клику - PullRequest
0 голосов
/ 12 июня 2018

Я устанавливаю 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();
}

Это работает нормально, и когда я выбираю соответствующее полеМне показано поле со списком.

combobox open

Когда я выбираю опцию из выпадающего списка, выпадающий список закрывается, и элемент отображается срядом с ним выпадающий значок:

selected

На этом этапе я хотел бы вызвать функцию QStyledItemDelegate::setModelData, чтобы выбрать элемент всписок передает данные в модель.

Однако мне необходимо сначала нажать Введите , чтобы зафиксировать данные (в результате исчезает раскрывающийся значок)

committed

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 Ответ

0 голосов
/ 13 июня 2018

Вы должны подать сигнал 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();
}
...