显示,更改数据并在qml中保留QQmlListProperty

时间:2014-07-26 00:55:02

标签: c++ qt qml qt5

过去我解决了QQmlListProperty的问题,将c ++ qlist暴露给qml,问题解决了,现在我再次尝试使用他们的解决方案,但我不能。 每次暴露给qml的列表第一次都是不同的,这次没有,我在主类中有一个Qlist,并且她的许多数据都是从db加载的,而其他数据在运行时已经改变。

当应用程序启动时,数据加载并暴露给Qml是可以的,我需要更改页面(gui)并保存数据存储在程序中,并且可能在其他guis(作为文本)中使用了许多数据,并且每当我更改页面(使用loader元素)程序崩溃时,我相信当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();
  }

在主类中为两个数据定义,我使用第一个作为aux,但是可以直接使用第二个(他们是我的想法)

QList<CStructBombUi * > listBombs;
ListBombsUi *listBufferBombs;  

我将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文件中的metod

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
         }
     }
 }

这里是元素转发器网格的声明

   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确定,但是我更改页面&#34; n&#34;并返回第1页,崩溃。我接受替代方案,谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

好吧,我检测到两件事,在CStructBombsUi的构造函数中失败,并且我使用了辅助列表,并且使用了CStructBombsUi *,并且更改了qml文件中的函数,我显示了更改。

main.qml中的更改

function setDataOfModelBombs()
{
    if(itemOfPageLoaded) {
        itemOfPageLoaded.numberBombs=listBombs.size()
          itemOfPageLoaded.setDataOfBombs(listBombs.bombsUi)
    }
}

更改detailsbombs.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();

我不使用值列表,用此调整程序不会崩溃