qml 信号与槽 (qml内部信号槽交互,qml与C++信号槽交互)

//MySigRect.qml

import QtQuick 2.0

Item {
    id: root

    //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
    //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
    signal mySignal    //信号定义

    Rectangle{
        id: rect
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: root.mySignal()  //点击时发送mySignal信号

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {
        id: txt
        text: qsTr("text")
    }

    MySigRect{
        y: 100

        //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
        //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
        onMySignal: {
            txt.text = "hello new text"
        }
    }

}

利用Connections的方法:

//MySigRect

import QtQuick 2.0

Item {
    id: root

    //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
    //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
    signal mySignal    //信号定义

    Rectangle{
        id: rect
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: root.mySignal()  //点击时发送mySignal信号

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {
        id: txt
        text: qsTr("text")

        //在目标组件里设置定义槽,需要指定id
        Connections{
            target: m_rect  //需要指定id
            onMySignal: txt.text = "hello new text"
        }
    }

    MySigRect{
        id: m_rect
        y: 100
    }

}

利用Connections方法的好处是可以单独建一个组件(上述例子当中的Text可以给它单独建一个组件),这个组件需要知道信号的实体id,槽的实现是由这个组件定义的。

下面是单独分离的组件的例子:

//MySigRect.qml

import QtQuick 2.0

Item {
    id: root

    //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
    //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
    signal mySignal    //带参数的信号定义

    Rectangle{
        id: rect
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: root.mySignal()  //点击时发送mySignal信号

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

}
//MyText.qml

import QtQuick 2.0

Item {

    Text {
        id: txt
        text: qsTr("text")

        //在目标组件里设置定义槽,需要指定id
        Connections{
            target: m_rect  //需要指定id
            onMySignal: txt.text = "hello new text"
        }
    }
}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MyText{
    }

    MySigRect{
        id: m_rect
        y: 100
    }

}

下面是带参数的信号,在上述例子的功能上添加参数10。


 

//MySigRect.qml

import QtQuick 2.0

Item {
    id: root

    //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
    //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
    signal mySignal(int num)    //带参数的信号定义

    Rectangle{
        id: rect
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: root.mySignal(10)  //点击时发送mySignal信号,参数为10

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

}
//MyText.qml

import QtQuick 2.0

Item {

    Text {
        id: txt
        text: qsTr("text")

        //在目标组件里设置定义槽,需要指定id
        Connections{
            target: m_rect  //需要指定id
            onMySignal: txt.text = "hello new text" + num   //添加变量名num
        }
    }
}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MyText{
    }

    MySigRect{
        id: m_rect
        y: 100
    }

}

以下是connect方式连接信号与槽

//MySigRect.qml

import QtQuick 2.0

Item {
    id: root

    //槽名称必须为on+信号名(第一个字母大写),否则编译不通过
    //信号在哪个组件定义槽就在哪个组件实现(槽通常不在本组件文件里实现,而是被外部使用时实现)
    signal mySignal(int num)    //带参数的信号定义

    Rectangle{
        id: rect
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: root.mySignal(10)  //点击时发送mySignal信号,参数为10

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

}
//MyText.qml

import QtQuick 2.0

Item {

    Text {
        id: txt
        text: qsTr("text")
    }

    function slot_fun(num){
        txt.text = "hello new text" + num
    }
}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MyText{
        id: m_txt
    }

    MyText{
        id: m_txt2
        y: 50
    }

    MySigRect{
        id: m_rect
        y: 100
    }

    Component.onCompleted: {
        //m_rect:     信号对象
        //mySignal:   信号函数
        //m_txt:      槽对象
        //slot_fun:   槽函数
        m_rect.mySignal.connect(m_txt.slot_fun)
        m_rect.mySignal.connect(m_txt2.slot_fun)
    }

}

以下是属性变化槽函数示例:

//MyText.qml

import QtQuick 2.0

Item {
    property int myNum: 0

    Text {
        id: txt
        text: qsTr("0")
    }

    //属性变化槽函数,如果一个组件声明了一个属性,
    //如果这个属性值发送变化会触发以下槽函数。
    //槽函数的名称为on+属性名(第一字母大写)+ Changed:
    onMyNumChanged: {
        txt.text = myNum
    }
}
//mail.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MyText{
        id: m_txt
    }

    Rectangle{
        id: m_rect
        y: 100
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent
            onClicked: {
                m_txt.myNum++
            }
            onPressed: m_rect.color = "darkred"
            onReleased: m_rect.color = "red"
        }
    }

}

