I have a QCompleter for a QLineEdit and it's working fine.
All I want is for this completer to be only read-only. So the user can only see the matches but cannot select any one of them. No highlighting, no selected item. Only a visible list of matches should be shown.
I tried for so long, but I'm still stuck and could not complete the task.
This is the code:
from PyQt5.QtWidgets import QApplication, QWidget, QCompleter, QLineEdit, QVBoxLayout
from PyQt5.QtCore import Qt, QStringListModel
import sys
class MainWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.testthislineEdit = QLineEdit()
temp_list = ['alpha', 'beta', 'boota', 'beita']
model = QStringListModel()
model.setStringList(temp_list)
completer = QCompleter()
completer.setFilterMode(Qt.MatchContains)
completer.setCaseSensitivity(Qt.CaseSensitivity(0))
completer.setModel(model)
layout = QVBoxLayout()
layout.addWidget(self.testthislineEdit)
self.setLayout(layout)
self.testthislineEdit.setCompleter(completer)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
try:
sys.exit(app.exec_())
except SystemExit:
print('Closing Window...')
One way to do this would be to use a custom item-view and selection-model with reimplemented methods that disable all the default selection, mouse and keyboard handling. It will also be necessary to ensure the custom selection-model is linked to the completer's internal proxy model.
Here is a working demo based on your example:
from PyQt5.QtWidgets import QApplication, QWidget, QCompleter, QLineEdit, QVBoxLayout, QListView
from PyQt5.QtCore import Qt, QStringListModel, QItemSelectionModel, QAbstractProxyModel
import sys
class SelectionModel(QItemSelectionModel):
def select(self, *args, **kwargs):
# disable selection
pass
def setCurrentIndex(self, *args, **kwargs):
# disable current index
pass
class ListView(QListView):
def setSelectionModel(self, model):
# link custom selection model to completer proxy model
super().setSelectionModel(SelectionModel(model.model(), self))
def mousePressEvent(self, event):
# ignore mouse events
self.close()
class MainWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.testthislineEdit = QLineEdit()
temp_list = ['alpha', 'beta', 'boota', 'beita']
model = QStringListModel()
model.setStringList(temp_list)
completer = QCompleter()
completer.setFilterMode(Qt.MatchContains)
completer.setCaseSensitivity(Qt.CaseSensitivity(0))
# set custom popup
completer.setPopup(ListView(self))
completer.setModel(model)
layout = QVBoxLayout()
layout.addWidget(self.testthislineEdit)
self.setLayout(layout)
self.testthislineEdit.setCompleter(completer)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
try:
sys.exit(app.exec_())
except SystemExit:
print('Closing Window...')