У меня есть такие данные автозаполнения: ['taste.sour', 'taste.salty', 'taste.sweet', 'taste.bitter']
Я хочу написать специальное автозаполнение, которое позволяет такие совпадения (как в PyCharm):
- ts (совпадение со словами начинается)-> должен показать
'taste.sour', 'taste.salty', 'taste.sweet'
- tb -> должен показать
'taste.bitter'
- tsa (совпадение со словами начинается, затем следующая буква) -> должен показать
'taste.salty'
- вкус.s (базовое соответствие) -> должен показать
'taste.sour', 'taste.salty', 'taste.sweet'
- вкус.са -> должен показать
'taste.salty'
- та (соответствует первому слову) -> шоудл шоу
'taste.', 'taste.sour', 'taste.salty', 'taste.sweet', 'taste.bitter'
Я написал код песочницы, который охватывает 4, 5, 6, но как это сделать 1. ts, 2. tb, 3. tsa - можете ли вы помочь мне с этим?
Я прочитал: https://doc.qt.io/qt-5/qabstractitemmodel.html но я понятия не имею, должен ли я использовать для этого разные QAbstractItemModel
.
Я хочу также обновлять эту модель при добавлении каждого нового тега.
Это моя работакод с PyQt5:
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import QStringListModel, Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPlainTextEdit, QCompleter
class Application(QtWidgets.QApplication):
pass
class SmartCompleter(QCompleter):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
model = QStringListModel()
model.setStringList(['taste.sour', 'taste.salty', 'taste.sweet', 'taste.bitter'])
self.setModel(model)
class SmartTextEdit(QPlainTextEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.completer = SmartCompleter()
self.completer.setWidget(self)
self.completer.setCompletionMode(QCompleter.PopupCompletion)
self.completer.setCaseSensitivity(Qt.CaseSensitive)
self.completer.activated.connect(self.insert_completion)
def insert_completion(self, completion):
if completion == self.completer.completionPrefix():
return
text_cursor = self.textCursor()
last_chars = len(completion) - len(self.completer.completionPrefix())
text_cursor.insertText(completion[-last_chars:])
self.setTextCursor(text_cursor)
def text_before_cursor(self):
text_cursor = self.textCursor()
text_cursor.select(QtGui.QTextCursor.WordUnderCursor)
return text_cursor.selectedText()
def keyPressEvent(self, e: QtGui.QKeyEvent) -> None:
if self.completer.popup().isVisible():
key = e.key()
if key in (Qt.Key_Enter, Qt.Key_Return):
e.ignore()
return
super().keyPressEvent(e)
text_before_cursor = self.text_before_cursor()
print('text', self.text_before_cursor())
if text_before_cursor != self.completer.currentCompletion():
if text_before_cursor != self.completer.completionPrefix():
print(text_before_cursor, self.completer.currentCompletion())
self.completer.setCompletionPrefix(text_before_cursor)
self.completer.popup().setCurrentIndex(self.completer.completionModel().index(0, 0))
cursor_rectangle = self.cursorRect()
popup = self.completer.popup()
cursor_rectangle.setWidth(popup.sizeHintForColumn(0) + popup.verticalScrollBar().sizeHint().width())
self.completer.complete(cursor_rectangle)
else:
self.completer.popup().hide()
class SmartEditWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
main_vertical_layout = QVBoxLayout()
self.setLayout(main_vertical_layout)
main_horizontal_layout = QHBoxLayout()
main_vertical_layout.addLayout(main_horizontal_layout)
text_edit = SmartTextEdit()
main_horizontal_layout.addWidget(text_edit)
def main():
app = Application(sys.argv)
app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
default_font = QFont()
default_font.setPointSize(12)
app.setFont(default_font)
smart_edit_widget = SmartEditWidget()
smart_edit_widget.showNormal()
sys.exit(app.exec())
if __name__ == '__main__':
main()