class Suggest(QObject): def __init__(self, parent): QObject.__init__(self, parent) self.editor = parent editor = self.editor self.popup = QTreeWidget() popup = self.popup popup.setWindowFlags(Qt.Popup) popup.setFocusPolicy(Qt.NoFocus) popup.setFocusProxy(parent) popup.setMouseTracking(True) popup.setColumnCount(1) popup.setUniformRowHeights(True) popup.setRootIsDecorated(False) popup.setEditTriggers(QTreeWidget.NoEditTriggers) popup.setSelectionBehavior(QTreeWidget.SelectRows) popup.setFrameStyle(QFrame.Box | QFrame.Plain) popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) popup.header().hide() popup.installEventFilter(self) popup.itemClicked.connect(self.done) self.timer = QTimer(self) timer = self.timer timer.setSingleShot(True) # TODO: make interval optional timer.setInterval(500) timer.timeout.connect(self.suggest) editor.textEdited.connect(timer.start) self.engine = Engine(iciba.Engine()) self.engine.query_finished.connect(self.handle_query_finished) def eventFilter(self, o, e): if not o is self.popup: return False if e.type() == QEvent.MouseButtonPress: self.popup.hide() self.editor.setFocus() return True if e.type() == QEvent.KeyPress: consumed = False key = e.key() if key in (Qt.Key_Enter, Qt.Key_Return): self.done() consumed = True elif key in (Qt.Key_Escape, ): self.editor.setFocus() self.popup.hide() consumed = True elif key in ( Qt.Key_Up, Qt.Key_Down, Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown ): pass else: self.editor.setFocus() self.editor.event(e) self.popup.hide() return consumed return False def complete(self, choices): if not choices: return self.popup.setUpdatesEnabled(False) self.popup.clear() for i in range(len(choices)): item = QTreeWidgetItem(self.popup) item.setText(0, choices[i]) self.popup.setCurrentItem(self.popup.topLevelItem(0)) self.popup.resizeColumnToContents(0) self.popup.resizeColumnToContents(1) self.popup.adjustSize() self.popup.setUpdatesEnabled(True) h = self.popup.sizeHintForRow(0) * min(7, len(choices)) + 3 self.popup.resize(self.editor.width(), h) self.popup.move(self.editor.mapToGlobal(QPoint(0, self.editor.height()))) self.popup.setFocus() self.popup.show() @pyqtSlot() def done(self): self.timer.stop() self.popup.hide() self.editor.setFocus() item = self.popup.currentItem() if item: self.editor.setText(item.text(0)) QMetaObject.invokeMethod(self.editor, "returnPressed") @pyqtSlot() def suggest(self): key = self.editor.text() self.engine.query(key) @pyqtSlot() def stop(self): self.timer.stop() @pyqtSlot(object) def handle_query_finished(self, result): self.complete(result)