Using a QCompleter in a QTableView with Qt and Python

别等时光非礼了梦想. 提交于 2019-12-14 02:43:57

问题


I'm reading up on how to make my QAbstractTableModel editable, and it looks pretty straightforward.

But how do I set up an editable cell to use a QCompleter? I take it somehow I have to tell the QTableView to use a QLineEdit widget? How can I do this?


edit: hmm, I guess it has something with QTableView.setItemDelegateForColumn() but I don't know anything about delegates or how to use them.


edit: I tried RobbieE's solution, got something that sort of works but it gets the geometry of the popup combo box wrong and crashes Python when I press 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)

My _completerSetupFunction looks something like this:

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)

回答1:


Create a subclass of QStyledItemDelegate

All you need to do is reimplement the setEditorData function, check that the editor widget is a QLineEdit and then set the completer.

Please, excuse that I don't know Python but this is how it would be done in c++. Hopefully, translating to Python will be easy.

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));
             }
         }
}; 



回答2:


Per RobbieE's suggestion, I subclassed QStyledItemDelegate. But the correct place to apply the completer is when the editor is created, not 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

and then I use a completerSetupFunction that basically looks like this:

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

Here's a complete example as a github gist.



来源:https://stackoverflow.com/questions/24947003/using-a-qcompleter-in-a-qtableview-with-qt-and-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!