QML端未捕获C ++信号

时间:2018-08-24 06:52:08

标签: c++ qt qml

我想通过 QQuickWidget 在基于窗口小部件的应用程序中使用一些QtQuick表单。我介绍了一个C ++类 BackEnd ,并尝试将其与qml连接。

基本上,该显示是文件路径选择器,带有说明文本,用于显示/编辑路径的文本字段以及用于打开经典打开文件对话框的按钮。作为C ++和QML之间的交互,我需要:

  • 在启动时,从C ++到QML的信号会填充QML文本字段中的现有路径。 (信号BackEnd :: setBlockTypePath)
  • 按下QML按钮时,触发C ++操作以打开文件对话框(Q_INVOKABLE BackEnd :: chooseBlockTypeDefinitionPath())

这是我的代码的最低运行版本:

  • Main.cpp创建一个QMainwindow,创建一个QQuickWidget并设置 到主窗口

    #include <QMainWindow>
    #include <QApplication>
    #include <QQuickWidget>
    #include <QQmlContext>
    #include "configbackend.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QMainWindow w;
        w.resize(450,80);
        w.setWindowTitle("test QML C++ backend");
        w.show();
    
        QQuickWidget *pQuickWidget = new QQuickWidget(&w);
        pQuickWidget->setSource(QUrl(QString("../cpp_qml/ConfigWdt.qml")));
        pQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    
        ConfigBackEnd *pConfigBackEnd = new ConfigBackEnd();
        pQuickWidget->rootContext()->setContextProperty("backend",    pConfigBackEnd);
    
        w.setCentralWidget(pQuickWidget);
    
        return a.exec();
    }
    
  • BackEnd类,它处理C ++中的逻辑

    backend.cpp:
    #include "configbackend.h"
    #include <QDebug>
    
    ConfigBackEnd::ConfigBackEnd(QObject *pParent) : QObject(pParent)
    {
    }
    
    void ConfigBackEnd::onQMLCompleted() //slot
    {
        qDebug() << "ConfigBackEnd::onQMLCompleted()";
        emit setBlockTypePath("BlockTypePath");
    }
    void ConfigBackEnd::chooseBlockTypeDefinitionPath()
    {
        qDebug() << "ConfigBackEnd::chooseBlockTypeDefinitionPath";
    }
    
    backend.h:
    #ifndef CONFIGBACKEND_H
    #define CONFIGBACKEND_H
    
    #include <QObject>
    
    class ConfigBackEnd: public QObject
    {
        Q_OBJECT
     public:
     ConfigBackEnd(QObject *pParent = nullptr);
     Q_INVOKABLE void onQMLCompleted();
     Q_INVOKABLE void chooseBlockTypeDefinitionPath();
     signals:
     void setBlockTypePath(const QString &rPath);
    };
    #endif // CONFIGBACKEND_H
    
  • 最后是ConfigWdt.qml

    import QtQuick 2.4
    import QtQuick.Controls 2.2
    
    Item {
        id: main
    
        Component.onCompleted:{
             backend.onQMLCompleted(); // NOT DEFINED!
        }
    
        Connections{
            target: backend   // NOT DEFINED!
    
            onSetBlockTypePath:{
                blockTypePathPb.text = rPath;
            }
        }
    
        Row{
            spacing:30
            Text {
                id: text2
                text: qsTr("my path:")
                font.pixelSize: 16
         }
    
         TextField {
            id: blockTypePathTxt
            text: qsTr("")
            font.pixelSize: 12
         }
    
         Button {
             id: blockTypePathPb
             text: qsTr("...")
             onClicked:{
                 backend.chooseBlockTypeDefinitionPath(); //THIS ONE IS OK...
         }
        }
      } //Row
     }
    
在QML中,从未捕获到

用于填充文本字段的 setBlockTypePath 信号。

以前,我曾尝试在 BackEnd 构造函数中发出它,我认为QML尚未准备好接收它,因此,我试图等待QML完成以通过 backend发出信号。 .onCompleted ,仅在QML完成时调用。没有变化。

实际上,问题出现在启动时的应用程序输出中,说:

  

ReferenceError:未定义后端

onQMLCompleted 调用和“连接”目标中,

给出2个首次出现的QML文件行。

奇怪的是,在单击Button的第三次后端外观正常,并且可以正常工作。按下按钮将调用 ConfigBackEnd :: chooseBlockTypeDefinitionPath

对此有任何提示吗?谢谢,

0 个答案:

没有答案