QSortFilterProxyModel按列值

时间:2018-11-15 17:28:22

标签: python python-2.7 qtableview pyside2 qsortfilterproxymodel

表格模型数据示例

我有一个带有tabWidget的gui,每个里面都有一个tableview。每个选项卡都描述了一个带有子目录的文件夹(请参阅列类型),从中可以提取数据。我想要一个通过在每个表视图之间附加一个QSortFilterProxy Model来驱动所有视图的主模型,该模型为每个单独的TableView的“类型”(传递到子类RenderTypeProxyModel中)过滤主模型。奖励:理想情况下,也应该对它们进行排序,以使最新视图(请参见日期列)排在最前面。 这是我的当前版本,但由于我不知道原因,该表仍然空白:

import sys
import os
from datetime import datetime
from pprint import pprint
from PySide2 import QtCore, QtGui, QtWidgets

#To be replaced by env variable
pathToProject = "/run/media/centos7/Data/Projects/Programming/Pipeline/SampleProject"
allowedExportTypes = ["img-prv", "img-final", "img-cg", "img-src", "camera"]


class ExportTableModel(QtCore.QAbstractTableModel):
    def __init__(self, exportData, horizontalHeaders, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self.__exportData = exportData
        self.__horizontalHeaders = horizontalHeaders

    def rowCount(self, parent):
        return len(self.__exportData)
    def columnCount(self, parent):
        return len(self.__horizontalHeaders)

    def data(self, index, role): #Returns the data stored under the given role for the item referred to by the index.
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.__exportData[row][column]
            return value

    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                if section < len(self.__horizontalHeaders):
                    return self.__horizontalHeaders[section]
                else:
                    return "not implemented"

def tableSetup(tableView):
    tableView.setAlternatingRowColors(True)
    tableView.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
    tableView.setSortingEnabled(True)

class RenderTypeProxyModel (QtCore.QSortFilterProxyModel): #Custom Proxy Model
    def __init__(self, type, parent=None):
        super(RenderTypeProxyModel,self).__init__(parent)
        self.__type = type

    def filterAcceptsRow(self, row, parent): #returns true if the given row should be included in the model
        model = self.sourceModel()
        index = model.index(row, 3, parent)
        if model.data(index,QtCore.Qt.DisplayRole) == type:
            return True
        else:
            return False

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)

    horizontalHeaders = ["status", "comment", "task", "type", "version", "user", "date", "filepath"] #horizontal header data
    #exportData = #insert sample data list of lists here for testing

    tableView = QtWidgets.QTableView()
    tableView.show()

    model = ExportTableModel(exportData,horizontalHeaders)
    proxyModel = RenderTypeProxyModel("img-prv")
    proxyModel.setSourceModel(model)
    tableView.setModel(proxyModel)

    tableSetup(tableView)
    sys.exit(app.exec_())

以下是用于调试的示例数据:https://pastebin.com/AB1XvKju 只需将其输入__main__方法内的exportData变量中即可。

1 个答案:

答案 0 :(得分:1)

由于类型是python中的保留字而引起的错误:

if model.data(index,QtCore.Qt.DisplayRole) == type:

您必须使用self.__type

另一方面,如果您想按日期对数据进行排序,则不必启用setSortingEnabled(),只需使用sort()

from PySide2 import QtCore, QtGui, QtWidgets

#To be replaced by env variable
allowedExportTypes = ["img-prv", "img-final", "img-cg", "img-src", "camera"]


class ExportTableModel(QtCore.QAbstractTableModel):
    def __init__(self, exportData, horizontalHeaders, parent=None):
        super(ExportTableModel, self).__init__(parent)
        self.__exportData = exportData
        self.__horizontalHeaders = horizontalHeaders

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.__exportData)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return len(self.__horizontalHeaders)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.__exportData[row][column]
            return value

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole and orientation == QtCore.Qt.Horizontal:
            if section < self.columnCount():
                return self.__horizontalHeaders[section]
            return "not implemented"

