Python 无法将CustomModel分配给QQmlListModel
假设我们有一个列表模型:Python 无法将CustomModel分配给QQmlListModel,python,qml,qtquick2,pyside2,qabstractlistmodel,Python,Qml,Qtquick2,Pyside2,Qabstractlistmodel,假设我们有一个列表模型: from PySide2.QtCore import Qt, QAbstractListModel, QModelIndex import numpy as np class AxisModel(QAbstractListModel): MaxRole = Qt.UserRole + 1015 MinRole = Qt.UserRole + 1016 TicksRole = Qt.UserRole + 1017 def __init_
from PySide2.QtCore import Qt, QAbstractListModel, QModelIndex
import numpy as np
class AxisModel(QAbstractListModel):
MaxRole = Qt.UserRole + 1015
MinRole = Qt.UserRole + 1016
TicksRole = Qt.UserRole + 1017
def __init__(self, min_, max_, price_unit, parent=None):
super(AxisModel, self).__init__(parent)
self.max = float(max_)
self.min = float(min_)
self.price_unit = float(price_unit)
self.ticks = np.arange(self.min, self.max + self.price_unit, self.price_unit).tolist()
def rowCount(self, parent=QModelIndex()):
if parent.isValid():
return 0
return len(self.ticks)
def data(self, index: QModelIndex, role):
if 0 > index.row() > self.rowCount() and not index.isValid():
return None
if role == AxisModel.MinRole:
return self.min
if role == AxisModel.MaxRole:
return self.max
if role == AxisModel.TicksRole:
return self.ticks[index.row()]
def roleNames(self):
roles = dict()
roles[AxisModel.MinRole] = b"min"
roles[AxisModel.MaxRole] = b"max"
roles[AxisModel.TicksRole] = b"ticks"
return roles
这稍后将在python代码中使用:
(...)
axismodel = AxisModel(min_=min_, max_=max_, price_unit=0.25)
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
# register models
view.rootContext().setContextProperty("axis_model", axismodel)
view.rootContext().setContextProperty("ts_model", tsmodel) # some other model
qml_file = os.path.join("/home/user/code/project", "simple_test.qml")
view.setSource(QUrl.fromLocalFile(os.path.abspath(qml_file)))
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
app.exec_()
使用它的QML文件(简化):
轴项目:
Item {
id: axis
property ListModel model
property real max: model.max
property real min: model.min
(...)
}
这会产生一个错误:
无法将AxisModel分配给QQmlListModel
好的,AxisModel在技术上不是QQmlListModel,但它们都继承自QBStractItemModel。我不知道如何解决这个问题。我的两个想法是:
ListModel
不同的类型。我不知道是哪一个。我试过QObject,QVariant,结果不是QML类型。项不工作,因为AxisModel不是QQuickItem实例谢谢您的时间。我想您已经正确地识别了问题。Axis模型不是QQmlListModel,因此无法指定它 但您应该能够像这样简单地定义您的模型:
property var model
为了补充已被接受的答案,以下是使其生效所需的更改 轴项目-使用
var
让QML自行决定类型:
Item {
id: axis
property var model
property var min
property var max
(...)
}
在QML中调用axis项:
Item {
AxisTest {
model: axis_model
min: axis_model.min
max: axis_model.max
}
(...)
}
然后,在python中:
就这样!至少对于模型零件。我仍然无法使用
model.max
访问最小/最大字段。这使得无法将[undefined]分配给QString
,这很奇怪,因为min和max都是浮点数,应该可以工作。min
和max
是模型中的角色,而不是模型本身的属性。这意味着列表中的每个项目都有自己的最小值和最大值。哎呀。看来我严重误解了这一点。你能给我指一下这里的正确方向吗?我如何将min和max定义为模型上的属性?我不是python爱好者,所以我不知道适合您的语法。我将从对属性的基本理解开始,然后也许可以解释如何在python中使用它。
Item {
AxisTest {
model: axis_model
min: axis_model.min
max: axis_model.max
}
(...)
}
class AxisModel(QAbstractListModel):
def get_min(self):
return self._min
def set_min(self, _min):
self._min = _min
def get_max(self):
return self._max
def set_max(self, _max):
self._max = _max
@Signal
def max_changed(self, _max):
pass
@Signal
def min_changed(self, _min):
pass
TicksRole = Qt.UserRole + 1015
max = Property(float, get_max, set_max, notify=max_changed)
min = Property(float, get_min, set_min, notify=min_changed)
def __init__(self, min_, max_, price_unit, parent=None):
super(AxisModel, self).__init__(parent)
self._max = float(max_)
self._min = float(min_)
self.ticks = np.arange(float(min_), float(max_) + float(price_unit), float(price_unit)).tolist()
def rowCount(self, parent=QModelIndex()):
if parent.isValid():
return 0
return len(self.ticks)
def data(self, index: QModelIndex, role):
if 0 > index.row() > self.rowCount() and not index.isValid():
return None
if role == AxisModel.TicksRole:
return self.ticks[index.row()]
else:
return None
def roleNames(self):
roles = dict()
roles[AxisModel.TicksRole] = b"ticks"
return roles