在PyQt5中对QTableWidget的行进行过滤
最初,我有一个简单的筛选函数,它从一个 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。