Использование QCompleter в QTableView с Qt и Python

Я читаю о том, как сделать мой QAbstractTableModel редактируемым, и это выглядит довольно просто.

Но как мне настроить редактируемую ячейку для использования QCompleter? Я так понимаю, я должен сказать QTableView использовать виджет QLineEdit? Как я могу это сделать?


edit: хм, я думаю, что-то есть с QTableView.setItemDelegateForColumn(), но я ничего не знаю о делегатах или как их использовать.


редактирование: я попробовал решение RobbieE, получил что-то в этом роде, но геометрия всплывающего комбинированного окна неверна и происходит сбой Python при нажатии Enter.

class CompleterDelegate(QtGui.QStyledItemDelegate):
    def __init__(self, parent=None, completerSetupFunction=None):
        super(CompleterDelegate, self).__init__(parent)
        self._completerSetupFunction = completerSetupFunction
    def createEditor(self, parent, option, index):
        return QtGui.QLineEdit(parent)
    def setEditorData(self, editor, index):
        super(CompleterDelegate, self).setEditorData(editor, index)
        self._completerSetupFunction(editor, index)

Моя _completerSetupFunction выглядит примерно так:

def setupFunc(editor, index):
    completer = MyCompleter(editor)
    completer.setCompletionColumn(0)
    completer.setCompletionRole(QtCore.Qt.DisplayRole)
    completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)    
    editor.setCompleter(completer)
    completer.setModel(myAbstractItemModel)

2 ответа

Решение

По предложению RobbieE я вложил в класс QStyledItemDelegate. Но правильное место для применения завершителя - это когда редактор создан, а не setEditorData.

class CompleterDelegate(QtGui.QStyledItemDelegate):
    def __init__(self, parent=None, completerSetupFunction=None):
        super(CompleterDelegate, self).__init__(parent)
        self._completerSetupFunction = completerSetupFunction
    def createEditor(self, parent, option, index):
        editor = QtGui.QLineEdit(parent)
        self._completerSetupFunction(editor, index)
        return editor

а затем я использую функцию completeterSet, которая в основном выглядит следующим образом:

def _completerSetupFunction(editor, index):
    print "completer setup: editor=%s, index=%s" % (editor, index)
    completer = QtGui.QCompleter(base_items, editor)
    completer.setCompletionColumn(0)
    completer.setCompletionRole(QtCore.Qt.EditRole)
    completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
    try:    
        editor.setCompleter(completer)            
    except:
        pass

Вот полный пример как GitHub Gist.

Создать подкласс QStyledItemDelegate

Все, что вам нужно сделать, это переопределить setEditorData убедитесь, что виджет редактора QLineEdit и затем установите завершитель.

Пожалуйста, извините, что я не знаю Python, но именно так это будет сделано в C++. Надеюсь, перевод на Python будет легким.

class MyDelegate : public QStyledItemDelegate{
     public:
         void setEditorData(QWidget *editor, QModelIndex const &index){

             // call the superclass' function so that the editor widget gets the correct data
             QStyledItemDelegate::setEditorData(editor, index);

             // Check that the editor passed in is a QLineEdit. 
             QLineEdit *lineEdit = qobject_cast<QLineEdit>(editor);

             if (lineEdit != 0){

                 // add whatever completer is needed, making sure that the editor is the parent QObject so it gets deleted along with the editor
                 lineEdit.setComplete(new MyCompleter(editor));
             }
         }
}; 
Другие вопросы по тегам