def tableSetup(tableView):
    tableView.setAlternatingRowColors(True)
    tableView.setSelectionBehavior(QtWidgets.QTableView.SelectRows)

class RenderTypeProxyModel (QtCore.QSortFilterProxyModel): #Custom Proxy Model
    def __init__(self, _type, parent=None):
        super(RenderTypeProxyModel,self).__init__(parent)
        self.__type = _type

    def filterAcceptsRow(self, row, parent):
        _type = self.sourceModel().index(row, 3, parent).data()
        return _type == self.__type

    def lessThan(self, left, right):
        fmt = "yyyy-MM-dd hh:mm:ss"
        left_data = self.sourceModel().data(left)
        right_data = self.sourceModel().data(right)
        return QtCore.QDateTime.fromString(left_data, fmt) < QtCore.QDateTime.fromString(right_data, fmt)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)

    horizontalHeaders = ["status", "comment", "task", "type", "version", "user", "date", "filepath"] #horizontal header data
    exportData = # ...
    model = ExportTableModel(exportData, horizontalHeaders)
    tab_widget = QtWidgets.QTabWidget()
    for _type in allowedExportTypes:
        tableView = QtWidgets.QTableView()
        c = horizontalHeaders.index("date")
        tableSetup(tableView)
        proxy = RenderTypeProxyModel(_type, tableView)
        proxy.setSourceModel(model)
        proxy.sort(c, QtCore.Qt.AscendingOrder)
        tableView.setModel(proxy)
        tab_widget.addTab(tableView ,_type)

    tab_widget.show()
    sys.exit(app.exec_())

更新

在下一部分中,我对您的原始代码进行了改进,避免覆盖不必要的方法并添加委托:

from PySide2 import QtCore, QtGui, QtWidgets

#To be replaced by env variable
allowedExportTypes = ["img-prv", "img-final", "img-cg", "img-src", "camera"]


class DateDelegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(DateDelegate, self).initStyleOption(option, index)
        option.text = index.data().toString("yyyy-MM-dd hh:mm:ss")

class ExportTableModel(QtCore.QAbstractTableModel):
    def __init__(self, exportData, horizontalHeaders, parent=None):
        super(ExportTableModel, self).__init__(parent)
        self.__exportData = exportData
        self.__horizontalHeaders = horizontalHeaders

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.__exportData)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return len(self.__horizontalHeaders)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.__exportData[row][column]
            header = self.headerData(column, QtCore.Qt.Horizontal)
            if header == "date":
                value = QtCore.QDateTime.fromString(value, "yyyy-MM-dd hh:mm:ss")
            return value

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole and orientation == QtCore.Qt.Horizontal:
            if section < self.columnCount():
                return self.__horizontalHeaders[section]
            return "not implemented"

def create_tableview():
    tableView = QtWidgets.QTableView()
    tableView.setAlternatingRowColors(True)
    tableView.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
    return tableView

class RenderTypeProxyModel (QtCore.QSortFilterProxyModel):
    def __init__(self, c_type, _type, c_date, model, parent=None):
        super(RenderTypeProxyModel,self).__init__(parent)
        self.setSourceModel(model)
        self.setFilterKeyColumn(c_type)
        self.setFilterFixedString(_type)
        self.sort(c_date, QtCore.Qt.AscendingOrder)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)

    horizontalHeaders = ["status", "comment", "task", "type", "version", "user", "date", "filepath"] #horizontal header data
    exportData = # ...
    c_date = horizontalHeaders.index("date")
    c_type = horizontalHeaders.index("type")
    tab_widget = QtWidgets.QTabWidget()
    for _type in allowedExportTypes:
        tableView = create_tableview()
        tab_widget.addTab(tableView ,_type)
        proxy = RenderTypeProxyModel(c_type, _type, c_date, model, tableView)
        tableView.setModel(proxy)
        delegate = DateDelegate(tableView)
        tableView.setItemDelegateForColumn(c_date, delegate)

    tab_widget.show()
    sys.exit(app.exec_())