You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中QLineEdit的QCompleter无有效高度且不显示匹配项

问题原因与解决方案

核心问题:QCompleter对TableModel的显示逻辑依赖Qt.DisplayRole与列配置

QCompleter默认会从TableModel的**第一列(index.column() == 0)**获取Qt.DisplayRole对应的数据来渲染弹窗列表。如果子类化模型存在以下情况,就会出现弹窗空但数据实际存在的现象:

  • 1. data()方法未正确返回Qt.DisplayRole对应的数据
    字典列表转模型时,若只在自定义角色或其他角色中返回字符串,漏掉Qt.DisplayRole的返回,QCompleter拿不到显示用的文本,弹窗就会为空,但实际数据可通过其他角色访问(所以上下键能切换)。比如错误写法:

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.UserRole:
            return self.data_list[index.row()]["name"]
        # 未处理DisplayRole,返回None
        return None
    
  • 2. columnCount()返回值错误
    若columnCount()返回大于1的数值,但第一列没有填充数据,QCompleter只关注第一列,也会导致弹窗为空。如果补全只需要字典中的单个字段,应让columnCount()返回1,或显式指定QCompleter的completionColumn。

  • 3. 未指定QCompleter的completionRole
    若用自定义角色存储补全文本,需要显式告诉QCompleter用哪个角色取数据:

    completer.setCompletionRole(Qt.UserRole)
    

    否则QCompleter默认用DisplayRole,拿不到数据就会显示空弹窗。

修复示例代码

from PyQt5.QtCore import QAbstractTableModel, Qt, QModelIndex
from PyQt5.QtWidgets import QApplication, QLineEdit, QCompleter

class DictTableModel(QAbstractTableModel):
    def __init__(self, data_list, parent=None):
        super().__init__(parent)
        self.data_list = data_list  # 格式:[{"name": "xxx"}, ...]

    def rowCount(self, parent=QModelIndex()):
        return len(self.data_list)

    def columnCount(self, parent=QModelIndex()):
        return 1  # 仅保留一列用于补全

    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return None
        row = index.row()
        if role == Qt.DisplayRole or role == Qt.EditRole:
            # 返回用于显示的补全文本
            return self.data_list[row]["name"]
        return None

if __name__ == "__main__":
    app = QApplication([])
    data = [{"name": "Apple"}, {"name": "Banana"}, {"name": "Cherry"}]
    model = DictTableModel(data)
    line_edit = QLineEdit()
    completer = QCompleter(model, line_edit)
    # 若使用自定义角色存储数据,需添加此行:
    # completer.setCompletionRole(Qt.UserRole)
    line_edit.setCompleter(completer)
    line_edit.show()
    app.exec_()

额外注意点

  • 确保data()方法在Qt.DisplayRole下返回的是字符串类型,若返回整数、None等非字符串类型,QCompleter无法渲染显示。
  • 按下上下键能切换,说明模型的rowCount()配置正确,数据可被访问,核心问题还是显示用的角色或列的配置错误。

内容的提问来源于stack exchange,提问作者Ian Bailey-Mortimer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:50:16