在 C++ 中从 QML 读取值

Posted

技术标签:

【中文标题】在 C++ 中从 QML 读取值【英文标题】:Reading value from QML in C++ 【发布时间】:2020-02-18 08:21:22 【问题描述】:

我正在尝试从c++ 上的QML 一侧读取int value,但该值仍然是0 并且不会在c++ 一侧更新,而console.log() 清楚地告诉我它在之后递增每次点击。我在这里做错了什么?

.qml 文件

FocusScope 

        property alias myrecordint: startbutton.recordint

        Rectangle 
            id: buttonPaneShadow
            width: bottomColumn.width + 16
            height: parent.height
            anchors.top: parent.top
            anchors.right: parent.right
            color: "white"

            Column 
                anchors 
                    right: parent.right
                    top: parent.top
                    margins: 8
                

                id: buttonsColumn
                anchors.rightMargin: 20
                anchors.topMargin: 20
                spacing: 12

                CameraButton 
                    id: startbutton
                    property int recordint:0
                    text: "Record"
                    visible: camera.videoRecorder.recorderStatus == CameraRecorder.LoadedStatus
                    onClicked:
                    
                        recordint=recordint+1
                        camera.videoRecorder.record()
                        console.log(recordint)

                    
                
           
      
 

.cpp 文件

   QQmlEngine engine;
   QQmlComponent component(&engine, QUrl("qrc:/VideoCaptureControls.qml"));
   QObject *object = component.create();
   qDebug() << "Property value:" << QQmlProperty::read(object, "myrecordint").toInt();

【问题讨论】:

将 c++ 暴露给 qml 是一种非常糟糕的方式,反之亦然。 Qt 已经提供了一种将您的 c++ 类与 qml 对象连接起来的方法,请在开发应用程序之前阅读此处doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html @arnes 非常感谢你,我一定会通过那个链接!我在 QML 方面没有太多经验,但这有帮助! 不客气,如果你卡在某个地方,你可以看看例子doc.qt.io/qt-5/qmlextendingexamples.html doc.qt.io/qt-5/qtqml-referenceexamples-adding-example.html 实际上这个例子展示了如何做到这一点。声明和定义 Person 类。在 main.cpp 之后,在调用 engine.load( "your_qml.qml" ) 之前,添加这段代码,qmlRegisterType&lt;Person&gt;( "your_module_name" , 1 /*major version of your module*/ , 2 /*minor version of your module*/ , "Person" /*Qml type name*/ );,这样它就告诉 qml 引擎将 Person 类暴露给 qml 端。您可以访问您的属性,也可以从 qml 端调用 public slots: 函数 @arnes 好的!非常感谢!我会玩,看看我能不能成功! 【参考方案1】:

编辑

在来回评论之后,您似乎没有使用您应该使用的实例,因为您是在单击按钮时创建一个新实例。

此外,属性的读取是一次性执行的,不会自动更新。

总而言之,这是一个经典的 XY problem,您应该努力使用 Arnes 指出的 C++ 模型(example 1 和 example 2)

原始答案(错误,因为属性 是***的)

您只能从 QML 对象的顶层读取属性(从对象外部读取时)。您应该按照以下建议移动该属性:

Rectangle 
        id: buttonPaneShadow
        width: bottomColumn.width + 16
        height: parent.height
        anchors.top: parent.top
        anchors.right: parent.right
        color: "white"

        property int recordint:0 //move to here

        Column 
            anchors 
                right: parent.right
                top: parent.top
                margins: 8
            

            id: buttonsColumn
            anchors.rightMargin: 20
            anchors.topMargin: 20
            spacing: 12

            CameraButton 
                id: startbutton
                text: "Record"
                visible: camera.videoRecorder.recorderStatus == CameraRecorder.LoadedStatus
                onClicked:
                
                    recordint=recordint+1
                    camera.videoRecorder.record()
                    console.log(recordint)

                
            
    

就个人而言,我不喜欢您似乎实现这一点的方式。我宁愿选择具有可更新属性的 C++ 模型,但这取决于你

【讨论】:

如果问的不是太多,您是否也请给我这样一个c++模型的参考?就我个人而言,我不喜欢我选择的方法,或者我只是这样做,因为我不知道其他方法:) @Raad 我看到你已经得到了关于 C++ 模型的提示。回答您的另一个问题:您的属性不是 qml 文件的顶层(假设这是您在附加的 .cpp 文件中加载的那个),因为它位于您的 qml 文件创建的组件之一中 @Raad 那么这很有趣......除了使用 C++ 模型的建议之外,我想了解为什么这会失败,因为它实际上不应该。你能告诉你什么时候在 C++ 代码中读取属性吗? (在.cpp sn-p中加载后连续或仅一次) 这意味着您每次点击都会创建一个新的VideoCaptureControls?在这种情况下,难怪你总是读 0,你绝对应该遵循 C++ 模型路线;-) 这是一次性执行,是的,但很可能您没有读取您认为应该读取的值(我假设您有一个正在运行的 qml gui,并且每次都在创建一个不可见的对象你点击你的QPushButton)。关于可能性:您可能有机会获得更改后的信号,以便您可以读取新值,或者您可以基于 QTimer 执行此操作,但实际上:不要 ;-) 【参考方案2】:

这里是从 c 读取 qml 数据的代码示例

QObject *rootObject = engine.rootObjects().first();
QObject *pageOne = rootObject->findChild<QObject*>("page1box");

//calling qml function from c
QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(pageOne, "myQmlFunction",
    Q_RETURN_ARG(QVariant, returnedValue),
    Q_ARG(QVariant, msg));
qDebug() << "QML function returned:" << returnedValue.toString();

【讨论】:

以上是关于在 C++ 中从 QML 读取值的主要内容,如果未能解决你的问题,请参考以下文章

在 Qml 中从字节数组加载到图像

有没有办法在 qml 中从网上下载图像

QML:如何从 C++ 中读取 QList

为啥在 C++ 中从标准输入读取行比 Python 慢得多?

为啥在 C++ 中从标准输入读取行比 Python 慢得多?

在opencv(C++)中从caffe读取多维数组