qml 信号和处理程序事件系统(Signal and Handler Event System)

简介: qml 信号和处理程序事件系统(Signal and Handler Event System)

概述

QML 具有信号和处理程序机制,其中信号是事件,信号通过信号处理程序进行响应。
当发出信号时,会调用相应的信号处理程序。在处理程序中放置诸如脚本或其他操作之类的逻辑允许组件响应事件。

<AttachingType>.on<Signal>
//<Signal>是信号的名称,首字母必须大写
//我们在处理程序中编写想要实现的效果
on<Property>Changed
//属性改变信号处理程序的用法
//<Property>是属性的名称,首字母大写
//都是放在当前元素的内部

信号处理程序

要在为特定对象发出特定信号时接收通知,对象定义应声明一个名为 on<Signal> 的信号处理程序,其中 <Signal>是信号的名称,首字母大写。信号处理程序应包含调用信号处理程序时要执行的 JavaScript 代码。。

例如,Qt Quick Controls 模块中的 Button 类型有一个 clicked 信号,每当单击按钮时都会发出该信号。 在这种情况下,用于接收此信号的信号处理程序应该是 onClicked。
在下面的示例中,每当单击按钮时,都会调用 onClicked 处理程序,将随机颜色应用于父 Rectangle:

import QtQuick 
import QtQuick.Controls
Rectangle {
    id: rect
    width: 250; height: 250
    Button {
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        text: "Change color!"
        onClicked: {
            rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
        }
    }
  }

属性更改信号处理程序

当 QML 属性的值发生变化时,会自动发出信号。 这种类型的信号是属性更改信号,这些信号的信号处理程序以 onChanged 的形式编写,其中 是属性的名称,第一个字母大写。

例如,MouseArea 类型有一个pressed 属性。 要在此属性更改时接收通知,下例为一个名为 onPressedChanged 的信号处理程序:

import QtQuick
Rectangle {
    id: rect
    width: 100; height: 100
    TapHandler {
    //点击屏幕时,修改了pressed属性,触发onPressedChanged
        onPressedChanged: console.log("taphandler pressed?", pressed)
    }
 } 

信号参数

信号可能有参数。 要访问这些,您应该为处理程序分配一个函数。 箭头函数和匿名函数都可以工作。

示例

// Status.qml import QtQuick
//注意:函数中形式参数的名称不必与信号中的名称相匹配。
Item {
    id: myitem
    signal errorOccurred(message: string, line: int, column: int) } 
Status {
    onErrorOccurred: (mgs, line, col) => console.log(`${line}:${col}: ${msg}`) 
  //不需要参数时 onErrorOccurred: function (message) { console.log(message) }
    }

关联信号(Connections)

在某些情况下,可能希望访问发出该信号的对象之外的信号。为此,该QtQuick模块提供用于连接任意对象信号的Connections类型。可以接收来自它的指定的任何信号的目标。

使用场景:

  • 将多个对象链接到同一个信号上
  • 在发出信号的作用域之外来建立连接
  • 发射信号的对象没有在QML中定义

例如,前面示例中的 onClicked 处理程序可能已被根 Rectangle 接收,方法是将 onClicked 处理程序放置在其目标设置为按钮的 Connections 对象中:

import QtQuick
import QtQuick.Controls
Rectangle {
    id: rect
    width: 250; height: 250
    Button {
        id: button
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        text: "Change color!"
    }
    Connections { //关联button的clicked信号
        target: button
        function onClicked() {
            rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
        }
    } }

附加信号处理

对象本身或者其基类没有的属性和信号,需要通过外部(附加类型)提供,从附加类型接收一个信号并进行处理

import QtQuick 2.14   
Rectangle {
    width: 200; height: 200
    color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1)
 
    Component.onCompleted: {  //Component 附加类型
        console.log("The rectangle's color is", color)
    } }

自定义类型添加信号

可以通过signal关键字将信号添加到自定义QML类型。定义新信号的语法为:

signal <name>[([<type> <parameter name>[, ...]])]
// SquareButton.qml
 import QtQuick 2.14   
Rectangle {
    id: root
    signal activated(real xPosition, real yPosition)  //定义一个信号 
    property point mouseXY
    property int side: 100
    width: side; height: side
 
    TapHandler {
        id: handler
        onTapped: root.activated(mouseXY.x, mouseXY.y)  //发送信号
        onPressedChanged: mouseXY = handler.point.position
    } }   
    
// myapplication.qml 
    SquareButton { //处理activated信号
    onActivated: console.log("Activated at " + xPosition + "," + yPosition)
     }

信号连接方法/信号

信号对象使用connect()连接方法或另一个信号。当信号连接到方法时,只要发出信号,该方法就会自动调用。这种机制使信号可以通过方法而不是信号处理程序来接收,也可以通过disconnect()来取消连接.

import QtQuick 2.14   Rectangle {
    id: relay
 
    signal messageReceived(string person, string notice)  //定义信号
 
    Component.onCompleted: {
        relay.messageReceived.connect(sendToPost)   //关联信号
        relay.messageReceived.connect(sendToTelegraph)
        relay.messageReceived.connect(sendToEmail)
        relay.messageReceived("Tom", "Happy Birthday")
    }
 
    function sendToPost(person, notice) {
        console.log("Sending to post: " + person + ", " + notice)
    }
    function sendToTelegraph(person, notice) {
        console.log("Sending to telegraph: " + person + ", " + notice)
    }
    function sendToEmail(person, notice) {
        console.log("Sending to email: " + person + ", " + notice)
    } }

使用disconnect()断开信号

Rectangle {
    id: relay
    //...
 
    function removeTelegraphSignal() {
        relay.messageReceived.disconnect(sendToTelegraph)
    } }

信号关联信号

import QtQuick 2.14   
Rectangle {
    id: forwarder
    width: 100; height: 100
 
    signal send()
    onSend: console.log("Send clicked")
 
    TapHandler {
        id: mousearea
        anchors.fill: parent
        onTapped: console.log("Mouse clicked")
    }
 
    Component.onCompleted: {
        mousearea.tapped.connect(send)   //关联信号 
    }


目录
相关文章
|
6月前
QT自定义信号,信号emit,信号参数注册
使用signals声明返回值是void在需要发送信号的地方使用emit 信号名字(参数)进行发送在需要链接的地方使用connect进行链接ct进行链接。
67 0
QT自定义信号,信号emit,信号参数注册
|
存储 Cloud Native 程序员
C++ Qt 事件(event)
C++ Qt 事件(event)
|
1月前
SDL基础使用05(事件系统event)
本文介绍了如何使用SDL库中的事件系统来控制图片的平铺和前景图的移动,包括响应键盘和鼠标事件调整图片位置和大小。
27 1
|
4月前
|
JavaScript
js【详解】event loop(事件循环/事件轮询)
js【详解】event loop(事件循环/事件轮询)
49 0
|
6月前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
347 0
|
JavaScript 前端开发
JS引擎的执行机制event loop
JS引擎的执行机制event loop
68 0
|
Java Android开发 C++
Framework 全局监听屏幕点击事件 INPUT_EVENT_INJECTION
Framework 全局监听屏幕点击事件 INPUT_EVENT_INJECTION
306 0
Revit空闲事件(Idling Event)增强和外部事件(External Event)
Revit空闲事件(Idling Event)增强和外部事件(External Event)
Revit空闲事件(Idling Event)增强和外部事件(External Event)
|
小程序
小程序--event对象
小程序--event对象
419 0
小程序--event对象