我是python和qt的初学者。我需要通过list的一个属性对python中创建的QAbstractList进行排序。我使用sorted()方法。但是当我运行代码时python停止工作。你帮助。从Qml我调用了槽sortData()。sortData()函数是我认为不正确 我的代码是
model2.py
from PyQt5.QtCore import QAbstractListModel, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtCore import QSortFilterProxyModel
class PersonModel(QAbstractListModel):
Name = Qt.UserRole + 1
value1 = Qt.UserRole + 2
value2 = Qt.UserRole + 3
value3 = Qt.UserRole + 4
value4 = Qt.UserRole + 5
personChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.persons = [
{'name': 'item1', 'value1': 10.66, 'value2':10.78, 'value3':10.94, 'value4':10.90},
{'name': 'item1', 'value1': 10.56, 'value2':10.78, 'value3':10.34, 'value4':10.90},
{'name': 'item2', 'value1': 10.66, 'value2':10.88, 'value3':10.44, 'value4':10.30}
]
self.i=0
print(self.persons)
def data(self, QModelIndex, role):
row = QModelIndex.row()
if role == self.Name:
return self.persons[row]['name']
if role == self.value1:
return self.persons[row]['value1']
if role == self.value2:
return self.persons[row]['value2']
if role == self.value3:
return self.persons[row]['value3']
if role == self.value4:
return self.persons[row]['value4']
def rowCount(self, parent=None):
return len(self.persons)
def roleNames(self):
return {
Qt.UserRole + 1: b'name',
Qt.UserRole + 2: b'value1',
Qt.UserRole + 3: b'value2',
Qt.UserRole + 4: b'value3',
Qt.UserRole + 5: b'value4'
}
@pyqtSlot()
def addData(self):
self.beginResetModel()
self.persons = self.persons.append({'name': 'peter', 'value1': 22, 'value2':30, 'value3':40, 'value4':50})
self.endResetModel()
print(self.persons)
@pyqtSlot()
def editData(self):
print(self.model.persons)
@pyqtSlot(int)
def sortData(self):
self.beginResetModel()
self.persons = sorted(self.persons, key=lambda x: float(x[1]))
sorted(self.persons)
#sorted_x = sorted(self._persons, key=lambda role: self.value1)
#print(sorted_x)
#self.persons.sort(2, key=Qt.AscendingOrder)
self.endResetModel()
print(self.persons)
Hello.py
import sys, model2
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QSortFilterProxyModel
from os import path
import PyQt5
import sys, model2
from PyQt5.QtCore import *
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import pyqtProperty, QCoreApplication, QObject, QUrl
from PyQt5.QtQml import qmlRegisterType, QQmlComponent, QQmlEngine, QQmlListProperty
from PyQt5.QtCore import QTimer, pyqtSignal,pyqtSlot
from PyQt5.QtQml import QQmlListProperty
import sys, model2
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
#import QSortFilterProxyModel
import imageResources
import fontResources
class MainWindow(QQuickView):
def __init__(self, parent=None):
super().__init__(parent)
self.model = model2.PersonModel()
self.proxyModel = QSortFilterProxyModel();
self.proxyModel.setSourceModel(self.model)
self.rootContext().setContextProperty('PersonModel', self.model)
self.rootContext().setContextProperty('MainWindow', self)
self.proxyModel.sort(2,Qt.AscendingOrder)
self.setSource(QUrl('main.qml'))
myApp = QApplication(sys.argv)
ui = MainWindow()
ui.show()
sys.exit(myApp.exec_())
从Qml我调用槽sortData()。sortData()函数不正确我认为
答案 0 :(得分:0)
要对视图进行排序,最合适的选择是使用QSortProxyModel,但这只能在Python端工作,如果我们想要将该方法暴露给QML,我们必须进行一些修改,以便创建一个继承自QSortProxyModel的类并添加方法:
class SortProxyModel(QSortFilterProxyModel):
@pyqtSlot(str, int)
def sortData(self, roleName, order):
if order == Qt.InitialSortOrderRole:
self.setSortRole(order)
self.invalidate()
else:
roles = [key for key, value in self.roleNames().items() if value == roleName.encode()]
if len(roles) > 0:
self.setSortRole(roles[0])
self.sort(0, order)
然后你需要做的是通过setSourceModel()
传递原始模型的基础,这个新模型是你必须传递给qml的。
if __name__ == '__main__':
myApp = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
model = PersonModel()
proxyModel = SortProxyModel()
proxyModel.setSourceModel(model)
engine.rootContext().setContextProperty('mymodel', proxyModel)
engine.load(QUrl.fromLocalFile(QDir.current().absoluteFilePath('main.qml')))
if len(engine.rootObjects()) == 0:
sys.exit(-1)
sys.exit(myApp.exec_())
在以下link中有一个示例