python - 如何通过文本在PyQt中为QTableView创建过滤器

标签 python python-3.x pyqt5

我想创建一个过滤器,它可以在单击一次时进行排序,而在双击时可以根据它进行写入和过滤。 我正在使用 pyqt5 ,如果你能帮我解决这个问题。

enter image description here

最佳答案

您必须实现一个 QHeaderView,它具有根据要求显示的 QLineEdit,方法是通过发送修改后的列和输入的文本来发出信号。

import random
from PyQt5 import QtCore, QtGui, QtWidgets

class EditableHeaderView(QtWidgets.QHeaderView):
    textChanged = QtCore.pyqtSignal(int, str)

    def __init__(self, parent=None):
        super(EditableHeaderView, self).__init__(QtCore.Qt.Horizontal, parent)
        self._is_editable = dict()
        self.setSectionsClickable(True)
        self._lineedit = QtWidgets.QLineEdit(self, visible=False)
        self._lineedit.editingFinished.connect(self._lineedit.hide)
        self._lineedit.textChanged.connect(self.on_text_changed)
        self.sectionDoubleClicked.connect(self.on_sectionDoubleClicked)
        self._current_index = -1
        self._filters_text = dict()

    def setEditable(self, index, is_editable):
        if 0 <= index < self.count():
            self._is_editable[index] = is_editable

    @QtCore.pyqtSlot()
    def hide_lineedit(self):
        self._filters_text[self._current_index] = self._lineedit.text()
        self._lineedit.hide()
        self._current_index = -1
        self._lineedit.clear()

    @QtCore.pyqtSlot(int)
    def on_sectionDoubleClicked(self, index):
        self.hide_lineedit()
        is_editable = False
        if index in self._is_editable:
            is_editable = self._is_editable[index]
        if is_editable:
            geom = QtCore.QRect(self.sectionViewportPosition(index), 0, self.sectionSize(index), self.height())
            self._lineedit.setGeometry(geom)
            if index in self._filters_text:
                self._lineedit.setText(self._filters_text[index])
            self._lineedit.show()
            self._lineedit.setFocus()
            self._current_index = index
            self.textChanged.emit(self._current_index, self._lineedit.text())

    @QtCore.pyqtSlot(str)
    def on_text_changed(self, text):
        if self._current_index != -1:
            # self.model().setHeaderData(self._current_index, self.orientation(), text)
            self.textChanged.emit(self._current_index, text)

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        tableview = QtWidgets.QTableView()
        headerview = EditableHeaderView(tableview)
        tableview.setHorizontalHeader(headerview)
        model = QtGui.QStandardItemModel(20, 10, self)
        self._proxy = QtCore.QSortFilterProxyModel(self)
        self._proxy.setSourceModel(model)
        tableview.setModel(self._proxy)
        tableview.setSortingEnabled(True)

        for i in range(model.rowCount()):
            for j in range(model.columnCount()):
                text = ''.join(random.sample(list("abcdefghijklmnopqrstuvwxyz"), 4))
                it = QtGui.QStandardItem(text)
                model.setItem(i, j, it)

        headerview.setEditable(2, True)
        headerview.setEditable(4, True)
        headerview.setEditable(7, True)
        headerview.textChanged.connect(self.on_text_changed)
        self.setCentralWidget(tableview)
        self.resize(640, 480)

    @QtCore.pyqtSlot(int, str)
    def on_text_changed(self, col, text):
        self._proxy.setFilterKeyColumn(col)
        self._proxy.setFilterWildcard("*{}*".format(text) if text else "")

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

关于python - 如何通过文本在PyQt中为QTableView创建过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54743838/

相关文章:

python - 优化 3d 点哈希函数

python - msgprop.EnumProperty 和 messages.Enum 与 Python 3 和 Cloud NDB 的最佳实践是什么?

python - 获取具有随机类名的元素

python的json : AttributeError: 'str' object has no attribute 'keys'

python - QSQLTableModel 中的格式化值出现问题

python - Python中用 'print'打开的文件不需要关闭?

python - Elasticsearch - 检查索引是否存在时的身份验证错误

python - 如何提取特定单词后的行?

python - 来自托盘图标的弹出窗口在窗口关闭时不会关闭程序

python - QFileDialog - PyQt4/PyQt5/PySide 之间的区别