在PyQt5中对QTableWidget的行进行过滤

编程语言 2026-07-12

最初,我有一个简单的筛选函数,它从一个 QLineEdit 取得文本,并将其与一个 QTableWidget 中所有单元格的文本进行匹配,如下所示:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # ...
        hlayout = QHBoxLayout()
        fltrlbl = QLabel("Filter on: ")
        hlayout.addWidget(fltrlbl)
        self.fltrle = QLineEdit()
        self.fltrle.textChanged.connect(self.filterer)
        self.fltrle.setClearButtonEnabled(True)
        hlayout.addWidget(self.fltrle)
        # ...

    def filterer(self, filtertext):
        for i in range(self.table.rowCount()):
            for j in range(self.table.columnCount()):
                item = self.table.item(i, j).text()
                match = filtertext.lower() not in item.lower()
                self.table.setRowHidden(i, match)
                if not match:
                    break

这工作得很完美,但用户要求能够指定筛选应用到哪一列。因此我新增了一个 QComboBox,其中列出了列名,并按如下方式更新了代码:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # ...
        hlayout = QHBoxLayout()
        fltrlbl = QLabel("Filter on: ")
        hlayout.addWidget(fltrlbl)
        self.fltrcb = QComboBox()
        self.fltrcb.addItems(["Name", "Email", "Address",
                              "City", "State", "Zip"])
        hlayout.addWidget(self.fltrcb)
        self.fltrle = QLineEdit()
        self.fltrle.textChanged.connect(self.filterer)
        self.fltrle.setClearButtonEnabled(True)
        hlayout.addWidget(self.fltrle)
        # ...

    def filterer(self, filtertext):
        icol = self.fltrcb.currentIndex()
        for irow in range(self.table.rowCount()):
            item = self.table.item(irow, icol).text()
            match = filtertext.lower() not in item.lower()
            self.table.setRowHidden(irow, match)
            if not match:
                break

现在,filterer 函数在迭代1 次后就会停止。举例来说,假设有100行。如果我搜索 "John Smith",且 "John Smith" 位于第12行,那么将显示第12行到第100行,而不仅仅是第12行。然后,当我清除 QLineEdit 时,只回到第1 行(因此会显示第1 行以及第12行到第100行)。

先行致谢。

解决方案

我无法测试,但我认为你必须移除 if not match: break,因为它可能在首次迭代后就停止筛选。

在旧版本中你有两个嵌套的 for-循环,因此 break 是用于 column 的现有循环,但不是用于 row 的循环。

在新版本中你只有针对 rows 的循环,因此 break 可能是多余的——它在遇到第一条不匹配的行后就存在,而且不会去检查其他行。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章