我有一个
ListView
用自定义C++模型初始化
rootModel
在Qml内。
模型继承
QAbstractListModel
定义了
QVector<customType>
作为私有成员填充模型。
在我的
ApplicationWindow
我创造了一个
Dialog
其中我更改了模型并调用
setList()
函数来更新它。这很管用。
我还想将模型的大小连接到
ScrollView
的
int
财产。此属性将定义
children
一个
RowLayout
.
问题是,当我试图将此属性绑定到模型的大小时,应用程序会崩溃。
仅供参考,模型的所有修改都遵循Qt的规则。
rowCount()
是
Q_INVOKABLE
. 我也试过用
onModelChanged
处理程序,但这不起作用(我在文档中检查过,当
modelReset()
是在里面发射的
设置列表()
通过
endResetModel()
我相信这是一个简单的过程(在我的项目中已经多次执行了属性绑定),但并没有如预期的那样工作。
我引用了我的项目的一些示例代码。
//main.qml
ConfiguredChannels{
id: configuredList
anchors{
left: parent.left
top: devices.bottom
right: tabs.left
bottom: parent.bottom
}
}
TabArea {
id: tabs
y: toolBar.height
x: parent.width / 8
anchors {
top: toolBar.bottom
}
width: 3 * parent.width / 4
height: 3 * parent.height / 4
countPWM: configuredList.model.rowCount() //This is where I want to bind.
}
//ConfiguredChannels.qml
id: confChanView
header: confChanHeader
model: ChannelModel{
id: rootModel
list: channelList
}
//TabArea.qml
Item{
id: tabAreaRoot
property alias channelsPWM: channelsPWM
property int countPWM
ScrollView{
id: scrollPWM
anchors.fill: parent
contentItem: channelsPWM.children
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOn
RowLayout{
id: channelsPWM
spacing: 0
Layout.fillHeight: true
Layout.fillWidth: true
Component.onCompleted: {
var namesPWM = [];
for (var i=0; i<countPWM; i++){
namesPWM.push("Channel"+(i+1));
}
createChannels(countPWM, "PWM", channelsPWM, namesPWM);
}
}
}
[编辑1]
在仔细观察之后,我意识到使用当前的实现,即使我正确地绑定到模型的大小,我仍然无法创建所需数量的
行列式
的
儿童
按需(在
对话
Configuration.qml
).
那是因为我把他们的创造放在里面
行列式
的
Component.onCompleted
处理程序。此处理程序的内容将在
配置.qml
将在内部初始化
main.qml
这是第一次。在那之后
countPWM
不会有什么不同,因为组件已经完成!拜托
纠正我
如果我在这一点上错了。
基于此,我遵循了另一个实现。我已经创建了一个“wrapper”函数
createChannels
,命名为
createStrips(countPWM)
。这样,才能正确更新
行列式
的
儿童
我必须调用这个函数。
\\Configuration.qml
\\more code
currentModel.setList(newList)
tabs.createStrips(tableModel.count) \\tableModel is used to populate the newList that will be set to the model
newList.clear()
\\more code
\\TabArea.qml
function createStrips(countPWM){
var namesPWM = [];
for (var i=0; i<countPWM; i++){
namesPWM.push("Channel"+(i+1));
}
createChannels(countPWM, "PWM", channelsPWM, namesPWM);
}
function createChannels(counter, channelType, channelParent, channelMapping){
if ( channelParent.children.length !== 0){
console.log("destroying");
for ( var j = channelParent.children.length; j > 0 ; j--){
channelParent.children[j-1].destroy();
}
}
for (var i=0;i<counter;i++){
var component = Qt.createComponent(channelType+".qml");
if( component.status !== Component.Ready )
{
if( component.status === Component.Error )
console.debug("Error:"+ component.errorString() );
return; // or maybe throw
}
var channels =component.createObject(channelParent, { "id": channelType+(i+1), "channelText.text": channelMapping[i]});
}
[编辑2]
尽管EDIT 1中的解决方案可以工作并产生
儿童
为了我的
卷轴视图
我认为它不够好,我认为最好的实现是将模型的大小更改与调用绑定到
创建条带(countPWM)
功能。类似于:
\\main.qml
ConfiguredChannels{
id: configuredList
anchors{
left: parent.left
top: devices.bottom
right: tabs.left
bottom: parent.bottom
}
onModelChanged: tabs.createStrips(model.rowCount) //or an appropriate signal handler defined on C++ side
}
或许更好的是
儿童
作为一种习俗
qml
每次更改模型大小时将发出的信号处理程序。(我试过
模型更改时
如上所述,但不起作用。可能我不见了,在这种情况下发出的是这个信号)
[解决方案]
我遵循了接受答案的指示
link
.
我加了一个
Q_PROPERTY
在名为
rowCount
与
NOTIFY
rowCountChanged
以及信号
void rowCountChanged();
. 而且,在函数内部
setList(newList)
我用它来更新模型,我在实现的末尾添加了
emit rowCountChanged();
. 最后我把这个信号和我的功能连接起来
createStrips(count)
在QML内。现在每次模型尺寸改变,我的
卷轴视图
将自动更新显示为
行列式
的孩子们。
\\ChannelModel.h
...
Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged)
...
signals:
void rowCountChanged();
\\ChannelModel.cpp
void ChannelModel::setList(ChannelList *list)
{
beginResetModel();
...
endRestModel();
emit rowCountChanged();
}
\\main.qml
Connections {
target: configuredList.model
onRowCountChanged: tabs.createStrips(configuredList.model.rowCount)
}