Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt autocomplete QCombobox in QTableview issue

Tags:

c++

qt

qtableview

I have a QTableView which has a column with a QComboBox QItemDelegate. There is a list of completions for the combobox. When you start typing and press enter then the completion is done properly (note the capital letter)
before enter (press enter) -> enter image description here

But when I press tab it does not complete to include the capital letter.
before enter(press tab) -> enter image description here

But when I try this on a free ComboBox it does autocomplete correctly
enter image description here(press tab) -> enter image description here

I'm not capturing the Tab input event anywhere so I'm not sure what is causing the issue. What could it be?

like image 488
Eejin Avatar asked Aug 18 '18 13:08

Eejin


2 Answers

Looks very much like QTableView handling the Tab key as it should -- to trigger navigation between cells, the completer is not receiving it. Of course, commitData happens, delegate works fine, but not the completer, which is not providing the editor with the proper value in the case.

Quick & easy solution could be setTabKeyNavigation(false) for the tableView. Filtering tab key event could work as well. And finally, you could implement focusOutEvent, that would mean checking currentCompletion() in it and could be tricky a bit.

At least, that's what it looks like at first glance.

like image 72
MasterAler Avatar answered Nov 02 '22 20:11

MasterAler


Here is how I would proceed, step by step.

Step 1: discover which widget takes the tab event.

This is a debugging technique that I find quite useful when I don't know where an event went. Set an eventfilter on the whole application, with qApp->installEventFilter(this); Any widget can handle this, it doesn't matter. This same widget then re-implement eventFilter(QObject* watched, QEvent *event) as:

if(event->type = QEvent::KeyPress) {
 QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
 if(keyEvent->key() == Qt::Key_Tab) {
      qDebug() << "tab is intercepted by" << watched ;
 }
}
return false ;

That should tell you which widget intercept your signal.

Step 2: stop the cullprit. Now that we identified the cullprit (maybe the QTableView, as MasterAler suggests) , maybe you can realize you don't really want him to use this event, and maybe there is an easy way to de-activate this behavior. If so, problem solved.

Step 3: After step 2 failed, or if you don't like it

Typically because you might want the event to be proceed normally, on top of the additional functionality you define here. Use an eventfilter (again). But this time to set in on the whole application, just on the widget that was receiving the event.

So this time, instead of qApp, we use cullprit->installEventFilter(this) ; In the constructor of the widget that you want to use the event in. And then same as for step 1, you can detect the event and react accordingly. Note that by returning false, the method eventFilter allows the event to follow his merry way and be handle ALSO by others.

Note: It'd probably be a bad idea to keep the eventfilter on the whole application, it'd waste the purpose of the whole event system organisation. I think it's better to keep step 1 to debugging phase only.

like image 42
Andéol Evain Avatar answered Nov 02 '22 18:11

Andéol Evain