我要做什么:从模型中获取项目,然后使用排序代理以不同的角色对它们进行排序: 预期输出:
实际输出中包含不应包含的空行:
您会看到空行展开了ListView,甚至可以通过光标选择。
以下是产生此错误行为的代码:
from PySide2.QtCore import *
from PySide2.QtWidgets import *
import sys
import string
import random
class MyItem:
def __init__(self, name, value):
self.name = name
self.value = value
def __str__(self):
return self.name +" "+ str(self.value)
class MyCustomModel(QAbstractListModel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.list = []
def rowCount(self, parent=None):
return len(self.list)
def data(self, index, role):
row = index.row()
if row < 0 or row >= len(self.list):
return None
item = self.list[row]
if role == Qt.DisplayRole:
return str(item)
if role == Qt.UserRole:
return item.value
else:
return None
def add(self, item):
rc = self.rowCount()
self.beginInsertRows(QModelIndex(), rc, rc+1)
self.list.append(item)
self.endInsertRows()
class MyWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = MyCustomModel()
self.listView = QListView(self)
self.sortingProxy = QSortFilterProxyModel()
self.sortingProxy.setSourceModel(self.model)
self.sortingProxy.setSortRole(Qt.UserRole)
self.sortingProxy.sort(0, Qt.AscendingOrder)
self.listView.setModel(self.sortingProxy)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.listView)
self.setLayout(self.layout)
self.show()
# create some random data for the model
for i in range(10):
randomName = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)])
self.model.add(MyItem(randomName, random.randint(0, 30)))
app = QApplication(sys.argv)
widget = MyWidget()
app.exec_()
我已将问题归结为QSortFilterProxyModel,因为将其删除后问题就消失了,但是程序不再对数据进行排序:
from PySide2.QtCore import *
from PySide2.QtWidgets import *
import sys
import string
import random
class MyItem:
def __init__(self, name, value):
self.name = name
self.value = value
def __str__(self):
return self.name +" "+ str(self.value)
class MyCustomModel(QAbstractListModel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.list = []
def rowCount(self, parent=None):
return len(self.list)
def data(self, index, role):
row = index.row()
if row < 0 or row >= len(self.list):
return None
item = self.list[row]
if role == Qt.DisplayRole:
return str(item)
if role == Qt.UserRole:
return item.value
else:
return None
def add(self, item):
rc = self.rowCount()
self.beginInsertRows(QModelIndex(), rc, rc+1)
self.list.append(item)
self.endInsertRows()
class MyWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = MyCustomModel()
self.listView = QListView(self)
self.listView.setModel(self.model)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.listView)
self.setLayout(self.layout)
self.show()
# create some random data for the model
for i in range(10):
randomName = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)])
self.model.add(MyItem(randomName, random.randint(0, 30)))
app = QApplication(sys.argv)
widget = MyWidget()
app.exec_()
由于该问题似乎是由Pyside2 / Qt5代码引起的,因此我似乎不知道如何解决它。
答案 0 :(得分:1)
问题不是代理,问题是由您用于添加项目的方法引起的,如果您查看docs,则必须将行号从其添加到的地方以及传递到的地方(在这种情况下为仅添加1,然后两个都匹配,通常情况下,如果添加n个元素,则解决方案是:
rc = self.rowCount()
self.beginInsertRows(QModelIndex(), rc, rc + n - 1)
因此,您的解决方案是:
def add(self, item):
rc = self.rowCount()
self.beginInsertRows(QModelIndex(), rc, rc)
self.list.append(item)
self.endInsertRows()