Solution - I have converted the C++ example code into python, and post it here to for all to see.
NB - The code assumes your dictionary is located at /usr/share/dict/words.
from PyQt4 import QtGui, QtCore STARTTEXT = ('This TextEdit provides autocompletions for words that have ' + 'more than 3 characters.\nYou can trigger autocompletion using %s\n\n'''% ( QtGui.QKeySequence("Ctrl+E").toString(QtGui.QKeySequence.NativeText))) class DictionaryCompleter(QtGui.QCompleter): def __init__(self, parent=None): words = [] try: f = open("/usr/share/dict/words","r") for word in f: words.append(word.strip()) f.close() except IOError: print "dictionary not in anticipated location" QtGui.QCompleter.__init__(self, words, parent) class CompletionTextEdit(QtGui.QTextEdit): def __init__(self, parent=None): super(CompletionTextEdit, self).__init__(parent) self.setMinimumWidth(400) self.setPlainText(STARTTEXT) self.completer = None self.moveCursor(QtGui.QTextCursor.End) def setCompleter(self, completer): if self.completer: self.disconnect(self.completer, 0, self, 0) if not completer: return completer.setWidget(self) completer.setCompletionMode(QtGui.QCompleter.PopupCompletion) completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.completer = completer self.connect(self.completer, QtCore.SIGNAL("activated(const QString&)"), self.insertCompletion) def insertCompletion(self, completion): tc = self.textCursor() extra = (completion.length() - self.completer.completionPrefix().length()) tc.movePosition(QtGui.QTextCursor.Left) tc.movePosition(QtGui.QTextCursor.EndOfWord) tc.insertText(completion.right(extra)) self.setTextCursor(tc) def textUnderCursor(self): tc = self.textCursor() tc.select(QtGui.QTextCursor.WordUnderCursor) return tc.selectedText() def focusInEvent(self, event): if self.completer: self.completer.setWidget(self); QtGui.QTextEdit.focusInEvent(self, event) def keyPressEvent(self, event): if self.completer and self.completer.popup().isVisible(): if event.key() in ( QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return, QtCore.Qt.Key_Escape, QtCore.Qt.Key_Tab, QtCore.Qt.Key_Backtab): event.ignore() return ## has ctrl-E been pressed?? isShortcut = (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_E) if (not self.completer or not isShortcut): QtGui.QTextEdit.keyPressEvent(self, event) ## ctrl or shift key on it's own?? ctrlOrShift = event.modifiers() in (QtCore.Qt.ControlModifier , QtCore.Qt.ShiftModifier) if ctrlOrShift and event.text().isEmpty(): # ctrl or shift key on it's own return eow = QtCore.QString("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=") #end of word hasModifier = ((event.modifiers() != QtCore.Qt.NoModifier) and not ctrlOrShift) completionPrefix = self.textUnderCursor() if (not isShortcut and (hasModifier or event.text().isEmpty() or completionPrefix.length() < 3 or eow.contains(event.text().right(1)))): self.completer.popup().hide() return if (completionPrefix != self.completer.completionPrefix()): self.completer.setCompletionPrefix(completionPrefix) popup = self.completer.popup() popup.setCurrentIndex( self.completer.completionModel().index(0,0)) cr = self.cursorRect() cr.setWidth(self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width()) self.completer.complete(cr) ## popup it up! if __name__ == "__main__": app = QtGui.QApplication([]) completer = DictionaryCompleter() te = CompletionTextEdit() te.setCompleter(completer) te.show() app.exec_()
8 comments:
Thanks for sharing! Made a handful of minor tweaks for Python3, to use Python strings instead of QStrings, and I was away. Now if only I could find a simple way to match anywhere rather than just prefixes...
Thanks a lot!
I just working on a editor. It's very useful for me.
Yeah, thanks for sharing!
is there a QsciScintilla version of this??
(one that ACTUALLY updates themenu like this)
than you so mush for your code it go on help ma alot
Thanks, this is great! Would it be ok to use this in a BSD-licensed project?
Thank you very much ! Good job !
Post a Comment