如何从两个不同的 cpp 更新 qml 文本?

How to update qml text from two different cpp?

我有一个 qml 项目。

StackPage.qml 上有一个文本(名为 id:cnt),我需要从 firstclass.cpp 和 secondclass.cpp 更新此文本。

Q_PROPERTY 定义在 firstclass.h 上,setCntText 函数在 firstclass.cpp.

我通过 setCntText(i) 从 firstclass.cpp 更新文本,并尝试通过调用 setCntText(0) 从 secondclass.cpp 更新文本。

我可以从 secondclass 设置 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);
}

secondclass.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
        }

    }

}

您的 extern 用法不完整,因此您实际上创建了 firstClass 的两个实例。由于 extern 在点上有点误导,我建议您在创建 secondClass 时(在 main 中)给出指向 "one-and-only" firstClass 的指针。这也使代码能够更好地表示预期的层次结构。

更新以下文件:

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);

    ...
}

免责声明:我没有尝试编译这个