写点什么

pyside6 qml TableView 列表 用 QSortFilterProxyModel 模糊查询

作者:Mr_No爱学习
  • 2022-10-18
    浙江
  • 本文字数:1577 字

    阅读完需:约 1 分钟

使用 QSortFilterProxyModel,配合文本输入框的 onTextChanged 信号,实现输入自动匹配模糊查询

如果是后端查询接口实现,每次 text change 都触发数据库 like 语句查询,性能可能有问题

实现代理类

class ControlProxyModel(QSortFilterProxyModel):    def __init__(self):        super().__init__()        # 设置大小写不敏感        self.setFilterCaseSensitivity(Qt.CaseInsensitive)        # 设置原始数据模型 control_inst_model类型是QAbstractTableModel        self.setSourceModel(control_inst_model)        # 设置默认查询字段为第一列        self.setFilterKeyColumn(0)
@Slot(int) def set_filter_role(self, index): if 0 <= index < 4: self.setFilterKeyColumn(index)
复制代码

通过设置 filterRole 来切换查询的列,获取 filterKeyColumn,发现没有生效

因此直接通过指定查询列 setFilterKeyColumn 来切换

实例化代理类

control_proxy_model = ControlProxyModel()
复制代码

注册代理类

engine = QQmlApplicationEngine()engine.rootContext().setContextProperty("controlProxyModel", control_proxy_model)
复制代码

qml 里 TableView 的 model 设定为 controlProxyModel,或者在 TextField 的 onTextChanged,ComboBox 的 onCurrentIndexChanged 指定 TableView.model = controlProxyModel,都可以

// qml// 自定义的ComboBoxCusComboBox {    id: instSearchCombo
model: ListModel { ListElement { text: "条码" } ListElement { text: "批号" } ListElement { text: "名称" } ListElement { text: "类型" } }
onCurrentIndexChanged: { controlProxyModel.set_filter_role(instSearchCombo.currentIndex); }}
复制代码

设置查询文本


TextField {    id: reagentSearchText    selectByMouse: true    placeholderText: qsTr("输入查询文本:")
onTextChanged: { reagentProxyModel.setFilterFixedString(reagentSearchText.text); }}
复制代码


这样已经实现按不同的列模糊查询了

还有一个问题,按输入过滤后的行号 row,和原始的 control_inst_model 里的行号是不对应的,需要 mapToSource,把代理类行号转换为原始数据的行号

// qmllet idx = controlProxyModel.index(row, column);let real_row = controlProxyModel.mapToSource(idx);// real_row 是QModelIndex类control_table_view.selectedRow = real_row.row;
复制代码

数据展示中,选中的行号是原始数据行号时,用 mapFromSource 转换成代理类的行号

// qmlcontrolProxyModel.mapFromSource(controlInstModel.index(control_table_view.selectedRow, 0)).row
复制代码

默认只要文本匹配,就会返回该行,如果需要自定义过滤行为,可以重新实现 filterAcceptsRow

The default implementation returns true if the value held by the relevant item matches the filter string, wildcard string or regular expression

例如实现多列的联合查询

def setFilterText(self, t0, t1):    self.text_0 = t0    self.text_1 = t1
def filterAcceptsRow(self, sourceRow, sourceParent): index0 = self.sourceModel().index(sourceRow, 0, sourceParent) index1 = self.sourceModel().index(sourceRow, 1, sourceParent) return str(self.sourceModel().data(index0)).__contains__(self.text_0 ) & str(self.sourceModel().data(index1)).__contains__(self.text_1)
复制代码



官方文档:https://doc.qt.io/qt-6/qsortfilterproxymodel.html#filterCaseSensitivity-prop

官方示例:https://doc.qt.io/qt-6/qtwidgets-itemviews-customsortfiltermodel-example.html

c++版本:https://blog.51cto.com/u_15310543/3163910

c++多列联合过滤:https://blog.csdn.net/qq78442761/article/details/84875123

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2019-09-13 加入

还未添加个人简介

评论

发布
暂无评论
pyside6 qml TableView列表 用QSortFilterProxyModel模糊查询_Mr_No爱学习_InfoQ写作社区