【发布时间】:2016-05-19 08:04:24
【问题描述】:
我想创建一个QComboBox,允许您选择值或输入您自己的值。它应该可以工作,如果您选择可编辑选项并输入文本,那将是该选项的文本。如果您选择其他,然后返回到可编辑的,您输入的文本应该会保留。
我已经取得了一些进展。它看起来像这样:
组合框菜单
已选择可编辑项
选择了普通项目
我使用事件过滤器实现了这一点:
class MagicComboBoxEventFilter : public QObject {
public:
explicit MagicComboBoxEventFilter(QObject* parent=0) :
QObject(parent),
parentBox(nullptr),
lastValue(""),
editableIndex(-1)
{
parentBox = dynamic_cast<QComboBox*>(parent);
if(parentBox) {
connect(parentBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &MagicComboBoxEventFilter::currentIndexChanged);
}
public slots:
void currentIndexChanged(int index) {
// Item data entry is unused, so I used it to determine
// the editable field from others
bool editable = parentBox->itemData(index).toInt()==666;
parentBox->setEditable(editable);
}
private:
QComboBox* parentBox;
};
这适用于新的组合框:
QComboBox* comboBox = new QComboBox(this);
comboBox->setEditable(false);
new MagicComboBoxEventFilter(comboBox);
我面临的问题是即使用户选择了其他项目,如何保持可编辑值。我试图连接可编辑的文本更改事件,这是我增强的事件过滤器。我不会重复整个类代码,唯一的另一件事是现在构造函数中有额外的connect调用:
public slots:
void currentIndexChanged(int index) {
bool editable = parentBox->itemData(index).toInt()==666;
parentBox->setEditable(editable);
// If editable field selected, restore the last value entered
if(editable) {
parentBox->setItemText(index, lastValue);
}
}
// slot connected in constructor
void editTextChanged(const QString& text) {
lastValue = text;
}
private:
QComboBox* parentBox;
// Last string value the editable field had
// qt doesn't remember that
QString lastValue;
问题在于,当用户选择其他项目时 editTextChanged 在 currentIndexChanged 之前触发 并且我最终在lastValue 中拥有所选项目的文本,而不是最后输入的文本。
如何解决这个问题?我真的很努力,我需要一些帮助。
【问题讨论】:
-
也许通过获取 QComboBox 的孩子,这是一个 QStandardItemModel,并在这个上安装另一个事件过滤器?我没有时间测试你的代码,但这个问题的答案可能会让我感兴趣
标签: qt qcombobox eventfilter