-
-
Save alimp5/90879018fa992473b2d3aaedc2b2200d to your computer and use it in GitHub Desktop.
AutoCompleting QLineEdit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PyQt4.QtCore import QEvent, Qt | |
from PyQt4.QtGui import QLineEdit | |
class MyLineEdit(QLineEdit): | |
def __init__(self, *args, **kwargs): | |
QLineEdit.__init__(self, *args, **kwargs) | |
self.completions = [] # All available completions | |
self.partials = [] # Parsed completions according to partially typed word | |
self.cursorpos = 0 | |
self.wordstart = -1 # Start of word where cursor positioned | |
self.wordend = -1 # End of word where cursor is positioned | |
self.lastindex = -1 # Last used completion of available completions | |
def addCompletion(self, word): | |
if not word in self.completions: | |
self.completions.append(word) | |
def delCompletion(self, word): | |
if word in self.completions: | |
self.completions.remove(word) | |
def setCompletions(self, items): | |
self.completions = items | |
def getWords(self): | |
text = str(self.text()) | |
if self.lastindex == -1: | |
self.cursorpos = self.cursorPosition() | |
self.wordstart = text.rfind(" ", 0, self.cursorpos) + 1 | |
pattern = text[self.wordstart:self.cursorpos] | |
self.partials = [item for item in self.completions if item.lower().startswith(pattern.lower())] | |
return self.partials | |
def applyCompletion(self, text): | |
old = str(self.text()) | |
self.wordend = old.find(" ", self.cursorpos) | |
if self.wordend == -1: | |
self.wordend = len(old) | |
new = old[:self.wordstart] + text + old[self.wordend:] | |
self.setText(new) | |
def event(self, event): | |
if event.type() == QEvent.KeyPress: | |
if event.key() == Qt.Key_Tab: | |
if not len(self.completions): | |
return True | |
if self.lastindex >= len(self.getWords()) or self.lastindex == -1: | |
self.lastindex = 0 | |
# only one item in the completion list | |
if len(self.partials) == 1: | |
self.applyCompletion(self.partials[0]) | |
# more than one remaining matches | |
else: | |
match = self.partials[self.lastindex] | |
self.lastindex += 1 | |
self.applyCompletion(match) | |
return True | |
else: | |
self.lastindex = -1 | |
return QLineEdit.event(self, event) | |
def main(): | |
import sys | |
from PyQt4.QtGui import QLabel, QVBoxLayout, QApplication, QWidget | |
LIST_DATA = ['a', 'aardvark', 'aardvarks', 'aardwolf', | |
'abacus', 'babel', 'bach', 'cache', | |
'daggle', 'facet', 'kabob', 'kansas'] | |
app = QApplication(sys.argv) | |
# objects | |
w = QWidget() | |
label = QLabel(w) | |
text = "Possible completions: \n" + \ | |
"%s\n" + \ | |
"Press Tab to autocomplete, multiple times " + \ | |
"to cycle thru available completions" | |
label.setText(text % ", ".join(LIST_DATA)) | |
lineedit = MyLineEdit(w) | |
lineedit.setCompletions(LIST_DATA) | |
# layout | |
layout = QVBoxLayout() | |
layout.addWidget(label) | |
layout.addWidget(lineedit) | |
w.setLayout(layout) | |
# go | |
w.show() | |
sys.exit(app.exec_()) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment