QML- 信号和事件系统

news2024/11/29 22:40:16

QML- 信号和事件系统

  • 一、概述
  • 二、信号事件处理系统使用
    • 1. 用信号处理器接收信号
    • 2. 信号处理程序
    • 3. 使用Connections 类型
    • 4. 附加信号处理程序
  • 三、向自定义QML类型添加信号
  • 四、将信号连接到方法和信号
    • 1. 信号与信号的连接

一、概述

应用程序和用户界面组件需要相互通信。例如,一个按钮需要知道用户是否点击了它。按钮可以改变颜色来表示其状态或执行某些逻辑。同样,应用程序需要知道用户是否点击了按钮。应用程序可能需要将此单击事件转发给其他应用程序。

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

二、信号事件处理系统使用

1. 用信号处理器接收信号

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

例如,Qt Quick Controls模块中的Button类型有一个clicked信号,当用户单击按钮时就会触发这个信号。

查阅参考资料知道 Button 继承了 AbstractButton 的信号功能。
在这里插入图片描述

在这种情况下,用于接收该信号的信号处理程序应该是onClicked。Qt 是是默认设置了 信号处理函数就是 on+信号名(信号首字母大写)

比如被按下的时候,处理函数就是 :onPressed()

在下面的示例中,每当单击按钮时,都会调用onClicked处理程序,并为父矩形应用随机颜色:

import QtQuick 2.14
import QtQuick.Controls 2.14

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);
          }
      }
}

2. 信号处理程序

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

例如,MouseArea类型有一个pressed属性。为了在这个属性改变时收到通知,写一个名为onPressedChanged的信号处理程序:

import QtQuick 2.14

Rectangle {
      id: rect
      width: 100; height: 100

      TapHandler {
          onPressedChanged: console.log("taphandler pressed?", pressed)
      }
}

即使TapHandler文档没有记录名为onPressedChanged的信号处理程序,但该信号是由pressed属性存在这一事实隐式提供的

3. 使用Connections 类型

在某些情况下,可能需要访问发出信号的对象之外的信号。为此,QtQuick模块提供了连接到任意对象信号的连接类型。连接对象可以从它指定的目标接收任何信号。 这个类型相当于就是一个 独立功能的 信号连接处理器。

例如,前面例子中的onClicked处理程序可以由根矩形接收,方法是将onClicked处理程序放在目标设置为按钮的Connections对象中:

import QtQuick 2.14
import QtQuick.Controls 2.14

  Rectangle {
      id: rect
      width: 250; height: 250

      Button {
          id: button
          anchors.bottom: parent.bottom
          anchors.horizontalCenter: parent.horizontalCenter
          text: "Change color!"
      }

      Connections {
          target: button
          onClicked: {
              rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
          }
      }
}

4. 附加信号处理程序

附加的信号处理程序接收来自附加类型的信号,而不是声明该处理程序的对象。
例如Component。onCompleted是一个附加的信号处理程序。它通常用于在创建过程完成后执行一些JavaScript代码。下面是一个例子:

import QtQuick 2.14

Rectangle {
      width: 200; height: 200
      color: Qt.rgba(Qt.random(), Qt.random(), Qt.random(), 1)

      Component.onCompleted: {
          console.log("The rectangle's color is", color)
      }
}

onCompleted 处理程序没有响应来自 Rectangle 类型的 completed 信号。相反,具有完成信号的组件附加类型的对象已由QML引擎自动附加到 Rectangle 对象。当创建 Rectangle 对象时,引擎会发出这个信号,从而触发 Component.onCompleted 信号处理程序。

附加的信号处理程序允许每个对象以特定信号通知待响应对象做出响应,例如,一个对象如果没有从某些特殊对象注册某些特殊信号,就无法接收此通知。附加的信号处理程序机制使对象能够接收特定的信号,而无需额外的代码。

三、向自定义QML类型添加信号

信号可以通过signal关键字添加到自定义QML类型中。这个一般就是我们自己用封装控件的时候用到的

定义新信号的语法是:

signal <name>[([<type> <parameter name>[, ...]])]

通过将信号作为方法调用来发出信号。
例如,下面的代码定义在名为SquareButton.qml的文件中。根矩形对象有一个激活的信号,每当子TapHandler被点击时就会发出这个信号。在这个例子中,激活的信号是通过鼠标点击的x和y坐标发出的:

// 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
      }
}

现在SquareButton的任何对象都可以通过onActivated信号处理程序连接到激活的信号:

// myapplication.qml
SquareButton {
      onActivated: console.log("Activated at " + xPosition + "," + yPosition)
}

有关为自定义QML类型编写信号的更多细节,请参见信号属性。

四、将信号连接到方法和信号

Signal对象有一个connect()方法,用于将一个信号连接到一个方法或另一个信号。当一个信号连接到一个方法时,只要这个信号发出,这个方法就会自动被调用。该机制使信号可以由方法接收,而不是由信号处理程序接收。 也是自己封装控件的时候调用时用到的。

下面,messagerreceived 信号使用 connect() 方法连接到三个方法:

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)
      }
  }

在很多情况下,通过信号处理程序而不是connect()函数接收信号就足够了。但使用connect方法时,信号可以由多个方法接收,如前所述,这对于信号处理程序来说是不可能的,因为它们必须唯一命名。此外,在将信号连接到动态创建的对象时,connect方法很有用。就是批量的创建列表对每一个列表元素都要绑定的时候。

有一个对应的disconnect()方法可以移除连接的信号:

Rectangle {
      id: relay
      //...

      function removeTelegraphSignal() {
          relay.messageReceived.disconnect(sendToTelegraph)
      }
}

1. 信号与信号的连接

通过连接信号和其他信号,connect()方法可以形成不同的信号链。

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)
      }
  }

每当触发TapHandler的tap信号时,send信号也会自动触发。

output:
      MouseArea clicked
      Send clicked

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/344622.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据迁移——技术选型

日常我们在开发中&#xff0c;随着业务需求的变更&#xff0c;重构系统是很常见的事情。重构系统常见的一个场景是变更底层数据模型与存储结构。这种情况下就要对数据进行迁移&#xff0c;从而使业务能正常支行。 背景如下&#xff1a;老系统中使用了mongo数据库&#xff0c;由…

webpack 的热更新是如何做到的?原理是什么?

Hot Module Replacement&#xff0c;简称 HMR&#xff0c;在不需要刷新整个页面的同时更新模块&#xff0c;能够提升开发的效率和体验。热更新时只会局部刷新页面上发生了变化的模块&#xff0c;同时可以保留当前页面的状态&#xff0c;比如复选框的选中状态等。 在 webpack 中…

Maxwell工作流程详解

要介绍maxwell的工作原理&#xff0c;首先需要讲一下mysql主从复制的原理 mysql主从复制原理&#xff1a; 如上图&#xff0c;左边是master主节点&#xff0c;右边是slave从节点 工作流程&#xff1a; 1.往主节点mysql的数据库中写入数据&#xff0c;产生数据变化&#xff0c…

让ChatGPT介绍一下ChatGPT

申请新必应内测通过了&#xff0c;我在New Bing中使用下ChatGPT&#xff0c;让ChatGPT介绍一下ChatGPT 问题1&#xff1a;帮我生成一篇介绍chatGPT的文章&#xff0c;不少于2000字 回答&#xff1a; chatGPT是什么&#xff1f;它有什么特点和用途&#xff1f; chatGPT是一种…

IO流概述

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录IO流概述IO 流的分类总结流的四大类字…

TCP传输文件

传输文件和传输信息的区别&#xff1a; 传输信息&#xff0c;只是一条数据&#xff0c;传输文件是多条数据传输信息传输过去一般都会显示&#xff0c;传输文件一般不会显示&#xff0c;一般只是存放在文件中传输文件需要传输&#xff0c;文件大小和文件名称&#xff08;不然不知…

C语言(字符串函数)

这章的内容记得引用<string.h>头文件 目录 1.strlen&#xff08;&#xff09; 2.strcat() 3.strncat() 4.strcmp() 5.strncmp() 6.strcpy() 7.strncpy() 8.sprintf() 8.strchr() 9.strpbrk() 10.strrchr() 11.strstr() 1.strlen&#xff08;&#xff09; 用于统计字符串的…

CentOS Stream 9尝鲜安装教程

作者&#xff1a;IT圈黎俊杰 一、下载CentOS Stream 9安装介质 在CentOS官网可以下载到CentOS Stream 9的安装介质&#xff0c;正面列出ISO介质的下载链接地址&#xff1a; https://download.cf.centos.org/9-stream/BaseOS/x86_64/iso/CentOS-Stream-9-20221019.0-x86_64-dv…

157、【动态规划】leetcode ——377. 组合总和 Ⅳ(C++版本)

题目描述 原题链接&#xff1a;377. 组合总和 Ⅳ 解题思路 一维滚动数组思路与 518. 零钱兑换 II&#xff08;二维数组一维滚动数组&#xff09; 大致相同&#xff0c;区别之处在于&#xff0c;零钱兑换解决的是组合问题&#xff08;元素在不同位置都代表同一个含义&#xff…

Java基础之IO流详解及使用方式(建议收藏)

目录前言一.初识IO流二.流的分类三.基本字节流3.1 FileOutputStream3.2 FileInputStream四.文件拷贝五.字符集六.乱码原因七.基本字符流7.1 FileReader7.2 FileWriter经典案例Demo八.高级流8.1 缓冲流8.1.1 字节缓冲流8.1.2 字符缓冲流8.2 转换流8.3 序列化流8.4 打印流8.4.1 字…

【算法】前缀和

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;要学会在纸上打草稿&#xff0c;这个很重要&#x1f43e; 文章目录1.什么是前缀和&#xff1f;2.怎么求前缀和&#xff1f;3.前缀和有什么用&#xff1f;4.进阶二维:矩阵和前缀和 主打一个记公式 1.什么是前…

四数之和-力扣18-java排序+双指针

一、题目描述给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a…

【C++】十分钟带你入门类和对象(上)

目录零 介绍一 面向过程和面向对象的初步认识二 类的引入三 类的定义四 类的访问限定符及封装4.1 访问限定符4.2 封装五 类的作用域六 类的实例化七 类对象模型7.1 如何计算类对象大小7.2 类对象的存储方式猜测7.3 结构体内存对齐规则八 this指针8.1 this指针的引出8.2 this指针…

leaflet 本地上传KML文件,在地图上解析显示图形(060)

第060个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中本地上传kml文件,利用解析此kml文件,在地图上显示图形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共114行)安装加载 leaflet-kml相关AP…

Ansible中Playbook的编写

目录 一、playbook 1 简介 2 playbook语法 3 playbook示例 检测语法 列出任务 列出tag 指定执行主机 执行yaml文件 4 playbook基础 主机与用户 Tasks 列表 一、playbook 1 简介 Playbook与ad-hoc相比,是一种完全不同的运用。 playbook是一种简单的配置管理系统…

2.13日报

完成官网国际化配置 Spring boot国际化支持 当我们web项目涉及到国外部署或者国外用户使用时&#xff0c;需要展示不同语言信息&#xff0c;所以就需要国际化支持&#xff0c;下面将讲解Springboot国际化支持操作 1. 修改Springboot application.yml配置 spring: messages…

【Linux】NTP时间同步服务与NFS网络文件共享存储服务器(配置、测试)

一、NTP时间同步服务1、NTP介绍NTP服务器【Network Time Protocol&#xff08;NTP&#xff09;】是用来使计算机时间同步化的一种协议&#xff0c;它可以使计机对其服务器或时钟源&#xff08;如石英钟&#xff0c;GPS等等)做同步化&#xff0c;它可以提供高精准度的时间校正&a…

Android12之apex调试

1.问题在调试libtinyalsa.so中添加log后&#xff0c;但是发现push so后&#xff0c;却没有log打印&#xff0c;why&#xff1f;2.分析以下为libtinyalsa.so的位置/system/lib64/libtinyalsa.so /system/lib/libtinyalsa.so /apex/com.android.vndk.v31/lib64/libtinyalsa.so /a…

C语言rewind和fseek函数的用法详解

前面介绍的文件读写函数都是顺序读写&#xff0c;即读写文件只能从头开始&#xff0c;依次读写各个数据。但在实际开发中经常需要读写文件的中间部分&#xff0c;要解决这个问题&#xff0c;就得先移动文件内部的位置指针&#xff0c;再进行读写。这种读写方式称为随机读写&…

C语言( 动态内存分配)

目录 一.malloc()和free()(原型都在stdlib.h头文件&#xff09; 1.malloc() 2.free()函数 3.案例演示 二.calloc() 三.realloc&#xff08;&#xff09; 在在C语言的内存当中&#xff0c;针对不同的数据我们所存放的位置都是不一样的。内存栈区和静态区系统会自动创建和销毁&am…