C++ 如何仅使一个QComboBox项可编辑?
我的Qt应用程序中有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
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);