QSortFilterProxyModel 按列值
QSortFilterProxyModel by column value
table 模型数据示例
我有一个带有 tabWidget 的图形用户界面,每个图形用户界面中都有一个 table 视图。每个选项卡都描述了一个文件夹(参见列类型),其中包含我从中提取数据的子目录。我想要一个主要模型,通过在每个 table 视图之间附加一个 QSortFilterProxy 模型来驱动所有视图,该模型过滤每个单独 TableView 的 "type" 的主要模型(传递到子类 RenderTypeProxyModel)。奖励:理想情况下,它们也应该排序,以便最近的视图(见日期列)出现在最前面。
这是我当前的版本,但 table 仍然空白,原因我无法弄清楚:
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 变量即可。
错误是因为type是python中的保留字:
if model.data(index,QtCore.Qt.DisplayRole) == type:
你必须使用 self.__type
.
另一方面,如果您想按日期对数据进行排序,则无需启用 setSortingEnabled()
, just use 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_())
table 模型数据示例
我有一个带有 tabWidget 的图形用户界面,每个图形用户界面中都有一个 table 视图。每个选项卡都描述了一个文件夹(参见列类型),其中包含我从中提取数据的子目录。我想要一个主要模型,通过在每个 table 视图之间附加一个 QSortFilterProxy 模型来驱动所有视图,该模型过滤每个单独 TableView 的 "type" 的主要模型(传递到子类 RenderTypeProxyModel)。奖励:理想情况下,它们也应该排序,以便最近的视图(见日期列)出现在最前面。 这是我当前的版本,但 table 仍然空白,原因我无法弄清楚:
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 变量即可。
错误是因为type是python中的保留字:
if model.data(index,QtCore.Qt.DisplayRole) == type:
你必须使用 self.__type
.
另一方面,如果您想按日期对数据进行排序,则无需启用 setSortingEnabled()
, just use 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_())