【问题标题】:Change QML Label text from a C++ function从 C++ 函数更改 QML 标签文本
【发布时间】:2020-03-08 09:35:33
【问题描述】:

我在 QML 中有一个标签,我想在单击按钮时更改其文本值。我尝试了许多不同的方法来实现这一点,但似乎没有任何工作正常。我使用了 QObject::setProperty(),当我使用 qDebug() 打印新文本值时它似乎可以工作,但它不会在 GUI 上刷新。我究竟做错了什么?

main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSettings>
#include <QQuickStyle>
#include <QtQuickControls2>
#include <QQmlContext>
#include <QIcon>

#include "Controllers/Network/network.hpp"
#include "Controllers/NFC/nfc.hpp"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QIcon::setThemeName("gallery");
    QQuickStyle::setStyle("Material");

    // Property bindings:
    qmlRegisterType<RFS::Communication::Network>("rfs.communication.network", 1, 0, "Network");
    qmlRegisterType<RFS::Communication::NFC>("rfs.communication.nfc", 1, 0, "NFC");

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("availableStyles", QQuickStyle::availableStyles());
    engine.load(QUrl("qrc:/main.qml"));
    if (engine.rootObjects().isEmpty()) return -1;
    return app.exec();
}

nfc.hpp:

#include <QObject>
#include <QtNfc/qnearfieldmanager.h>
#include <QtNfc/qnearfieldtarget.h>

namespace RFS::Communication
{
    class NFC : public QObject
    {
        Q_OBJECT

    public:
        explicit NFC(QObject *parent = nullptr);
        Q_INVOKABLE bool getStatus() { return pairingStatus; }
        Q_INVOKABLE void changeTextValue();

    private:
        bool pairingStatus;
    };
}

nfc.cpp:

#include <QtQuick>
#include <QQuickView>
#include "Controllers/NFC/nfc.hpp"

void RFS::Communication::NFC::changeTextValue()
{
    QQuickView view;
    view.setSource(QUrl("qrc:/Views/overview.qml"));
    QObject *rootObject = view.rootObject();

    QList<QObject*> list = rootObject->findChildren<QObject*>();
    QObject *testLabel = rootObject->findChild<QObject*>("testLabel");

    qDebug() << "Object" << testLabel->property("text"); // Successfully prints old value
    testLabel->setProperty("text", "test1");
    qDebug() << "Object" << testLabel->property("text"); // Successfully prints new value
    QQmlProperty(testLabel, "text").write("test2");
    qDebug() << "Object" << testLabel->property("text"); // Successfully prints new value
}

overview.qml:

import QtQuick 2.12
import QtQuick.Controls 2.12
import rfs.communication.nfc 1.0

Page {
    id: page

    NFC {
        id: nfc
    }

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Pane {
            id: overviewTab
            width: swipeView.width
            height: swipeView.height

            Button {
                id: pairButton
                text: qsTr("Pair new receiver")

                onClicked: {
                    nfc.changeTextValue()
                }
            }

            Label {
                id: testLabel
                objectName: "testLabel"
                text: "hei" // I want to change this value
            }
        }
    }
}

有没有更好的方法来实现这一点?提前非常感谢。

【问题讨论】:

  • 嗯,我认为你的方法是错误的,除了你有一个 XY 问题。类名、变量名等。我直觉你想根据NFC对象的信息更新Label。我对么?同时显示 main.qml
  • 不要从 C++ 访问 QML,但反过来,将文本公开为 Q_PROPERTY。
  • @eyllanesc 目标是根据来自 NFC 对象的信息更新标签,是的。但现在我只想从 C++ 函数手动更新标签,而不需要与 NFC 交互。 main.qml 中没有与此问题相关的信息,它仅包含一些样式块。
  • @FrankOsterfeld 我曾尝试使用 Q_PROPERTY 但它并没有特别帮助我解决这个问题。目标是用 NFC 标签替换按钮,这将触发 C++ 函数,然后更新标签文本。

标签: c++ qt qml c++17


【解决方案1】:

任何人都在寻找一个简单的解决方案,我只是想出了这个尝试通过按下 QML 中的按钮来实现在 c++ 端更改标签的文本

添加到 main.cpp:

Backend backend;
engine.rootContext()->setContextProperty("backend", &backend);

创建一个新类(backend.h & backend.cpp)

在 backend.h 中:

#ifndef CONTROLLERS_H
#define CONTROLLERS_H

#include <Qt>
#include <QObject>
#include <QCoreApplication>
#include <QWindow>
#include <QString>
    class Backend : public QObject
{
    Q_OBJECT
public:
    explicit Backend(QObject *parent = nullptr);
   
public slots:
    void setText();
    QString getText();
};
#endif // CONTROLLERS_H

在 backend.cpp 中:

#include "backend.h"

QString text = ""; // don't forget this
Backend::Backend(QObject *parent) : QObject(parent)
{

}

QString Backend::getText()
{
    return text; //returns the text you set or didnt in setText()
}

void Backend::setText()
{
    text = "text"; // or do anything you want with global QString text
}

在 QML 中:

Label{
    id: myLabel
}

Button{ 
    id: myButton
    onClicked:{
        backend.setText()
        myLabel.text = backend.getText()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多