Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;Qt中QML插槽的信号 < >我想把一个C++的信号发送到QML文件中的一个槽中。 我已经让它在没有和基元类型参数的情况下工作,尽管如果我想向我的QML插槽发送QString,我在连接时会出错_C++_Qt_Qml_Signals Slots - Fatal编程技术网

C++;Qt中QML插槽的信号 < >我想把一个C++的信号发送到QML文件中的一个槽中。 我已经让它在没有和基元类型参数的情况下工作,尽管如果我想向我的QML插槽发送QString,我在连接时会出错

C++;Qt中QML插槽的信号 < >我想把一个C++的信号发送到QML文件中的一个槽中。 我已经让它在没有和基元类型参数的情况下工作,尽管如果我想向我的QML插槽发送QString,我在连接时会出错,c++,qt,qml,signals-slots,C++,Qt,Qml,Signals Slots,我在main.cpp中连接 QObject *contentView = rootObject->findChild<QObject*>(QString("contentView")); QObject::connect(&myObj, SIGNAL(finishedGatheringDataForItem(QString)), contentView, SLOT(updateViewWithItem(QString)));

我在main.cpp中连接

QObject *contentView = rootObject->findChild<QObject*>(QString("contentView"));
QObject::connect(&myObj,      SIGNAL(finishedGatheringDataForItem(QString)), 
                 contentView, SLOT(updateViewWithItem(QString)));
错误:

Object::connect: No such slot QDeclarativeRectangle_QML_2::updateViewWithItem(QString)

我认为最好查看本教程:

特别是本节:

我认为你在这个案例中的错误可能是你没有将它声明为插槽,或者你没有使它成为发票。这两个选项在Qt教程中都有说明

还需要使用QFAXT来交换C++与QML之间的数据。 您还可以注册类型,例如小部件和其他东西,以便在QML中将它们作为“本机”类型(如矩形)使用。在大多数情况下,不建议这样做,除非您需要某些外部类或某些无法在QML接口中显示的数据

QVariant的原因是QML基于脚本的方法。QVariant基本上包含您的数据和数据类型的描述,以便QML知道如何正确处理它。这就是为什么必须在QML中用String、int等指定参数。。但与C++的原始数据交换仍然是q变体< /p> 我以前使用过qmlRegisterType,但是对于简单的数据类型来说,它是一个非常不方便的解决方案。它更适合用于更复杂的数据,如定制小部件、画布或视频元素,QML本机不支持或扩展
QStandardItemModels
。它是一种更方便的方法,在QML和C++之间交换数据,不需要在第一个实例中使用信号或时隙,因为QStaleReTimeMeod自动更新GUI。要使用QStandardItemModel,您需要向qmlRegisterType注册类型。然后可以在基于模型的视图(如ListView等)中使用该模型

我为这个主题附上了一个教程,它描述了如何使用QListModel

