为什么我不能从QML中读取公开的C ++数据?

时间:2019-01-22 10:51:27

标签: c++ qt properties qml

我制作了此类,将其用作数据容器。我从json中读取了一些数据(在c ++中),并填充了存储在dataHandler的m_guiAreas列表中的GUIArea列表。在QML的某个点上,我向dataHandler请求了一系列selectedAreas。 DataHandler填充QList m_selectedGuiAreas并发出selectedAreasChanged()信号。现在,我希望设置一个由所选数据填充的矩形网格,但是什么也看不到。 在C ++级别上,当发出selectedAreasChanged()时,m_selectedGuiAreas结果填充了正确的数据,但在QML级别上,它似乎为空,或者可能是未正确读取数据。

这是我用作包装将数据带入QML级别的类:

class GUIArea : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString id READ id )
        Q_PROPERTY(QString configurations READ configurations )

        ...

    public:
        explicit GUIArea(QObject *parent = nullptr): QObject (parent) {}

        QString id() {return m_id;}
        void id(QString newId) {m_id = newId;}

        QString configurations() {return m_configuration; }
        void configurations(QString newConfiguration) {m_configuration = newConfiguration;}

        ...

    private:
        QString m_id;
        QString m_configuration;
    };

下面是dataHandler类,在该类中声明从Json读取的数据列表,并将其从Qlist转换为QQmlPropertyList(我在一些QML指南中看到了将c ++属性公开给QML的信息)。 方法initializeDatas读取存储在m_GUIAreas中的数据,然后选择要发送到m_selectedGUIAreas中的QML的数据,最后发出信号selectedGUIAsChanged()。

class dataHandler : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QQmlListProperty<GUIArea> selectedGuiAreas READ selectedGuiAreas NOTIFY selectedAreasChanged)

public:
    explicit dataHandler(QObject *parent = nullptr);
    static dataHandler* instance();

    QQmlListProperty<GUIArea> selectedGuiAreas();
    ...

public slots:
        void initializeDatas(const json& blocksList);
    ... 

signals:
    ...
    void selectedAreasChanged();
    ...
private:   
    ... 
    QList<GUIArea *> m_guiAreas;
    QList<GUIArea *> m_selectedGuiAreas;
};

在主文件中,然后将dataHandler声明为属性: 这是代码:

  QQuickView view;
  ...
  view.engine()->rootContext()->setContextProperty("dataHandler", dataHandler::instance());
  ...
  view.show();

我想在QML中可视化的页面的一部分在下面。 AreaButton是Text中的一个Rectangle和属性text的别名。

Grid {
    id: areasButtonsGrid
    columns: 4
    anchors.fill: parent

    Repeater {
        model: dataHandler.selectedGuiAreas
        delegate:
            AreaButton {
                text: qsTr(model.modelData.programName)
            }
    }
}

1 个答案:

答案 0 :(得分:0)

由于代码不完整,因此无法进行分析,因此我将提供一个有效的代码,以便您分析问题出在哪里:

main.cpp

#include <QGuiApplication>
#include <QQmlContext>
#include <QQuickView>
#include <QTimer>

class GUIArea : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString id READ id  CONSTANT)
    Q_PROPERTY(QString configurations READ configurations CONSTANT)
public:
    GUIArea(const QString & id="", const QString & configurations="", QObject *parent=nullptr):
        QObject(parent), m_id(id), m_configurations(configurations)
    {}
    QString id() const{return m_id;}
    QString configurations() const{return m_configurations;}
    void setId(const QString &id){
        m_id = id;
    }
    void setConfigurations(const QString &configurations){
        m_configurations = configurations;
    }
private:
    QString m_id;
    QString m_configurations;
};

class DataHandler: public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<GUIArea> selectedGuiAreas READ selectedGuiAreas NOTIFY selectedAreasChanged)
    using QObject::QObject;
public:
    static DataHandler& instance(){
        static DataHandler handler;
        return handler;
    }
    QQmlListProperty<GUIArea> selectedGuiAreas(){
        return QQmlListProperty<GUIArea>(this, m_selectedGuiAreas);
    }
    void append(GUIArea *area){
        if(area){
            m_selectedGuiAreas << area;
            emit selectedAreasChanged();
        }
    }
signals:
    void selectedAreasChanged();
private:
    QList<GUIArea *> m_selectedGuiAreas;
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    qmlRegisterType<GUIArea>();
    QQuickView view;
    view.rootContext()->setContextProperty("dataHandler", &DataHandler::instance());
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();
    QTimer timer;
    static int counter =0;
    QObject::connect(&timer, &QTimer::timeout, [](){
        GUIArea *area = new GUIArea(QString::number(counter),
                                    QString("configuratio-%1").arg(counter),
                                    &DataHandler::instance());
        DataHandler::instance().append(area);
        counter++;
    });
    timer.start(1000);
    return app.exec();
}
#include "main.moc"

main.qml

import QtQuick 2.12

Grid {
    id: areasButtonsGrid
    columns: 5
    width: 640
    height: 480
    spacing: 20
    Repeater {
        model: dataHandler.selectedGuiAreas
        delegate:
            Rectangle{
            width: 100
            height: 100
            color: "blue"
            Text {
                anchors.fill: parent
                text: qsTr(model.modelData.configurations)
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
            }
        }
    }
}