【问题标题】:Passing QVariant from QML to C++将 QVariant 从 QML 传递到 C++
【发布时间】:2016-06-23 07:43:21
【问题描述】:

我正在尝试将列表从 QML 发送到 c++。我尝试使用字符串和整数成功,但是当我尝试使用 QVariant 时出现错误:

QObject::connect: ../test_2206/main.cpp:31 中没有这样的插槽 MyClass::cppSlot(QVariant)

我的 main.qml

import QtQuick 2.4
import QtQuick.Layouts 1.1
import Material.ListItems 0.1 as ListItem
import Material.Extras 0.1
import QtQuick.Controls 1.3 as QuickControls
import QtQuick.Controls 1.4
import Material 0.2


Window {
    visible: true
    property var listCloud: ["nuage1", "nuage2", "nuage3", "nuage4"]
        id: item
        width: 100; height: 100

        signal qmlSignal(variant msg)

       /* MouseArea {
            anchors.fill: parent
            onClicked: item.qmlSignal("Hello from QML")
        }*/
    Rectangle{
        id:sousRect
        color:"red"
        width:100; height:100
            Button{
                id:buttonTest
                onClicked: {
                     item.qmlSignal(listCloud)
                }
            }
    }

}

我的 main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QQmlComponent>
#include <QDebug>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);   
    QQmlApplicationEngine engine;

    QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml")));
    QObject *object = component.create();

        MyClass myClass;
        QObject::connect(object, SIGNAL(qmlSignal(QVariant)),
                         &myClass, SLOT(cppSlot(QVariant)));


    return app.exec();
}

我的 myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QDebug>
#include <QString>
#include <QList>



class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass(QObject *parent = 0);
signals:
public slots:
    void cppSlot(QVariant &msg);
};

#endif // MYCLASS_H

我的 myclass.cpp

#include "myclass.h"

MyClass::MyClass(QObject *parent):
    QObject(parent)
{

}
void MyClass::cppSlot(QVariant &msg){
    qDebug() << "c++: bien reçu chef " << msg;
}

我不明白为什么我不能在这个信号中加入 QVariant 参数。 欢迎任何帮助:)

【问题讨论】:

  • 您是否尝试过使用var(而不是variant):variant 类型是泛型属性类型。它已过时,仅用于支持旧应用程序;新应用程序应该使用 var 类型属性。
  • 您还想明确使用变体吗? listCloud 是一个带有字符串的列表,所以 QStringList 也可以。
  • 我想使用变体,因为我需要传递字符串列表和对象列表。你觉得我应该写property var listCloud而不是property vairant listCloud

标签: c++ qml


【解决方案1】:

更改您的插槽以通过值而不是通过引用接收他的参数。像这样:

    void cppSlot(QVariant msg);

我认为这与 QML 拒绝通过引用传递 Window 的属性有关。无论如何,Qt 经常发送信号 by-value,即使您的信号/槽签名[s] 声明了参数 by-reference。有关该主题的更多信息,请参阅 thisthat

【讨论】:

    【解决方案2】:

    不要在 QML 和 C++ 之间使用引用,它们不会起作用。

    void cppSlot(QVariant & msg);

    您还可以在 C++ 中创建 Q_INVOKABLE 函数并直接从 QML 调用它。这是它的样子:

    ma​​in.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlProperty>
    #include <QQmlComponent>
    #include <QDebug>
    #include "myclass.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);   
        QQmlApplicationEngine engine;
    
        auto myobject = new MyClass(&app);
        engine.rootContext()->setContextProperty(QStringLiteral("myobject"), myobject);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
        {
            return -1;
        }
    
        return app.exec();
    }
    

    mycass.h:

    #ifndef MYCLASS_H
    #define MYCLASS_H
    #include <QDebug>
    #include <QString>
    #include <QList>
    
    class MyClass : public QObject
    {
        Q_OBJECT
    public:
        MyClass(QObject *parent = 0);
    
        Q_INVOKABLE void cppSlot(QVariant msg);
    };
    #endif // MYCLASS_H
    

    myclass.cpp:

    #include "myclass.h"
    
    MyClass::MyClass(QObject *parent):QObject(parent){}
    
    void MyClass::cppSlot(QVariant msg)
    {
        qDebug() << "c++: bien reçu chef " << msg;
    }
    

    ma​​in.qml:

    import QtQuick 2.4
    import QtQuick.Layouts 1.1
    import Material.ListItems 0.1 as ListItem
    import Material.Extras 0.1
    import QtQuick.Controls 1.3 as QuickControls
    import QtQuick.Controls 1.4
    import Material 0.2
    
    Window 
    {
        visible: true
        property var listCloud: ["nuage1", "nuage2", "nuage3", "nuage4"]
        id: item
        width: 100; height: 100
    
        Rectangle
        {
            id:sousRect
            color:"red"
            width:100; height:100
    
            Button
            {
                id:buttonTest
                onClicked: myobject.cppSlot(listCloud)
            }
        }
    } 
    

    但如果你喜欢使用 SIGNAL SLOTS,QML 中有 Connections Object。您的 main.qml 将如下所示:

    Window 
    {
        visible: true
        property var listCloud: ["nuage1", "nuage2", "nuage3", "nuage4"]
        id: item
        width: 100; height: 100
    
        Connections
        {
            target: buttonTest
            onClicked: myobject.cppSlot(listCloud)
        }
    
        Rectangle
        {
            id:sousRect
            color:"red"
            width:100; height:100
    
            Button
            {
                id:buttonTest
            }
        }
    }
    

    Q_INVOKABLE 不是别的公共SLOT,它会通过元对象系统调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多