I've a QSqlQueryModel
which fetches IDs like 1
, 2,
, etc. In the UI we display this field as a 4-digit int: 0001
, 0002
, etc.
Here's my proxy subclass of QIdentityProxyModel
to add the zero prefix:
class ZeroPrefixProxy(QIdentityProxyModel):
def __init__(self, parent=None):
super().__init__(parent)
def data(self, index, role):
d = self.sourceModel().data(index, role)
return f'{d:04}' if role in (Qt.DisplayRole, Qt.EditRole) else d
# Uncommenting this works
# def rowCount(self, parent=QModelIndex()):
# return self.sourceModel().rowCount(parent)
Here's how I set it to a QLineEdit
s completer:
def setIdCompleterModel(self):
# model is a loaded QSqlQueryModel
proxy = ZeroPrefixProxy(self.ui.txtId)
proxy.setSourceModel(model)
self.ui.txtId.setCompleter(QCompleter(proxy, self.ui.txtId))
# Uncommenting this works
# proxy.data(proxy.index(0, 0), Qt.DisplayRole)
No suggestions are displayed irrespective of what I type (1
or 0001
). However, when I uncomment either snippets above things work great.
I do not want to do either as they seem pointless:
QIdentityProxyModel
already implementscolumCount
(it works correctly)- I've no reason to call
data
(I originally wrote it just to test)
What am I missing? Why is the simple subclass implementation not working?
Setup: ArchLinux, Qt 5.15.10, PySide2 5.15.2.1
MCVE
This code works on my setup only if I comment out ZeroPrefixProxy.data
:
import sys
from PySide2.QtCore import Qt, QIdentityProxyModel, QModelIndex
from PySide2.QtWidgets import QApplication, QMainWindow, QLineEdit, QCompleter
from PySide2.QtGui import QStandardItem, QStandardItemModel
class ZeroPrefixProxy(QIdentityProxyModel):
def __init__(self, parent=None):
super().__init__(parent)
# Commenting this method out makes things work
def data(self, index, role=Qt.DisplayRole):
return self.sourceModel().data(index, role)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
useStdModel = False
if useStdModel:
model = QStandardItemModel(5, 1, self)
for i in range(1, 6):
item = QStandardItem()
# setData as ctor only takes an str, we need an int
item.setData(i, Qt.EditRole)
model.setItem(i-1, 0, item)
else:
db = QSqlDatabase.addDatabase('QPSQL')
host = 'localhost'
dbname = 'test'
db.setHostName(host)
db.setDatabaseName(dbname)
db.setUserName('pysider')
if not db.open():
print('DB not open')
model = QSqlQueryModel()
model.setQuery('SELECT id FROM items')
proxy = ZeroPrefixProxy(self)
proxy.setSourceModel(model)
lineEdit = QLineEdit()
comp = QCompleter(proxy, lineEdit)
lineEdit.setCompleter(comp)
self.setCentralWidget(lineEdit)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()