在过去我解决了一个问题与QQmlListProperty暴露c++ qlist到qml,问题得到了解决,现在我尝试使用他们的解决方案再次,但我不能。第一次暴露给qml的列表每次都是不同的,这次不是,我在一个主类中有一个Qlist,并且她的许多数据是从db加载的,其他的在运行时更改。
当应用程序启动时,数据的加载和暴露在Qml中是ok的,我需要更改页面(gui)并保持数据存储在程序中,并且可能在其他gui中使用了许多数据(作为文本),并且每次更改页面(带有加载器元素)程序崩溃,我认为当从c++类中的数据复制到Qml中的gui时,Qml中指针的方向发生了变化。我的代码从QmlListproperty类和方法加载数据在qml中,并从主qml复制到页面。
类listbombui .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;
i assign一个listBufferBombs给qml元素
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{
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
}
}
}
这里是元素repeat -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 ok,但我更改了页面"n"并返回到页面1,崩溃了。谢谢你的帮助。
好吧,我发现了两件事,CStructBombsUi的构造函数失败,我详细说明了辅助列表的使用,以及CStructBombsUi*的使用,并在qml文件中更改了函数,我显示了更改。
main的变化。qml
function setDataOfModelBombs()
{
if(itemOfPageLoaded) {
itemOfPageLoaded.numberBombs=listBombs.size()
itemOfPageLoaded.setDataOfBombs(listBombs.bombsUi)
}
}
细节变化。qml(文件作为页面加载),这里我没有实例ListBombs
function setDataOfBombs(bombsUi)
{
if(numberBombs>0) {
for(var i=0; i<numberBombs; i++)
{
arrayBombs.itemAt(i).priceText=bombsUi[i].ultimateProductPrice
arrayBombs.itemAt(i).volumeText = bombsUi[i].ultimateProductVolume
arrayBombs.itemAt(i).amountText= bombsUi[i].getUltimateProductMount()
arrayBombs.itemAt(i).fuelText= bombsUi[i].getUltimateProductName()
if(bombsUi[i].getFuels())
{arrayBombs.itemAt(i).setListOfFuelsInBomb( bombsUi[i].getFuels() ) }
}
}
}
下一行不存在
QList<CStructBombUi* > listBombs;
每一个都是指针
CStructBombUi *e=new CStructBombUi();
我不使用值列表,这样调整程序不会崩溃