QComboBox autocomplete automatically changes edittext.
Hi guys I'm having a problem with QComboBox's autocompletion.
Create a QComboBox. Fill it with a couple of strings, say 'One', 'Two', 'Three'.
When the program is running enter one of those strings, but differ the case, into the combo. Change the focus to anything else, by clicking on another window or something.
THE TEXT WILL BE AUTOMATICALLY CHANGED TO THE FIRST MATCHING ITEM IN THE COMBO BOX!
For instance, if 'ONE' was entered it'll be changed to 'One'.
Is it possible to do Case-Insensitive autocompletion without the above happening?
I've tried changing the Completer. I've tried reimplementing focusOutEvent by adding the desired text to the combo box nor does restoring the desired text after focus is lost work (well). Even replacing the lineEdit (with it's own completer since QLineEdit's don't suffer from this problem) doesn't help.
Although I'm using PyQt4 (4.7.4 on Ubuntu) (I can post the code if anyone likes) create this I'm sure the problem lies with Qt (4.6.3)
Errata: This behaviour doesn't exist for Qt < 4.5 and I've posted this on both the PyQt mailing list and stackoverflow. Case-Sensitive completion works as expected, but is very close to useless.
What did you change the completer to? (Although it does say that case-sensitive is the default...)
I tried using the completer with my own model from scratch and
using QStringListModel. Getting case-insensitive completions using both methods worked fine, but the combo box would still change it's edit text if it differed in case from any preexisting item upon losing focus.
I mean - obvious question, but did you explicitly set case-sensitive on the QCompleter?
Yes, then the problem is resolved. But then autocompletion becomes almost useless as the I'd have to remember the original string as opposed to changing the case of various words as I type since no completion is suggested.
Let me be sure I understand, then... what you want is that the user starts typing, and items are suggested in a case-insensitive manner - but the completion does not happen unless the user explicitly selects it?
(For what it's worth, I don't think that this has anything to do with case-sensitivity - if you do as we discussed above and you do type in the "right" case, does it still auto-select it?)
...yes. Say there're the following items in the Combo Box. 'first item', 'second item' and 'third item'
Assume to completer is set to case-insensitive.
Now if the user started typing 'first', 'first item' will be the suggested completion and ' item' will then be highlighted. I can press Enter to accept the completion and the combo box's text will become 'first item'.
If I'd started typing 'First', 'first item' would still be the suggested and completion, but the edit text will be 'First item' where ' item' will be highlighed. If I press Enter to accept the autocompletion, the text will change to 'first item'. While I'd like the text to be 'First item', I can live with this.
If I type in 'First Item' then change the focus to anything else (like clicking on another window) the text will become 'first item'. This is NOT what I want. I'd like the text to stay at 'First Item' unless explicitly changed by me.
This is the way things were with Qt < 4.5.
If the completer were set to case-sensitive the combo box doesn't change the text as in 3, but no completions are suggested either. Completions for 2 are suggested, but this operation is rarely required in my app whereas 3 is done quite a bit.
Can you filter the focus out event to prevent the completer from activating?
Nope. If I don't run it at all, I get artifacts like the caret still being visible on the combo box even if the focus is on another combo box (I have more than one in my app, but this behaviour is manifested if I change the focus to any widget).
Edit: Just realized what you meant. Checking it now.
No luck. I get artifacts like the combo box seeming to have focus when it doesn't, like the caret still being visible and the selection not being discarded after pressing tab.
Here's the code I used:
@def eventFilter(self, obj, event):
if isinstance(obj, QComboBox) and event.type() == QEvent.FocusOut:
return QGroupBox.eventFilter(self, obj, event) #The combo box has a QGroupBox parent
In C++ it'd be (I think):
@bool ComboGroup::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::FocusOut)
return QGroupBox::eventFilter(obj, event);
Okay, I would post a "bug report":http://bugreports.qt.nokia.com on this one then; I don't know whether that was an intentional change or not.