C++ 如何仅使一个QComboBox项可编辑?

C++ 如何仅使一个QComboBox项可编辑?,c++,qt,qcombobox,C++,Qt,Qcombobox,我的Qt应用程序中有QComboBox,我希望它有几个默认的、不可编辑的项目,但我也希望它有一个可编辑的项目,它有默认文本,但在编辑后会被替换,并且在默认情况下按下一些确认按钮 以下是我尝试过的: QComboBox* combo_1 = new QComboBox(); combo_1->setEditable(true); combo_1->addItems(QStringList()<<"Option_1."<<"Option_2."<<"O

我的Qt应用程序中有QComboBox,我希望它有几个默认的、不可编辑的项目,但我也希望它有一个可编辑的项目,它有默认文本,但在编辑后会被替换,并且在默认情况下按下一些确认按钮

以下是我尝试过的:

QComboBox* combo_1 = new QComboBox();
combo_1->setEditable(true);
combo_1->addItems(QStringList()<<"Option_1."<<"Option_2."<<"Option_3."<<"Option_4."<<"Other...");
这样,所有项目都是可编辑的,一旦我编辑任何项目并按enter键,它将保持不变,但带有编辑文本的新项目将插入到框中

我怎样才能达到我想要的行为?感谢您的帮助


另外,我指出我的目标是只有一个可编辑项,但我也想知道如何以相同的方式插入无限数量的新项。

解决方案是对组合框使用模型视图模式,并对QComboBox进行子类化

1:实现自定义模型。在我的例子中,我有行=2的可编辑项QString m_strEditableValue和0,1行的固定项

class MyModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit MyModel(QObject *parent = nullptr);

    QModelIndex index(int row, int column, const QModelIndex &parent) const;
    QModelIndex parent(const QModelIndex &child) const;
    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    Qt::ItemFlags flags(const QModelIndex &index) const;

private:
    QString m_strEditableValue;

};

MyModel::MyModel(QObject *parent) : QAbstractItemModel(parent)
{
    m_strEditableValue = "default value";
}

QModelIndex MyModel::index(int row, int column, const QModelIndex &parent) const
{
    return createIndex(row, column);
}

QModelIndex MyModel::parent(const QModelIndex &child) const
{
    return QModelIndex();
}

int MyModel::rowCount(const QModelIndex &parent) const
{
    return 3;
}

int MyModel::columnCount(const QModelIndex &parent) const
{
    return 1;
}

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
        if (index.row() == 0) {
            return tr("First fixed value");
        }
        if (index.row() == 1) {
            return tr("Second fixed value");
        }

        if (index.row() == 2) {
            return m_strEditableValue;
        }
    }

    return QVariant();
}

bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role == Qt::EditRole) {
        if (index.row() == 2) {
            m_strEditableValue = value.toString();
            return true;
        }
    }

    return false;
}

Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags f = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    if (index.row() == 2) {
        //mark editable only for row 2
        f = f | Qt::ItemIsEditable;
    }
    return f;
}
2:子类QComboBox更改标准行为

class MyCombobox : public QComboBox
{
    Q_OBJECT
public:
    explicit MyCombobox(QWidget *parent = nullptr);

private slots:
    void OnEditTextChanged(const QString& text);
    void OnCurrentIndexChanged(int index);

public slots:
};

MyCombobox::MyCombobox(QWidget *parent) : QComboBox(parent)
{
    connect(this, &QComboBox::editTextChanged, this, &MyCombobox::OnEditTextChanged);
    connect(this, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MyCombobox::OnCurrentIndexChanged);
}

void MyCombobox::OnEditTextChanged(const QString &text)
{
    if (model()) {
        //set data to model immediately 
        model()->setData(model()->index(currentIndex(), 0), text);
    }
}

void MyCombobox::OnCurrentIndexChanged(int index)
{
    if (model())
    {
        //disable editing if model disable it
        Qt::ItemFlags flags = model()->flags(model()->index(index, 0));
        if (flags & Qt::ItemIsEditable) {
            lineEdit()->setReadOnly(false);
        } else {
            lineEdit()->setReadOnly(true);
        }
    }
}

谢谢你的回答。不幸的是,我有一个问题,我希望你能指出问题所在。我能够创建MyCombobox的实例,但一旦我尝试将任何数据设置为MyModel,包括在MyModel实例上使用setModel方法,我的应用程序就会崩溃,如您的回答所示。知道为什么吗。检查崩溃点:在模型创建或setModel 2上。尝试将另一个模型设置为组合框,如QStandarItemModel3。使用组合框的替代创建。如果通过GUI设计器创建小部件子类MyCuMBOBOX,则只尝试在C++侧创建。4.当然,检查一下你的combobox是否不为空,也许是因为一些奇怪的原因,我可以将QStandardItemModel设置为MyCombobox,我也可以将MyModel设置为QComboBox,所有这些都不会崩溃。但不幸的是,他们两个都不合作,这真的让人困惑
MyModel *cbModel = new MyModel(this);
ui->cbEditable->setModel(cbModel);