【问题标题】:Show, change data and keep QQmlListProperty in qml在 qml 中显示、更改数据并保留 QQmlListProperty
【发布时间】: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 不可能在静态成员中发出信号(我不知道到今天为止,但谢谢,每天学习一件事)。

标签: c++ qt qml qt5


【解决方案1】:

好吧,我检测到两件事,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();

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

【讨论】:

    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    • 2013-11-05
    • 2019-08-14
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多