Qt autocomplete QCombobox in QTableview issue
Asked Answered
A

3

9

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?

Autrey answered 18/8, 2018 at 13:25 Comment(0)
D
3

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.

Delapaz answered 31/8, 2018 at 14:9 Comment(1)
So the event seems to be taken by the combobox itself and not by the tableview. I'm now looking into how I can force the completer to complete the string if possible.Autrey
C
4

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.

Chock answered 28/8, 2018 at 17:46 Comment(0)
D
3

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.

Delapaz answered 31/8, 2018 at 14:9 Comment(1)
So the event seems to be taken by the combobox itself and not by the tableview. I'm now looking into how I can force the completer to complete the string if possible.Autrey
K
0

Try using the keyPressEvent when pressing the Tab key

if event.key() == QtCore.Qt.Key_Tab: 
    # autocomplete here
    pass

Try reading this example here . Might be usefull. Cheers

Kaoliang answered 28/8, 2018 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.