【问题标题】:QVariantList becomes nested when accessed from Q_PROPERTY in QML从 QML 中的 Q_PROPERTY 访问时,QVariantList 变为嵌套
【发布时间】:2018-01-25 17:50:18
【问题描述】:

我在通过另一个 Q_GADGET 对象中的 Q_PROPERTY 访问由 Q_GADGET 对象组成的 QVariantLists 时遇到了一个奇怪的问题。出于某种原因,当通过属性访问它们时,列表将自身嵌套在两个元素中,如下所示:

变量观看截图

这是一个小而有效的示例,说明了我遇到的问题。

应用类:

#pragma once

#include <QObject>
#include "Data.h"

class App : public QObject
{
   public:
      explicit App( QObject* parent = nullptr );

   public slots:
      void getData() const;

   signals:
      void dataReady( const Data& data ) const;

   private:
      Q_OBJECT
};


#include "App.h"

App::App( QObject* parent )
{
}

void App::getData() const
{
   emit dataReady( Data() );
}

数据类:

#pragma once

#include <QObject>
#include <QVariant>

#include "Stats.h"

class Data
{
   public:
      Data();
      Data( const Data& data );
      ~Data() = default;

   public slots:
      QList< QVariant > getStats() const;

   private:
      Q_GADGET
      Q_PROPERTY( QList< QVariant > stats READ getStats CONSTANT )

      QList< QVariant > stats;

      void fillStats();
};
Q_DECLARE_METATYPE(Data)


#include "Stats.h"
#include "Data.h"

Data::Data()
{
   fillStats();
}

Data::Data( const Data& data ) :
   stats{ data.stats }
{
}

void Data::fillStats()
{
   for ( int i = 0; i < 10; i++ )
      stats.append( QVariant::fromValue( Stats( i ) ) );
}

QList< QVariant > Data::getStats() const
{
   return stats;
}

统计类:

#pragma once

#include <QObject>

class Stats
{
   public:
      Stats() = default;
      Stats( int val );
      Stats( const Stats& stats );
      ~Stats() = default;

   public slots:
      int getValue() const;

   private:
      Q_GADGET
      Q_PROPERTY( int value READ getValue CONSTANT )

      int value;
};
Q_DECLARE_METATYPE(Stats)


#include "Stats.h"

Stats::Stats(const Stats& stats) :
   value{ stats.value }
{
}

Stats::Stats(int val) :
   value{ val }
{
}

int Stats::getValue() const
{
   return value;
}

main.cpp:

#include <QGuiApplication>
#include <QMetaType>
#include <QQmlApplicationEngine>

#include "App.h"
#include "Stats.h"
#include "Data.h"

int main( int argc, char* argv[] )
{
   QGuiApplication app( argc, argv );
   QQmlApplicationEngine engine;

   qRegisterMetaType< Data >( "Data" );
   qRegisterMetaType< Stats >( "Stats" );
   qmlRegisterType< App >( "Test", 1, 0, "App" );

   engine.load( QUrl( QStringLiteral( "qrc:/main.qml" ) ) );

   if (engine.rootObjects().isEmpty())
      return -1;

   return app.exec();
}

main.qml:

import QtQuick 2.6
import QtQuick.Window 2.2
import Test 1.0

Window
{
   visible: true
   width: Screen.width
   height: Screen.height
   title: qsTr("Hello World")

   Component.onCompleted: app.getData()

   App
   {
      id: app
   }

   Connections
   {
      target: app

      onDataReady: iterateThroughData( data )
   }

   function iterateThroughData( data )
   {
      for ( var i = 0; i < data.stats.length; i++ )
         console.log( "broken here... somehow gets nested." );
   }
}

现在,如果你在 main.qml 中的以下行放置一个断点:

for ( var i = 0; i < data.stats.length; i++ )

在监视窗口中,您将看到它是如何嵌套在另外两个单元素列表中的。

现在,如果我将信号更改为发出列表而不是对象,则列表完全正常且没有嵌套。

有人遇到过这种情况或看到我可能正在做的任何明显的事情吗?谢谢。抱歉代码这么多,这是我能做的最小的工作示例。

【问题讨论】:

    标签: c++ qt qml qt5 qt-signals


    【解决方案1】:

    问题是由于想用下面这行代码复制列表引起的:

    Data::Data( const Data& data ):
        stats{data.stats} 
        // Is similar to stats << data.stats or stats.append(data.stats)
    {
    }
    

    要成为stats 使用{} 时的QList,您正在添加一个项目,即现有统计数据的另一个统计数据,您必须使用copy constructor of QList

    Data::Data( const Data& data ):
        stats(data.stats)
    {
    }
    

    【讨论】:

    • 非常感谢!这解决了它。我永远不会抓住这个。
    猜你喜欢
    • 2021-12-21
    • 2020-10-20
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    相关资源
    最近更新 更多