Я хочу сделать 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
, а не последний введенный текст.
Как это обойти? Я очень старался, и мне нужна помощь.