C++发送信号到Qml槽

//MyForm.h

#ifndef MYFORM_H
#define MYFORM_H

#include <QWidget>

namespace Ui {
class MyForm;
}

class MyForm : public QWidget
{
    Q_OBJECT

public:
    explicit MyForm(QWidget *parent = nullptr);
    ~MyForm();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MyForm *ui;

signals:
    void sigCpp(QString msg);
};

#endif // MYFORM_H
//MyForm.cpp

#include "MyForm.h"
#include "ui_MyForm.h"

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

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

void MyForm::on_pushButton_clicked()
{
    emit sigCpp(ui->lineEdit->text());
}
//main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MyForm.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    //1.创建C++对象
    MyForm* pMyForm = new MyForm();
    pMyForm->show();

    //2.注册C++对象到Qml
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("pMyForm", pMyForm);

    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();
}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: pMyQml
    visible: true
    width: 350
    height: 200
    title: qsTr("Qml界面")

    Text {
        id: m_txt
        width: 100
        height: 100
    }

    //槽函数,跟普通函数定义一样
    function slotQml(str){
        m_txt.text = str
    }

    //程序最后执行:连接C++信号与Qml槽
    Component.onCompleted: {
        pMyForm.sigCpp.connect(pMyQml.slotQml)
    }
}

Qml信号发送到C++槽:

//MySlotForm.h

#ifndef MYSLOTFORM_H
#define MYSLOTFORM_H

#include <QWidget>

namespace Ui {
class MySlotForm;
}

class MySlotForm : public QWidget
{
    Q_OBJECT

public:
    explicit MySlotForm(QWidget *parent = nullptr);
    ~MySlotForm();

private:
    Ui::MySlotForm *ui;

public slots:
    void slotCpp(QString str);
};

#endif // MYSLOTFORM_H
//MySlotForm.cpp

#include "MySlotForm.h"
#include "ui_MySlotForm.h"

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

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

void MySlotForm::slotCpp(QString str)
{
    ui->lineEdit->setText(str);
}
//main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MySlotForm.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQmlApplicationEngine engine;

    //1.创建C++对象
    MySlotForm* pMySlotForm = new MySlotForm();
    pMySlotForm->show();

    //2.注册C++对象到Qml
    QQmlContext* context = engine.rootContext();
    context->setContextProperty("pMySlotForm", pMySlotForm);

    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();
}
//main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: pMyQml
    visible: true
    width: 350
    height: 200
    title: qsTr("Qml界面")
    signal sigQml(string num)    //带参数的信号定义

    Rectangle{
        width: 100
        height: 30
        border.color: "black"

        TextInput {
            id: m_txt
            width: 100
            height: 30
        }
    }

    Rectangle{
        id: rect
        y: 50
        width: 100
        height: 100
        color: "red"

        MouseArea{
            anchors.fill: parent

            onClicked: pMyQml.sigQml(m_txt.text)  //点击时发送mySignal信号,参数为10

            onPressed: rect.color = "darkred"
            onReleased: rect.color = "red"
        }
    }

    //程序最后执行:连接Qml信号与C++槽
    Component.onCompleted: {
        pMyQml.sigQml.connect(pMySlotForm.slotCpp)
    }
}

猜你喜欢

转载自blog.csdn.net/yongwoozzang/article/details/110896707