PDA

View Full Version : QCompleter causes table to lose focus



knack
28th August 2010, 17:41
So I've subclassed QItemDelegate to add a QCompleter to the QLineEdit widgets that are created for editing a table cell. However, as soon as I type the first letter of a word that's in the completer, the entire table loses focus and the next widget is selected. This _doesn't_ happen if the word isn't in the completer, or the cell is activated for editing.

This seems like buggy behavior to me. I'm wondering if anyone else has come across this or can confirm this, and if anyone might be able to suggest a possible work around. Setting edit triggers to AllEditTriggers mitigates this somewhat, but isn't foolproof. Doing that also seems to make it harder to hook into events to customize the table's focus behavior (which is something else I'm trying to do).

I'm using PyQt 4.7.3 on Debian Linux, but this appears to be the same issue that's described in this thread (http://www.qtcentre.org/threads/12677-Completer-on-QItemDelegate). Other than that, I haven't found any other resources discussing this.

Here's a code snippet that demonstrates the problem:



import sys

from PyQt4.QtCore import Qt
from PyQt4.QtGui import *


class TableDelegate(QItemDelegate):

def createEditor(self, parent, option, idx):
editor = super(TableDelegate, self).createEditor(parent, option, idx)

completer = QCompleter(['fee', 'fie', 'foe', 'fum'], editor.parent())
completer.setCaseSensitivity(Qt.CaseInsensitive)
editor.setCompleter(completer)

return editor


def main():
app = QApplication(sys.argv)

table = QTableWidget(2, 4)
table.setItemDelegate(TableDelegate())

buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

layout = QFormLayout()
layout.addRow(table)
layout.addRow(buttons)

view = QDialog()
view.setLayout(layout)
view.show()

buttons.accepted.connect(view.accept)
buttons.rejected.connect(view.reject)

app.exec_()


if __name__ == '__main__':
main()


Any help would be greatly appreciated!

norobro
28th August 2010, 21:38
EDIT: Sorry, missed in your post where you said that you tried this. BTW your sample code works fine here with "AllEditTriggers" set.


Try this:
table.setEditTriggers(QAbstractItemView.AllEditTri ggers)

knack
29th August 2010, 22:04
Yeah, the completer works if the cell is in edit mode, but I don't really find setting AllEditTriggers a satisfactory solution.

1. Hitting escape ends editing and keeps the cell selected. If you start typing again, and enter the first letter of a word in the completer, the table loses focus. So the problem is still present, but just being masked by the cell being put in edit mode.

2. In my actual code, I'm using this table in a larger dialog, and am registering an event handler to allow the user to tab "through" the table (i.e., if you're on the last cell and hit tab, the next widget is selected, rather than wrapping back to the first cell). Having AllEditTriggers set makes accomplishing this quite a bit more complicated.

If possible, I'd like to try to solve the actual problem, rather than just masking its occurrence. But it seems like this should just work. That's why I'm thinking this might be a bug in Qt.

wysota
29th August 2010, 22:22
You need to override some of events to keep the focus in the widget. I don't remember the exact routine right now but you may look at QtCreator's source code for its Quick Search widget, I think it was overriding the events too.