ListView中的XML未更改 我试图用C++实现一个例子,使XML数据模型在我的.qML文件中(当我点击按钮时)发生变化。为此,我将返回一个Qt属性(GroupDataModel)。但是在返回对象之后,ListView没有改变,尽管我看到model属性再次返回 OBS:如果从XML数据模型中加载它,而不是加载C++代码,它就工作了。
这是我的XmlTest.hpp:ListView中的XML未更改 我试图用C++实现一个例子,使XML数据模型在我的.qML文件中(当我点击按钮时)发生变化。为此,我将返回一个Qt属性(GroupDataModel)。但是在返回对象之后,ListView没有改变,尽管我看到model属性再次返回 OBS:如果从XML数据模型中加载它,而不是加载C++代码,它就工作了。,c++,qml,blackberry-10,blackberry-cascades,C++,Qml,Blackberry 10,Blackberry Cascades,这是我的XmlTest.hpp: #ifndef XmlTest_HPP_ #define XmlTest_HPP_ #include <QObject> #include <bb/cascades/GroupDataModel> namespace bb { namespace cascades { class Application; }} class XmlTest : public QObject { Q_OBJECT Q_PROPERTY(
#ifndef XmlTest_HPP_
#define XmlTest_HPP_
#include <QObject>
#include <bb/cascades/GroupDataModel>
namespace bb { namespace cascades { class Application; }}
class XmlTest : public QObject
{
Q_OBJECT
Q_PROPERTY(bb::cascades::GroupDataModel* model READ model NOTIFY onModelChanged);
public:
XmlTest(bb::cascades::Application *app);
virtual ~XmlTest() {}
Q_INVOKABLE
bb::cascades::GroupDataModel *model();
Q_INVOKABLE
void setGroupDataModel();
signals:
void onModelChanged();
private:
bb::cascades::GroupDataModel *m_model;
};
#endif /* XmlTest_HPP_ */
以及我尝试加载的XML:
<root>
<user name="myUsername" realname="My Real Name"/>
<option title="Option 1"/>
<option title="Option 2"/>
<option title="Option 3"/>
<option title="Option 4"/>
<option title="Option 5"/>
</root>
Q_可调用函数是某种插槽,因此它们无法返回对象。 您应该找到ListView并放置数据模型
- 在id:objectName:“listview”之后添加QML
- 在C++中获取listView:listView*listView=root->findChild(“listView”)李>
- 设置数据模型:listView->setDataModel(m_模型)李>
setGroupDataModel()
设置为可调用的Q\u
——其他只是属性访问器
但是你误解了GroupDataModel。除非模型属性发生更改,否则不希望发出一个onModelChanged()
。在您的情况下,属性没有更改,更改的只是属性中的值。因此,您不需要emit onModelChanged()
,我认为它应该将新值作为参数
那么问题出在哪里呢
您需要检查是否正确读取了XML文件中的数据
然后,您需要仔细阅读-如果我阅读正确,它将只使用'item'和'header'作为项目类型,因此不会使用ListItemComponents
如果不使用GroupDataModel而使用
这是我的XmlListView.hpp
主类(您的XmlTest
类):
xml模型文件与您的相同
要真正理解哪里出了问题,需要检查从XmlDataAccess
类加载的ehte数据。我还没有完全解决这个问题——恐怕我现在没有更多的时间了——但我尝试了,在我的构造函数中:
qDebug() << "==========================================================";
XmlDataAccess xml;
QVariant xmlData = xml.load(QDir::currentPath() + "/app/native/assets/models/model.xml");
if (xml.hasError()) {
qDebug(xml.error().errorMessage().toAscii());
} else {
QVariantList list = xmlData.toList();
qDebug() << "list len = " << list.size();
}
qDebug() << "==========================================================";
qDebug()如果您真正想要的是将“用户”数据显示为标题,那么您可以使用@craigmj在其回答中建议的确切代码将数据放入模型中,但只需将main.qml中的ListItemComponent
的定义更改为使用header
,而不是StandardListItem
。我在下面提供了完整的列表视图
,您应该可以直接将其放到main.qml中<代码>标题
已记录在案
Q_INVOKABLE不是插槽,它们只是向QML公开的方法。它们可以返回值。没错,问题在于我调用.toList()时解析数据的方式。不知何故,当我们在QML中使用XMLDATAMODEL时,当我从C++代码中解析它时,它就不起作用。但是我还没有弄清楚如何使它与头和项一起工作……如果您使用XMLDataModel,那么您可以区分“用户”和“选项”,尽管这可能不是您的确切意思。。。?您是否希望将“用户”节点作为[n]的indexPath,将选项作为[n,o]的indexPath?这其实并不重要。我想要的是区分作为标题的“用户”和作为标准项的“选项”。我使用的是GroupDataModel,因为当我尝试XmlDataModel时,它没有出现在屏幕上,但我只能使用QVariantList才能使它工作,因为在QVariantList中无法知道节点的名称。
<root>
<user name="myUsername" realname="My Real Name"/>
<option title="Option 1"/>
<option title="Option 2"/>
<option title="Option 3"/>
<option title="Option 4"/>
<option title="Option 5"/>
</root>
// Default empty project template
#ifndef XmlListView_HPP_
#define XmlListView_HPP_
#include <QObject>
#include <bb/cascades/XmlDataModel>
#include <bb/cascades/DataModel>
namespace bb { namespace cascades { class Application; }}
class XmlListView : public QObject
{
Q_OBJECT
Q_PROPERTY(bb::cascades::DataModel *model READ model NOTIFY onModelChanged);
public:
XmlListView(bb::cascades::Application *app);
virtual ~XmlListView() {}
bb::cascades::DataModel *model();
Q_INVOKABLE void setGroupDataModel();
signals:
void onModelChanged();
private:
bb::cascades::XmlDataModel *m_model;
};
#endif /* XmlListView_HPP_ */
// Default empty project template
#include "XmlListView.hpp"
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/data/XmlDataAccess>
using namespace bb::cascades;
using namespace bb::data;
XmlListView::XmlListView(bb::cascades::Application *app)
: QObject(app)
{
m_model = new XmlDataModel();
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("_xmlTest", this);
AbstractPane *root = qml->createRootObject<AbstractPane>();
app->setScene(root);
}
DataModel *
XmlListView::model() {
return m_model;
}
void
XmlListView::setGroupDataModel() {
m_model->setSource(QUrl("models/model.xml"));
}
import bb.cascades 1.0
Page {
Container {
id: mainContainer
layout: DockLayout {}
ListView {
id: listView
dataModel: _xmlTest.model
listItemComponents: [
ListItemComponent {
type: "user"
StandardListItem {
title: ListItemData.realname
description: ListItemData.name
}
},
ListItemComponent {
type: "option"
StandardListItem {
title: ListItemData.title
}
}
]
}
Button {
text: "Click"
onClicked: {
_xmlTest.setGroupDataModel()
}
verticalAlignment: VerticalAlignment.Bottom
horizontalAlignment: HorizontalAlignment.Center
}
}
}
qDebug() << "==========================================================";
XmlDataAccess xml;
QVariant xmlData = xml.load(QDir::currentPath() + "/app/native/assets/models/model.xml");
if (xml.hasError()) {
qDebug(xml.error().errorMessage().toAscii());
} else {
QVariantList list = xmlData.toList();
qDebug() << "list len = " << list.size();
}
qDebug() << "==========================================================";
ListView {
id: listView
dataModel: _xmlTest.model
onDataModelChanged: {
console.log("Data model changed!");
}
listItemComponents: [
ListItemComponent {
type: "user"
Header {
title: ListItemData.realname
subtitle: ListItemData.name
}
},
ListItemComponent {
type: "option"
StandardListItem {
title: ListItemData.title
}
}
]
}