长话短说,我已经在列表中有需要显示的内容(对于qlineedit(。但是我需要在自动完成框中显示一些额外的信息,这弄乱了QCompleter,因为我使用它的setModel方法来更新它显示的内容(所以我放入setModel方法的附加信息与QCompleter的完成规则混淆了QCompleter(所以我需要在QLineEdit下面有一个类似QCompleter的显示。无论如何,我能做到这一点吗?
#The method TopProducts(text) -> returns a list of strings with the format
#"manufacturer - model number - description" (picks three products based on the given text)
#in __init__ somewhere:
self.nameEdit = QLineEdit()
self.completer = QCompleter()
self.nameEdit.setCompleter(self.completer)
self.nameEdit.textEdited.connect(self.suggest)
self.model = QStringListModel()
def suggest(self,text):
stringList = TopProducts(text)
self.model.setStringList(stringList)
self.completer.setModel(self.model)
合适的解决方案是创建一个自定义模型,该模型具有每个制造商的角色、型号和说明,因此您可以使用 QCompleter
的 completionRole
属性并仅按型号对其进行筛选。
默认情况下,将显示选定的角色文本,因此我们不会有这种不当行为,我们将覆盖pathFromIndex()
以返回Qt::DisplayRole
角色:
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_())