【问题标题】:PyQt - QTableView search by hiding rowsPyQt - QTableView 通过隐藏行搜索
【发布时间】:2013-12-13 18:53:01
【问题描述】:

这是我的问题。我有一个 QTableView 显示一些数据(在模型中设置)和一个 QLineEdit 小部件,我想用它来搜索所有显示行中的文本。预期的行为应该是:我在 QLineEdit 中键入一些文本,并且 QTableView 更新本身隐藏所有不包含该数据的行。

问题是,我应该如何实现它?我找到了一个名为 hideRows() 的 QTableView 成员函数,这似乎是正确的选择,但我不知道应该如何遍历所有数据以及将该方法放在哪里。它应该包含在模型或对话框中? (这其实是我第一次使用模型,所以我只是掌握了它们的工作原理)

另外我需要实现一个导出功能(csv、html 或其他),但只需要当前显示的行(那些没有隐藏的行)。这可能吗?

感谢您的建议。

这是我到目前为止的代码:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
import Android_extractor
import ui_android_dialog



class recordsTableModel(QAbstractTableModel):

    def __init__(self, records, parent = None):
        QAbstractTableModel.__init__(self, parent)
        self.__records = records

    def rowCount(self, parent):
        return len(self.__records)

    def columnCount(self, parent):
        return len(self.__records[0])

    def flags(self, index):
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable

    def data(self, index, role):
        if role == Qt.EditRole:
            row = index.row()
            column = index.column()
            return self.__colors[row][column].name()

        if role == Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.__records[row][column]

            return value

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return self.__records[0]._fields[section]




class AndroidDialog(QDialog, ui_android_dialog.Ui_androidDialog):

    def __init__(self, parent=None):
        super(AndroidDialog, self).__init__(parent)
        self.setupUi(self)

        self.buttonMapper = QSignalMapper(self)

        self.buttonMapper.setMapping(self.contactsToolButton, 0)
        self.buttonMapper.setMapping(self.groupsToolButton, 1)
        self.buttonMapper.setMapping(self.chatsessionToolButton, 2)
        self.buttonMapper.setMapping(self.messageToolButton, 3)

        self.contactsToolButton.clicked.connect(self.buttonMapper.map)
        self.groupsToolButton.clicked.connect(self.buttonMapper.map)
        self.chatsessionToolButton.clicked.connect(self.buttonMapper.map)
        self.messageToolButton.clicked.connect(self.buttonMapper.map)

        self.buttonMapper.mapped.connect(self.dataStackedWidget.setCurrentIndex)


        self.newQuery = Android_extractor.AndroidQuery(sys.argv[1])
        self.contacts = self.newQuery.getContacts()
        self.groups = self.newQuery.getGroups()
        self.chats = self.newQuery.getChats()

        self.contactsTableView.setModel(recordsTableModel(self.contacts))
        self.contactsTableView.resizeColumnsToContents()
        self.contactsTableView.resizeRowsToContents()
        self.groupsTableView.setModel(recordsTableModel(self.groups))
        self.groupsTableView.resizeColumnsToContents()
        self.groupsTableView.resizeRowsToContents()
        self.chatsessionTableView.setModel(recordsTableModel(self.chats))
        self.chatsessionTableView.resizeColumnsToContents()
        self.chatsessionTableView.resizeRowsToContents()



app = QApplication(sys.argv)
form = AndroidDialog()
form.show()
app.exec_()

【问题讨论】:

标签: python qt filter pyqt


【解决方案1】:

你应该看看QSortFilterProxyModel

不要直接在 tableview 上设置自定义模型,而是在代理上设置为源模型,然后在视图上设置代理模型。

    self.proxyModelContact = QSortFilterProxyModel(self)
    self.proxyModelContact.setSourceModel(recordsTableModel(self.contacts))
    self.contactsTableView.setModel(self.proxyModelContact)

QSortFilterProxyModel提供两种方法:

  • setFilterRegExp(pattern) 允许您在视图上设置正则表达式过滤器(即仅显示与模式匹配的项目)

  • setFilterKeyColumn(index) 允许您定义将使用哪一列进行过滤(如果 index = -1,将查看所有列)。

您只需要将 linedit 的 textChanged 信号链接到将更新过滤器的插槽,例如:

def onTextChanged(self, text):
    self.proxyModelContact.setFilterRegExp(str(text))

【讨论】:

  • 非常感谢,居然不知道这个!它非常适合!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2015-11-07
  • 2013-07-03
  • 1970-01-01
相关资源
最近更新 更多