如何从 Qml Checkbox 获取初始值到 C++?

How get the initial value from Qml Checkbox to c++?

我有 qtquick 前端和 c++ 后端。在 Qml 中,我有一个带有随机初始值的复选框。我在 onCheckedChanged 发出了一个从未收到过的信号。我相信,这是因为组件是在创建连接语句之前创建的。当用户交互时,我可以捕捉到这些事件,但我错过了初始值。我无法尽快建立连接,因为 QMl 引擎必须首先创建组件,这样我才能引用它们来建立信号槽连接。那么如何找出初始值呢?我是否必须制作一个计时器,它会在启动后几秒钟发出值?有没有更好的方法?

这里是最小的例子(当初始值为真时,插槽永远不会被触发)

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    signal checkboxStateChanged(enabled: bool)
    CheckBox{
        checked: Math.random() > 0.5
        text: "value"
        onCheckedChanged: checkboxStateChanged(checked)
    }
}

backend.h

#include <QObject>
#include <QDebug>
class Backend: public QObject{
    Q_OBJECT
public:
    Backend(){}
public slots:
    void logChecked(bool checked){
        qDebug()<<checked;
    }
};

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>
#include "backend.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    const auto root=engine.rootObjects();
    QObject *window = root[0];
    Backend b;
    QObject::connect(window,SIGNAL(checkboxStateChanged(bool)),
                     &b,SLOT(logChecked(bool)));
    return app.exec();
}

我不确定您正在尝试的方法,但更简洁的方法是将 QML 检查值绑定到 c++ class。然后你可以在你的后端处理所有事情 class 这更容易调试和维护。所以使用你的例子,

#include <QObject>
#include <QDebug>
class Backend: public QObject{
    Q_OBJECT
    // Add a Q_PROPERTY to bind in QML
    Q_PROPERY(Qt::CheckState checked READ getChecked WRITE setChecked NOTIFY checkedChanged)
signals:
    void checkedChanged();
public:
    Backend() { m_checked = <random_value>;}

    // implement the q_property methods
    void setChecked(const Qt::CheckState value) {
        if (m_checked != value) {
             m_checked = value;
             emit checkedChanged();
        }
    }
    Qt::CheckState getChecked() const { return m_checked; }
public slots:
    void logChecked(bool checked){
        qDebug()<<checked;
    }

private:
   m_checked;
};

然后在 QML 中:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQml 2.12 // Binding
import Backend 1.0

ApplicationWindow {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    signal checkboxStateChanged(enabled: bool)
    
    CheckBox{
        id: qmlCheckBox
        checked: backend.checked // C++ to QML binding
        text: "value" // you can bind this too
    }

    // QML to C++ binding
    Binding {
        target: backend
        property: "checked"
        value: qmlCheckBox.checked
    }
}

在main.cpp中:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>
#include "backend.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    // Register backend class for qml
    qmlRegisterType<Backend>("Backend", 1, 0, "Backend");
    engine.rootContext()->setContextProperty("backend", new Backend);


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    
    return app.exec();
}