繁体   English   中英

如何根据在 QLineEdit 中搜索文本的列过滤行并在 QTableView 中更新它

[英]How filter rows on the basis of columns having searched text in QLineEdit and update it in QTableView

我想根据 column0、column1、column2 和 column3 中同时存在的值过滤行并将其显示在 QTableView 中。 但是由于错误,我无法从任何列中过滤文本,即

 File "c:/Users/Shivani/Dropbox/My PC (10873-laptop)/Desktop/pyQt5 project/filter_model.py", line 25, in filterAcceptsRow    
    if not text.contains(regex):
AttributeError: 'str' object has no attribute 'contains'

从随机导入 randint 导入 sys,选择

from PyQt5.QtCore import Qt, QSortFilterProxyModel, QRegExp
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (
    QApplication,
    QFormLayout,
    QLineEdit,
    QTableView,
    QVBoxLayout,
    QWidget,
)

class SortFilterProxyModel(QSortFilterProxyModel):
    def __init__(self, *args, **kwargs):
        QSortFilterProxyModel.__init__(self, *args, **kwargs)
        self.filters = {}

    def setFilterByColumn(self, regex, column):
        self.filters[column] = regex
        self.invalidateFilter()

    def filterAcceptsRow(self, source_row, source_parent):
        for key, regex in self.filters.items():
            ix = self.sourceModel().index(source_row, key, source_parent)
            if ix.isValid():
                text = self.sourceModel().data(ix)
               
                if text != regex:
                    return False
        return True


def random_word():
    letters = "abcdedfg"
    word = "".join([choice(letters) for _ in range(randint(4, 7))])
    return word


class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.setLayout(QVBoxLayout())

        tv1 = QTableView(self)
        tv2 = QTableView(self)
        model = QStandardItemModel(8, 4, self)
        proxy = SortFilterProxyModel(self)
        proxy.setSourceModel(model)
        tv1.setModel(model)
        tv2.setModel(proxy)
        self.layout().addWidget(tv1)
        self.layout().addWidget(tv2)

        for i in range(model.rowCount()):
            for j in range(model.columnCount()):
                item = QStandardItem()
                item.setData(random_word(), Qt.DisplayRole)
                model.setItem(i, j, item)

        flayout = QFormLayout()
        self.layout().addLayout(flayout)
        for i in range(model.columnCount()):
            le = QLineEdit(self)
            flayout.addRow("column: {}".format(i), le)
            le.textChanged.connect(lambda text, col=i:
                                   proxy.setFilterByColumn(QRegExp(text, Qt.CaseSensitive, QRegExp.FixedString),
                                                           col))


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

OP 没有提供生成错误的代码行,但根据我的经验,它正在尝试翻译一些用 C++(或旧版本的 PyQt4)编写的代码,其中文本与具有 contains() 方法的 QString 相关联接受 QRegex 但在 PyQt5 中的文本是 python 字符串,因此它们没有该方法。 解决方案是使用 QRegex 的 indexIn 方法实现相同的逻辑:

def filterAcceptsRow(self, source_row, source_parent):
    for key, regex in self.filters.items():
        ix = self.sourceModel().index(source_row, key, source_parent)
        if ix.isValid():
            text = self.sourceModel().data(ix)
            if regex.indexIn(text) == -1:
                return False
    return True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM