A suitable solution is to create a custom model that has roles for each manufacturer, model number and description, so you can use the completionRole
property of QCompleter
and only filter it by model number.
By default the selected role text is displayed, so that we do not have that inappropriate behavior we will overwrite pathFromIndex()
to return the Qt::DisplayRole
role:
class ProductModel(QAbstractListModel):
ManufacturerRole, ModelNumberRole, DescriptionRole = range(Qt.UserRole, Qt.UserRole + 3)
def __init__(self, parent=None):
QAbstractListModel.__init__(self, parent)
self._products = []
def addProduct(self, product):
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
self._products.append(product)
self.endInsertRows()
def removeProduct(self, model_number, manufacturer):
selecteds = filter(lambda product: product['manufacturer'] == manufacturer and product["modelNumber"] == model_number,
self._products)
for selected in selecteds:
row = self._products.index(selected)
self.beginRemoveRows(QModelIndex(), row, row)
self._products.pop(row)
self.endRemoveRows()
def rowCount(self, parent=QModelIndex()):
return len(self._products)
def data(self, index, role=Qt.DisplayRole):
if 0 <= index.row() < self.rowCount():
product = self._products[index.row()]
if role == ProductModel.ManufacturerRole:
return product["manufacturer"]
elif role == ProductModel.ModelNumberRole:
return product["modelNumber"]
elif role == ProductModel.DescriptionRole:
return product["description"]
elif role == Qt.DisplayRole:
return "{} {} {}".format(*product.values())
class ProductCompler(QCompleter):
def pathFromIndex(self, index):
return index.data()
if __name__ == '__main__':
app = QApplication(sys.argv)
le = QLineEdit()
completer = ProductCompler(le)
le.setCompleter(completer)
model = ProductModel()
completer.setModel(model)
completer.setCompletionRole(ProductModel.ModelNumberRole)
model.addProduct({"manufacturer": "StarTech", "modelNumber": "STANDOFF122", "description": "description"})
model.addProduct({"manufacturer": "StarTrek", "modelNumber": "STANDOFF111", "description": "description"})
model.addProduct({"manufacturer": "StackOverFlow", "modelNumber": "STANDOFF100", "description": "description"})
model.addProduct({"manufacturer": "StarTech", "modelNumber": "ABCSTANDOFF122", "description": "description"})
model.addProduct({"manufacturer": "StarTrek", "modelNumber": "ABCSTANDOFF111", "description": "description"})
model.addProduct({"manufacturer": "StackOverFlow", "modelNumber": "DFSTANDOFF100", "description": "description"})
model.removeProduct("STANDOFF111", "StarTrek")
le.show()
sys.exit(app.exec_())