【发布时间】:2014-07-26 00:55:02
【问题描述】:
过去我解决了 QQmlListProperty 将 c++ qlist 暴露给 qml 的问题,问题已解决,现在我尝试再次使用他们的解决方案,但我不能。 第一次暴露给qml的list每次都不一样,这次不行,我在主类中有一个Qlist,她的很多数据都是从db加载的,还有一些在运行时改变。
当应用程序启动时,数据加载和暴露给 Qml 是好的,我需要更改页面(gui)并将数据保存在程序中,并且可能在其他 guis(作为文本)中使用了它们的许多数据,并且每次我更改页面(使用加载器元素)时程序崩溃,我相信当 c++ 类中的数据复制到 qml 中的 gui 时,qml 中的指针方向会发生变化。 我的代码来自 QmlListproperty 类和在 qml 中加载数据的方法,并从主 qml 复制到页面。
ListBombsUi.h 类的定义
#include "StructBombUi.h"
class ListBombsUi: public QObject{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<CStructBombUi> bombsUi READ bombsUiList NOTIFY bombsUiChanged);
Q_CLASSINFO("DefaultProperty", "bombsUi");
public:
ListBombsUi(QObject *parent=0);
QQmlListProperty<CStructBombUi> bombsUiList();
static void appendBombUi(QQmlListProperty<CStructBombUi> *list, CStructBombUi *pdt);
static void clear(QQmlListProperty<CStructBombUi> *property);
static int listSize(QQmlListProperty<CStructBombUi> *property);
static CStructBombUi *bombUiAt(QQmlListProperty<CStructBombUi> *property, int index);
void addBomb(CStructBombUi *bombUi);
Q_INVOKABLE int size();
void Q_INVOKABLE getMemory();
Q_INVOKABLE void clearList();
CStructBombUi* getValue(int index) const;
QList<CStructBombUi *> copyList();
signals:
void bombsUiChanged();
public:
int lastAdded;
private:
CStructBombUi *item;
QList<CStructBombUi*> m_BombsUi;
我如何注册qmltype
qmlRegisterType<ListBombsUi>("BombsListUiModel", 1, 0, "ListBombsUi");
ListBombsUi主要方法定义
ListBombsUi::ListBombsUi(QObject *parent):QObject(parent)
{}
QQmlListProperty<CStructBombUi> ListBombsUi::bombsUiList()
{
return QQmlListProperty<CStructBombUi>(this, &m_BombsUi, &ListBombsUi::appendBombUi,
&ListBombsUi::listSize,
&ListBombsUi::bombUiAt,
&ListBombsUi::clear);
emit bombsUiChanged();
}
void ListBombsUi::appendBombUi(QQmlListProperty<CStructBombUi> *list, CStructBombUi *pdt)
{
ListBombsUi *bombsList= qobject_cast<ListBombsUi *>(list->object);
if(bombsList) {
pdt->setParent(bombsList);
bombsList->m_BombsUi.append(pdt);
bombsList->bombsUiChanged();
}
}
void ListBombsUi::clearList()
{
m_BombsUi.clear();
emit bombsUiChanged();
}
void ListBombsUi::addBomb(CStructBombUi *bombUi)
{
m_BombsUi.append(bombUi);
emit bombsUiChanged();
}
在主类中定义两个数据,我使用第一个作为辅助,但可以直接使用第二个(它们最初是我的想法)
QList<CStructBombUi * > listBombs;
ListBombsUi *listBufferBombs;
我为 qml 中的元素分配了一个 listBufferBombs
listBufferBombs = mainObject->findChild<ListBombsUi*>("listGralBombs");
向 qml 公开数据的方法
void EgasWindowWork::setDataOfBombsInModels()//, const QList <CEstrucBombUi> *const dataArrayBombs)
{
if( (mainObject) ) {
CStructBombUi e,k,j;
e.initializing(QStringList()<<"text1"<<"text2"<<"text3");
e.update(QString("15"), QString("1"), QString("1"), QString("1"),QString("1"));
k.initializing(QStringList()<<"text1"<<"text2");
k.update(QString("2"), QString("2"), QString("2"), QString("2"),QString("2"));
listBombs.append(&e);
listBombs.append(&k);
for(qint16 i=0; i<listBombs.size() ; i++)
{ listBufferBombs->addBomb( listBombs.value(i) ); }
QMetaObject::invokeMethod(mainObject, "setDataOfModelBombs"); //this method copy the list located in main qml for page
}
main.qml 文件中的方法
function setDataOfModelBombs()
{
if(itemOfPageLoaded) {
itemOfPageLoaded.listBombs=listed
itemOfPageLoaded.setDataOfBombs() //this function put every data inside the every field of qml gui element
}
}
在 main.qml 文件中声明 loader 元素
Loader{
id: pageLoader
focus: true
//anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: parent.height-50
anchors.top: headerIcons.bottom
objectName: "switchPages"
z: 2
source: "BombsUi.qml"
property bool valid: item !== null
Binding {
target: pageLoader.item
property: "numberBombs"
value: numberOfBombs
when: pageLoader.status == Loader.Ready
}
}
作为页面加载的qml文件中的方法
function setDataOfBombs()
{
var size=newList.size()
arrayBombs.model=size //i use a repater container, and model is the number of elements loaded
if(size>0) {
for(var i=0; i<size; i++) {
//exactly in the next line the error happens
arrayBombs.itemAt(i).priceText=newList.bombsUi[i].ultimateProductPrice
arrayBombs.itemAt(i).volumeText = newList.bombsUi[i].ultimateProductVolume
//exist mor date, but with this are sufficient
}
}
}
这里是元素repeater-grid的声明
Item{
width: parent.width; height: parent.height
Item{
id: bombsArea
height: parent.height; width: parent.width*0.7
anchors.leftMargin: 10
y: 3
x: 2
Grid{
id: gridOfBombsModel
width: parent.width; height: parent.height
spacing: 7
rows: 6; columns: Math.round((parent.width/165))
Repeater{
id: arrayBombs
BombModel{
numberBomb: (index + 1)
MouseArea{
anchors.fill: parent
onClicked:{
parent.borderProperties.color="red"
parent.borderProperties.width=1.5
}
}
}
}
}
}
程序加载页面 1 正常,但我更改页面“n”并返回页面 1,崩溃。我接受替代方案,感谢您的帮助。
【问题讨论】:
-
它在哪里崩溃?你能上传整个项目吗?
-
在
ListBombsUi::appendBombUi函数中,您忘记了“emit”关键字。它应该发出 bombsList->bombsUiChanged(); -
Mitch,当我在迭代所有日期列表后尝试使用数据时程序崩溃,(我从 qml 添加更多数据)并且 Shubhanga 不可能在静态成员中发出信号(我不知道到今天为止,但谢谢,每天学习一件事)。