在这种情况下,您应该使用(可能这是连接的唯一方式)

  • 通过
    setContextProperty

    qmlVectorForm->rootContext()->setContextProperty("YourObject", myOb);
    
  • 你的信号是

    finishedGatheringDataForItem(QString signalString)
    
  • 在QML文件中,添加如下连接:

    Connections {
        target: YourObject 
        onFinishedGatheringDataForItem: {
            qmlString = signalString
        }
    }
    

  • 无连接的解决方案和任何上下文都不是通过连接信号插槽,而是通过连接信号插槽。建立 示例代码如下所示

    qml:

    后台类的头文件包含

    public signals:
        void cppSend(QString textOut);
    public slots:
        void cppReceive(QString textIn);
    
    main.cpp通过以下方式连接它们:

    1.从qml到cpp:

    QObject::connect(qmlRootObject, SIGNAL(qmlSend(QString)),
                    backgroundObject, SLOT(cppReceive(QString)));
    
    2.从cpp到qml:

    QObject::connect(backgroundObject, SIGNAL(cppSend(QString)),
                     qmlRootObject, SIGNAL(qmlReceive(QString)));
    

    为什么不使用rootContext呢

    在C++方面,你有:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    //--------------------------------------------------------
    #include <myClass.h>
    //--------------------------------------------------------
    
    int main(int argc, char *argv[])
    {
    
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        //--------------------------------------------------------
        myClass * myobj = new myClass(&app);
        //--------------------------------------------------------
    
        //--------------------------------------------------------
        engine.rootContext()->setContextProperty("myobj",myobj);
        //--------------------------------------------------------
    
        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();
    }
    
    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        //--------------------------------------------------------
        Component.onCompleted: {
           myobj.onSomeSignal.connect(signalHandling) 
        }
        //--------------------------------------------------------
    
        //--------------------------------------------------------
        function signalHandling(){
           console.log("Signal emitted from c++ side")
        }
        //--------------------------------------------------------
    }
    
    

    我已经尝试了很多解决方案来成功地从一个C++信号中更新QML,但是很多都没有用。 这个解决方案是有效的,并且已经过测试,它基于这个答案:(作者@Adriano Campos)

    <>你可以用信号发送C++到QML,比如:

    main.cpp:

    #include <QQmlContext>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        // Class init
        YourClass yourObject;
    
        // Embedding C++ Objects into QML with Context Properties
        QQmlContext* ctx = engine.rootContext();
        ctx->setContextProperty("yourObject", &yourObject);
    
        return app.exec();
    }
    
    yourClass.h:

    class YourClass : public QObject
    {
    Q_OBJECT
    signals:
        // Signal from YourClass
        void signalData(QString signal_param);
    }
    
    yourClass.cpp:

    emit signalData("Hello QML"); // Signal from yourClass
    

    一个完整的教程,关于如何将带有QT的信号和时隙的QT C++类公开到这个页面上:

    您的UpDeVIEWWWITH项中没有QStand参数吗?(错误指出)抱歉,测试后忘记再次添加。但仍然不起作用。我尝试了UpDeVIEWWWEY(QString)和UpDeVeWiWiWiWiTew(String)。C++的信号意味着C++库或Qt类??谢谢,这个Q/A真的帮助了我。作为将来的参考,这里有一个很好的例子:我在这里不使用QDeclarativeView子类。正如我在我的问题中指出的,如果我不考虑参数,一切都会起作用。我必须以某种方式将QString引入我的QML吗?在这种情况下,尝试使用QVariant。我有几次遇到这个问题,QML不能识别QVariant以外的其他数据类型。嘿,这为我解决了这个问题!仍然在想是否有更好的解决方案。有没有试过使用qmlRegisterType?我刚刚更新了上面的回复。如果足够,请将其标记为答案。QML文件中的何处?当以高频或大量交换数据时,这可能会导致UI延迟。请确保信号插槽不总是具有良好的性能。所以为了优化,您应该在通过信号发送数据之前对其进行处理。在某些情况下,如果在两个线程之间连接,plz注意到不要以如此高的速率发送信号,这将导致UI卡住。您应该建立一种机制来控制发送频率(可能使用定时器或延迟)@HorusKol将
    连接
    对象放在应该接收连接的QML组件中。它通常是根组件。看到例子我仍然无法使用的主要区别是QML的方式做这件事和良好的旧C++代码。基本上,插槽是在内部生成的,无需手动定义(因为在QML中,插槽基本上是
    信号
    偏差的一个侧面特征)。
    import QtQuick 2.6
    
    Window {
        id: mainWindow
    
        Connections {
            target: yourObject
            onSignalData: {
                console.log("Data: " + signal_param)
                textToChange.text = "Changed to: " + signal_param
            }
        }
    
        Text {
            id: textToChange
            text: "beforeChange"
        }
    }
    
    class YourClass : public QObject
    {
    Q_OBJECT
    signals:
        // Signal from YourClass
        void signalData(QString signal_param);
    }
    
    emit signalData("Hello QML"); // Signal from yourClass