Как обновить qml текст из двух разных cpp? - PullRequest
0 голосов
/ 08 января 2020

У меня есть проект qml.

В StackPage.qml есть текст (с именем id: cnt), и мне нужно обновить этот текст из первого класса. cpp и второго класса. cpp.

Определения Q_PROPERTY включены Функция firstclass.h и setCntText находится в первом классе. cpp.

Я обновляю текст из первого класса. cpp с помощью setCntText (i) и пытаюсь обновить из второго класса. cpp, вызывая setCntText (0 ).

Я могу установить переменную m_cntText из второго класса, но не могу обновить текст qml (с именем id: cnt).

main. cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "firstclass.h"
#include "secondclass.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    firstClass frmFirstClass;
    engine.rootContext()->setContextProperty("frmFirstClass",&frmFirstClass);

    secondClass frmSecondClass;

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

firstclass. cpp

#include "firstclass.h"

firstClass::firstClass(QObject *parent) : QObject(parent)
{
    QTimer *timer1 = new QTimer();
    connect(timer1, &QTimer::timeout, [=]() {setter1();});
    timer1->start(2000);
}

int firstClass::cntText() const
{
    return m_cntText;
}

void firstClass::setCntText(int cntText)
{
    if (m_cntText == cntText)
        return;

    m_cntText = cntText;
    emit cntTextChanged(m_cntText);
}

void firstClass::setter1()
{
    static int i = 0;
    i++;
    qDebug() <<"counter1 : " << i;
    setCntText(i);
}

второго класса. cpp

#include "secondclass.h"

firstClass frmFirstClass;

secondClass::secondClass(QObject *parent) : QObject(parent)
{
    QTimer *timer = new QTimer();
    timer->setSingleShot(true);
    timer->start(1000);

    connect(timer, &QTimer::timeout, [=]() {
        QTimer *timer2 = new QTimer(this);
        connect(timer2,SIGNAL(timeout()),this,SLOT(setter2()));
        timer2->start(2000);
        timer->deleteLater();
    } );
}

void secondClass::setter2()
{
    frmFirstClass.setCntText(0);
    qDebug() << "Checking m_cntText = " << frmFirstClass.m_cntText;
}

firstclass.h

#ifndef FIRSTCLASS_H
#define FIRSTCLASS_H

#include <QObject>
#include <QTimer>
#include <QDebug>

class firstClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int cntText READ cntText WRITE setCntText NOTIFY cntTextChanged)


public:
    explicit firstClass(QObject *parent = nullptr);

    int cntText() const;

    int m_cntText;

signals:

    void cntTextChanged(int cntText);

public slots:

    void setCntText(int cntText);

private slots:

    void setter1();
};

#endif // FIRSTCLASS_H

secondclass.h

#ifndef SECONDCLASS_H
#define SECONDCLASS_H

#include <QObject>
#include <QTimer>
#include <QDebug>
#include "firstclass.h"

extern firstClass frmFirstClass;

class secondClass : public QObject
{
    Q_OBJECT

private:

public:
    explicit secondClass(QObject *parent = nullptr);

signals:

public slots:

private slots:

    void setter2();
};

#endif // SECONDCLASS_H

main.qml

import QtQuick 2.10
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle{
        anchors.fill: parent
        color: "black"

        StackView{
            anchors.fill: parent
            initialItem : stackPage
        }

        Component{
            id:stackPage
            StackPage{}
        }
    }
}

StackPage.qml

import QtQuick 2.0

Item {

    Rectangle{
        anchors.centerIn: parent
        width: 200
        height: 200
        color: "orange"

        Text {
            id: cnt
            text: frmFirstClass.cntText
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            font.pointSize: 40
            anchors.fill: parent
        }

    }

}

1 Ответ

1 голос
/ 08 января 2020

Ваше использование extern не завершено, поэтому вы фактически создаете два экземпляра firstClass. Поскольку extern немного вводит в заблуждение в poitns, я предлагаю вам указать указатель на "100% *" при создании secondClass (в основном). Это также дает коду лучшее представление предполагаемой иерархии.

Обновите следующие файлы:

secondClass.h

#include "firstClass.h"

class secondClass : public QObject
{
    Q_OBJECT

    private:

    public:
        explicit secondClass(firstClass *theFirstClass, QObject *parent = nullptr);

    signals:

    public slots:

    private slots:

        void setter2();

    private:
        firstClass *myFirstClass_ = nullptr;
};

secondClass. cpp

#include "secondclass.h"

secondClass::secondClass(firstClass *theFirstClass, QObject *parent) 
    : QObject(parent)
    , myFirstClass(theFirstClass)
{
    QTimer *timer = new QTimer();
    timer->setSingleShot(true);
    timer->start(1000);

    connect(timer, &QTimer::timeout, [=]() {
        QTimer *timer2 = new QTimer(this);
        connect(timer2,SIGNAL(timeout()),this,SLOT(setter2()));
        timer2->start(2000);
        timer->deleteLater();
    } );
}

void secondClass::setter2()
{
    myFirstClass->setCntText(0);
    qDebug() << "Checking m_cntText = " << myFirstClass->m_cntText;
}

main. cpp

int main(int argc, char *argv[])
{
    ...

    firstClass frmFirstClass;
    engine.rootContext()->setContextProperty("frmFirstClass", &frmFirstClass);

    secondClass frmSecondClass(&frmFirstClass);

    ...
}

Отказ от ответственности: я не пытался скомпилировать

...