Reputation: 1843
In a non-editable QComboBox, if you press some keys quickly, a search will be performed in the displayed texts and the first item which has the prefix you typed will be selected. For example, if there are six items in the combobox, "Alabama", "Alaska", "California", "Colorado", "Ohio" and "Louisiana", and you press C, "California" will be selected. If you wait some time and press O, "Ohio" will be selected. However, if you quickly type "CO", "Colorado" will be selected.
Is this behaviour a Qt's feature? Apparently, this works universally, in spite of the GUI framework underneath. If it is Qt that handles this, can I customize it? What I want to do is basically perform the search based in data that is not displayed in the ComboBox. For example, in a ComboBox to select users, in which the logins are listed, it would suffice to type the user's last name to select it. It would be enough to search for matches in the middle of the text, though (for example, typing "nia" to select "California").
At first, QCompleter seemed to help, but it looks like it would only be useful in an editable QComboBox...
If this is not possible with QComboBox, which widget should be used to achieve this?
Thanks for the attention.
Upvotes: 2
Views: 5010
Reputation: 12331
You subclass QComboBox
and reimplement the keyPressEvent
. Let's assume that in your combo box you have implemented a function that adds an entry with two arguments: the login name and the actual name:
void MyComboBox::addEntry(QString loginName, QString name)
{
addItem(loginName);
// Store the name in a member variable, eg a map between names and login names
namesMap.insert(name, loginName);
}
void MyComboBox::keyPressEvent(QKeyEvent *evt)
{
QString currentString = ebt->text();
if (currentString.isEmpty())
{
QComboBox::keyPressEvent(evt);
return;
}
// Iterate through the map and search for the given name
QMapIterator<QString, QString> it(namesMap);
while(it.hasNext())
{
it.next();
QString name = it.key();
if (name.contains(currentString))
{
// it.value() is the login name corresponding to the name
// we have to find its index in the combo box in order to select it
int itemIndex = findText(it.value());
if (itemIndex >= 0)
setCurrentIndex(itemIndex);
return;
}
}
Upvotes: 2