qml的信号槽机制

qml的信号槽机制和qtwidget差不多,但是使用方法不一样,qtwidget一般直接用connect函数把信号和槽一绑定就完事了,qml分为自动绑定和手动绑定。

信号自动绑定

在一个组件里面定义一个信号,用signal定义,当事件触发,比如button的onclick,发送信号,连接信号槽,就是这个信号发出后对他进行一个处理,边看例子边讲吧

//测试qml的信号槽机制
import QtQuick
import QtQuick.Controls

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

    //文本框
    Flickable {
           id: flickable
           anchors.centerIn: parent
           width: 200
           height: 200
           contentWidth: textEdit.width
           contentHeight: textEdit.height
           clip: true
//滑动条部份,需要用flickable或者scrollbar包装起来
           ScrollBar.vertical: ScrollBar {
               id: vbar
               width: 20
               policy: ScrollBar.AsNeeded
               anchors {
                   right: parent.right
                   top: parent.top
                   bottom: parent.bottom
               }
           }

           TextEdit {
               id: textEdit
               width: flickable.width
               height: Math.max(flickable.height, implicitHeight)
               wrapMode: TextEdit.Wrap
               color: "red"
           }
       }

    //测试信号按钮
    Button{
        x:10
        y:10
        width: 40
        height: 20
        text: "btn1"
        signal haveClick()
        onClicked: {
            haveClick()
        }
        onHaveClick: {textEdit.append("btn1被点击")}
    }

}

上面这段代码,我定义了一个文本框和一个按钮,文本框有一个滑动条模块,注意下,滑动条需要用scrollview或者flickable包装一下,button中定义了一个信号haveclick(),当按钮被点击onclick的时候就会被触发发送,发送出去自动绑定就是在信号名前面加上on并把信号名首字母大写,后面跟上处理函数,如上onHaveClick: {textEdit.append("btn1被点击")},textedit是我给文本框定义的id,我希望信号发出后,文本框能加上一行某某被点击,上面的代码可以直接复制到qml文件中区跑着看看,这个就是自动绑定信号槽。上面是信号槽绑定的一种方法,还有一种是类似JavaScript的箭头函数或者c++的lamda函数表达式的。

信号槽的手动绑定

我们在发送者的内部定义信号,在接收者内部定义接收槽函数。信号发出时进行信号槽的绑定

下面是无参和有参的实例

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    // Component.onCompleted: { print("窗口被创建")}
    // Component.onDestruction: {print("窗口被销毁")}
    //接收者,接收信号后打印
    Rectangle{
        id:rec
        // Component.onCompleted: { print("矩形被创建")}
        // Component.onDestruction: {print("矩形被销毁")}
        function ptr(){print("接收到按钮信号")}
        function ptr2(a, b){print(a+b)}
    }

    //发送者,触发后发送信号
    Button{
    width: 200
    height: 40
    x:50
    y:50
    text: "发送信号"
    signal testsignal
    signal test2(int a,int b)
    onClicked: {
    testsignal()
    test2(1,2)
    }
    onTestsignal: ()=>{rec.ptr()}
    onTest2: (a,b)=>{rec.ptr2(a,b)}
    //有参信号连接的第二种方法亲测无效,避雷
    //onTest2: rec.ptr2
    }

}

还有一种连接方式

onClicked: {
        parent.testsignal.connect(rec.ptr)
        parent.test2.connect(rec.ptr2)
    }

 一般不会这么用,只是理解下用法,这里可能有重复链接的问题,qml5的用法,在qml6中已经废除,qml6中改用connections,这里需要注意

QML5中的connections基本用法

import QtQuick 2.15
import QtQuick.Controls 2.15

Item {
    signal mySignal()
    
    Button {
        text: "触发信号"
        onClicked: mySignal()
    }
    
    Text {
        id: statusText
        text: "未收到信号"
    }
    
    // QML5 风格的 Connections
    Connections {
        target: parent // 连接到此对象发出的信号
        onMySignal: {
            console.log("信号已接收")
            statusText.text = "已接收信号!"
        }
    }
}

QML5的connections没有enable属性 

QML6的基本用法

Connections {
    target: sourceObject // 发出信号的对象
    enabled: true // 可选,控制连接是否激活
    
    // 信号处理器 - 方式1:函数声明
    function onSignalName(param1, param2) {
        // 处理逻辑
    }
    
    // 信号处理器 - 方式2:Lambda表达式
    onAnotherSignal: (param) => {
        // 处理逻辑
    }
}

组件的创建和销毁

每个组件其实都有两个信号,类似c++中类的构造函数和析构函数

Component.onCompleted:{}//组件的构造
Component.onDestruction: {}//组件的析构

在他们初始化和销毁的时候就会发生

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    Component.onCompleted: { print("窗口被创建")}
    Component.onDestruction: {print("窗口被销毁")}
    Rectangle{
        Component.onCompleted: { print("矩形被创建")}
        Component.onDestruction: {print("矩形被销毁")}
    }
}

运行效果:

按钮点击后控制台输出:

 

 在一个窗口里面创建一个矩形,窗口就是矩形的父对象,看看运行结果

初始化的时候是父节点先创建,在创建子节点,程序销毁的时候是子节点先被销毁,再是父节点被销毁,和qtwidget的对象树一样

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值