qml与c++信号槽的交互

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:52   1406   0

qml接收c++信号

在qml代码中接收信号时,不需要再写槽函数,直接在目标信号前加on即可。如发送过来的信号为nameChanged(const QString &name),则在qml中这样写即可:

// 针对于类名中
TestData {     // qmlRegisterType注册的类名
        id: testData;
        onNameChanged: {
        // 需要执行的操作
        console.log("Received the signal: " + name);
    }
}
// 针对于实例化后的对象
Connections {
        target: testData
        onNameChanged: {
        // 需要执行的操作
        console.log("Received the signal: " + name)
    }
}

示例代码如下:

#include <QObject>
#include <QDateTime>

class testObject : public QObject
{
    Q_OBJECT
    // 注册属性,通过Q_PROPERTY注册到元对象系统
    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
public:
    testObject(QObject *parent = Q_NULLPTR)
    {

    };
    ~testObject() { };

    void setName(const QString &name)
    {
        m_name = name;
        emit nameChanged(name);
    }

    QString getName()
    {
        return m_name;
    }

signals:
    void nameChanged(const QString name);

private:
    QString m_name = "Initial Text";
};
#include "widget.h"
#include "ui_widget.h"
#include "testObject.h"

#include <QQmlContext>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    qmlRegisterType<testObject>("com.qt.testcomponent", 1, 0, "TestData");

    ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->quickWidget->setSource(QUrl("qrc:/main.qml"));
}

Widget::~Widget()
{
    delete ui;
}
import QtQuick 2.9

import com.qt.testcomponent 1.0

Item {
    visible: true
    width: 640
    height: 480

    Rectangle {
        id: bg1;
        width: parent.width;
        height: 50;
        radius: height / 8;
        color: "blue";
        anchors.top: parent.top;

        Text {
            id: namer;
            text: testData.name;
            font.pixelSize: 30
            anchors.centerIn: bg1;
        }

        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {
                if(mouse.button === Qt.LeftButton){
                    testData.name = "Mouse Clicked!";
                    console.log(testData.name);
                }
            }
        }
        // 针对于实例化后的对象
        Connections {
            target: testData
            onNameChanged: {
                console.log("Received the signal: " + name)
            }
        }
    }

    // 针对于类名中
    TestData {
        id: testData;
        onNameChanged: {
            console.log("Received the signal: " + name);
        }
    }
}

c++接收qml信号

(testObject.h并未改变,参照上文即可)

#include "widget.h"
#include "ui_widget.h"
#include "testObject.h"

#include <QQmlContext>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    qmlRegisterType<testObject>("com.qt.testcomponent", 1, 0, "TestData");

    ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
    ui->quickWidget->setSource(QUrl("qrc:/main.qml"));
    // QML使用arg()函数扩展了JavaScript String类型,以支持值替换;
    // 与C++集成时,从C++传递到QML的任何QString值都会自动转换为string,反之亦然;
    connect((QObject*)ui->quickWidget->rootObject(), SIGNAL(qmlSignal(QString)), this, SLOT(recQmlSignal(QString)));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::recQmlSignal(QString text)
{
    qDebug() << "Received the qml signal: " + text << endl;
}
import QtQuick 2.9

import com.qt.testcomponent 1.0

Item {
    visible: true
    width: 640
    height: 480

    signal qmlSignal(string text)

    Rectangle {
        id: bg1;
        width: parent.width;
        height: 50;
        radius: height / 8;
        color: "blue";
        anchors.top: parent.top;

        Text {
            id: namer;
            text: testData.name;
            font.pixelSize: 30
            anchors.centerIn: bg1;
        }

        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {
                if(mouse.button === Qt.LeftButton){
                    testData.name = "Mouse Clicked!";
                    qmlSignal(testData.name);
                }
            }
        }

    TestData {
        id: testData;
    }
}

其他

c++调用qml中函数

QMetaObject::invokeMethod((QObject*)ui->quickWidget->rootObject(), "qml中的函数名");

qml中的信号触发qml的函数

Component.onCompleted:    // 相当于qml中的构造函数,一般用以初始化
{
    qmlSignal.connect(qmlFunction);
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP