【问题标题】:Calling a QML function from C++从 C++ 调用 QML 函数
【发布时间】:2013-11-28 19:08:28
【问题描述】:

我正在使用 BB Native SDK 开发一个 Blackberry 10 移动应用程序。

我需要在我的 C++ 类中调用一个 QML 函数。我对此进行了很多搜索,但我只发现将 C++ 调用到 QML 而不是相反的可能性。你可以检查这个:QML and C++ integration

谁能帮我解决这个问题?

这是指定我需要调用的函数的 QML 代码,该函数将标记添加到我的地图视图中:

Container {
    id: pinContainer
    objectName: "pinContObject"
        ...

        function addPin(lat, lon, name, address) {
            var marker = pin.createObject();
            marker.lat = lat;
            marker.lon = lon;
            ...
        }
}

【问题讨论】:

    标签: qt mobile blackberry qml blackberry-10


    【解决方案1】:

    这就是信号和插槽的用途。 您可以使用 QML Connections 将任意信号连接到 QML 中的任意插槽。

    http://qt-project.org/doc/qt-4.8/qml-connections.html

      Container {
                id: pinContainer
                objectName: "pinContObject"
                ...
    
                function addPin(lat, lon, name, address) {
                    var marker = pin.createObject();
                    marker.lat = lat;
                    marker.lon = lon;
                    ...
                }
    
                Connections {
                    target: backend
                    onDoAddPin: { 
                      addPin(latitude, longitude,name, address)
                    }
                }
         }
    

    而在 C++ 后端,您所要做的就是

    class Backend: public QObject {
    signals:
        void doAddPin(float latitude, float longitude, QString name, QString address);
    
     ........
     void callAddPinInQML(){
         emit doAddPin( 12.34, 45.67, "hello", "world");
     }
    }
    

    【讨论】:

    • 非常感谢您的回答!!!但是如何在c++中传递参数并将其影响到qml函数参数?
    • 更新了传递函数参数的例子。信号。如果变量与信号的函数参数存在任何命名空间冲突,则适用 javascript 函数/变量范围规则。祝你好运:)
    • 谢谢 ^_^ !!但不幸的是,当我尝试在我的 BB 设备中运行应用程序时,它不想加载;我查了一下,发现在QML文件中添加connection property的时候有问题。我真的很困惑:/
    【解决方案2】:

    MyItem.qml

    import QtQuick 2.0
      Item {
        function myQmlFunction(msg) {
          console.log("Got message:", msg)
          return "some return value"
      }
    }
    

    main.cpp

    QQmlEngine engine;
    QQmlComponent component(&engine, "MyItem.qml");
    QObject *object = component.create();
    
    QVariant returnedValue;
    QVariant msg = "Hello from C++";
    QMetaObject::invokeMethod(object, "myQmlFunction",
        Q_RETURN_ARG(QVariant, returnedValue),
        Q_ARG(QVariant, msg));
    
    qDebug() << "QML function returned:" << returnedValue.toString();
    delete object;
    

    这应该有效。这里我从我的 C++ 类中调用一个 QML 函数。

    【讨论】:

    • 这正是可以在 Qt 文档中找到的代码:[doc.qt.io/qt-5/…
    • Qt 的文档已经足够好,但人们没有时间阅读它们。他们很快需要我提供的具体信息。
    • 不过,您仍然应该给予学分。甚至提供文档的链接
    【解决方案3】:

    来自 Qt 文档:

    http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#invoking-qml-methods

    调用QMetaObject::invokeMethod 将调用正确的槽,无论它是用C++ 还是QML 定义的。

    【讨论】:

      【解决方案4】:

      还有另一种使用绑定的方式,当某个x值的值在Cpp端发生变化并且它被绑定到qml端时,onchange会在qml端被调用。这个解决方案比here 注意到的连接信号到信号更容易和更直接,但是如果你想在信号内传输数据,我建议使用信号信号连接

      例如:

      qml 端

          import com.drOmranConsulting.backend 1.0
      
          BackEnd {
              id: _backend
          }
      
      Page1Form {
           objectName: "page1box"
      
              /* property alias recchange: _backend.rec_x
                 signal rec_xChanged is transmitted from C++
                 when rec_x is newly set. To receive this signal
                 an alias is used in qml side to the value rec_x
                 the binding will be updated upon signal emitting
              */
              property alias recXchange: _backend.rec_x
      
          onRecXchangeChanged:
              {
                 console.log("signal received")
                 console.log(" the x coordinate is changed on cpp side to " + _backend.getRecX() )
                 _rect.x=_backend.getRecX()
              }
           }
      

      后端.h

      signals:
          void rec_xChanged();            /* cpp emits signal rec_xChanged             */
                                          /* when rec_x value has been changed         */
                                          /* in QML: value is aliased using            */
                                          /* property alias recchange: _backend.rec_x  */
                                          /* detecing signal at onRecchangeChanged     */
      

      在 main.cpp 中

      //Backend class Initialization
      backend Backend;
      qmlRegisterType<backend>("com.drOmranConsulting.backend",1,0,"BackEnd");
      

      在后端.cpp中

      emit rec_xChanged();
      

      【讨论】:

        猜你喜欢
        • 2015-09-27
        • 2021-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 2020-07-09
        相关资源
        最近更新 更多