Show, change data and keep QQmlListProperty in qml

最后都变了- 提交于 2020-01-05 08:49:08

问题


in the past i resolved a problem with QQmlListProperty for expose c++ qlist to qml, and the problem was resolved, now i try use their solution again, but i can't. the first time the list exposed to qml every time are different, this time no, i have a Qlist in a main class, and many data from her are loaded from db, and others changed in runtime.

When the application start, the load of data and exposed to Qml is ok, i need change of page(gui) and keep the data stored in program and probably used many of their data in other guis (as text), and every time i change of page (with loader element) the program crashes, i believe a directions of pointers are changed in qml when the data from c++ class is copied to gui in qml. My Code from QmlListproperty class and method of Load data in qml, and copy from the main qml to page.

definition of class 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;

i register how qmltype

qmlRegisterType<ListBombsUi>("BombsListUiModel", 1, 0, "ListBombsUi");

definition of main methods of 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();
  }

definition in main class for two data, i use the first as aux, but is possible use the second directly(their are my idea originallly)

QList<CStructBombUi * > listBombs;
ListBombsUi *listBufferBombs;  

i assign a listBufferBombs to element in qml

listBufferBombs = mainObject->findChild<ListBombsUi*>("listGralBombs");

method for expose data to 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
 }

the metod in main.qml file

function setDataOfModelBombs()
{  
    if(itemOfPageLoaded)   {   
        itemOfPageLoaded.listBombs=listed
        itemOfPageLoaded.setDataOfBombs() //this function put every data inside the every field of qml gui element
    }
 }

declaration of loader element in main.qml file

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
    }

}

method in qml file loaded as page

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

and here is declaration of element 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
                        }
                    }
                }
            }
        }
    }

the program load the page 1 ok, but i change a page "n" and return to page 1, crashes. i accept alternatives to, Thanks for your help.


回答1:


Well, i detected two things, fail in constructor of CStructBombsUi and i descart use of auxiliar list, and the use of CStructBombsUi* exclusively, and change the function in qml file, i show the changes.

Changes in main.qml

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

changes in detailsbombs.qml (file loaded as page), and here i don't instance a 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() ) }
         }
   }
}

The next line don't exist more

QList<CStructBombUi* > listBombs;

And every is a pointer

CStructBombUi *e=new CStructBombUi();

i don't use a list of values, with this adjusts the program don't crashes



来源:https://stackoverflow.com/questions/24966474/show-change-data-and-keep-qqmllistproperty-in-qml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!