3
我想在PySide中爲我的模型/視圖結構設置自定義排序行爲。 所有項目都是字典,我需要按鍵過濾(我不是在這些字典的表格視圖之後,而是需要將它們呈現爲一個實體)。mvc(QSortFilterProxyModel)中的自定義排序只能工作一次
我繼承自QSortFilterProxyModel並重新實現了lessThan方法。它在第一次更改排序小部件(它觸發代理的sort()方法)時工作正常,但在此之後,不再調用lessThan方法。我不知道爲什麼,並希望在這裏得到一些幫助。如果解決方案存在,我很樂意考慮如何以不同的方式解決這個問題。
這是我的代理:
class ProxyModel (QSortFilterProxyModel):
def __init__(self, parent=None):
super(ProxyModel, self).__init__(parent)
self.setFilterCaseSensitivity(Qt.CaseInsensitive)
self.setSortCaseSensitivity(Qt.CaseInsensitive)
self.setDynamicSortFilter(True)
def sortBy(self, attr):
print 'sorting by', attr
self.__sortBy = attr
self.sort(0, Qt.AscendingOrder) # THIS DOES NOT GET CALLED WHEN THE COMBO BOX CHANGES A SECOND TIME
def lessThan(self, left, right):
'''Custom sorting behaviour'''
leftTool = (self.sourceModel().itemFromIndex(left))
rightTool = (self.sourceModel().itemFromIndex(right))
leftData = leftTool.data()[ self.__sortBy ]
rightData = rightTool.data()[ self.__sortBy ]
return leftData < rightData
這裏是完整的測試代碼: 進口SYS 從PySide.QtGui進口* 從PySide.QtCore進口*
class MainWidget(QWidget) :
def __init__(self, parent=None):
super(MainWidget, self).__init__()
self.listView = MyListView()
model = MyModel()
# MODELS AND VIEWS
self.proxyModel = ProxyModel()
self.proxyModel.setSourceModel(model)
self.listView.setModel(self.proxyModel)
# LAYOUTS
verticalLayout = QVBoxLayout()
filterLayout = QHBoxLayout()
# SORTING WIDGET
sortLayout = QHBoxLayout()
sortLabel = QLabel('sort:')
self.sortWidget = QComboBox()
self.sortWidget.addItems(['title', 'author', 'downloads'])
self.sortWidget.currentIndexChanged.connect(self.sortTools)
sortLayout.addWidget(sortLabel)
sortLayout.addWidget(self.sortWidget)
verticalLayout.addLayout(filterLayout)
verticalLayout.addLayout(sortLayout)
verticalLayout.insertWidget(0, self.listView)
self.setLayout(verticalLayout)
def sortTools(self):
text = self.sortWidget.currentText()
self.proxyModel.sortBy(text)
class ProxyModel (QSortFilterProxyModel):
def __init__(self, parent=None):
super(ProxyModel, self).__init__(parent)
self.setFilterCaseSensitivity(Qt.CaseInsensitive)
self.setSortCaseSensitivity(Qt.CaseInsensitive)
self.setDynamicSortFilter(True)
def sortBy(self, attr):
print 'sorting by', attr
self.__sortBy = attr
self.sort(0, Qt.AscendingOrder) # THIS DOES NOT GET CALLED WHEN THE COMBO BOX CHANGES A SECOND TIME
def lessThan(self, left, right):
'''Custom sorting behaviour'''
leftTool = (self.sourceModel().itemFromIndex(left))
rightTool = (self.sourceModel().itemFromIndex(right))
leftData = leftTool.data()[ self.__sortBy ]
rightData = rightTool.data()[ self.__sortBy ]
return leftData < rightData
class MyListView(QListView):
def __init__(self, parent=None):
super(MyListView, self).__init__(parent)
self.setEditTriggers(QListView.NoEditTriggers)
self.setViewMode(QListView.IconMode)
self.setMovement(QListView.Static)
self.setResizeMode(QListView.Adjust)
self.setDragEnabled(True)
class MyModel(QStandardItemModel):
def __init__(self, parent=None):
super(MyModel, self).__init__(parent)
self.init_data()
def init_data(self):
row = 0
toolData = [ {'title':'ToolA', 'author':'John Doe', 'downloads':123, 'category':'color'},
{'title':'ToolB', 'author':'me', 'downloads':13, 'category':'color'},
{'title':'ToolC', 'author':'you', 'downloads':321, 'category':'transform'},
{'title':'ToolD', 'author':'unknown', 'downloads':2, 'category':'transform'}]
for tool in toolData:
item = QStandardItem('%(title)s by %(author)s (%(category)s) - %(downloads)s downloads' % tool)
item.setData(tool)
self.setItem(row, 0, item)
row += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWidget = MainWidget()
mainWidget.resize(400, 400)
mainWidget.show()
sys.exit(app.exec_())
嘗試使用model.invalidate()後組合框的值發生變化 –
太好了,非常感謝 –