显示,更改数据和保持QQmlListProperty在qml



在过去我解决了一个问题与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();

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

相关内容

  • 没有找到相关文章

最新更新