QML键盘事件

news2024/12/26 21:37:33

在QML中,当有一个按键按下或释放时,会产生一个键盘事件,将其传递给获得有焦点的QML项目(讲focus属性设置为true,则获得焦点)。

按键处理的基本流程:

  1. Qt接收密钥操作并生成密钥事件。
  2. 如果 QQuickWindow 是活动窗口,则密钥事件将传递给它。
  3. 关键事件由场景传递到具有活动焦点的项目。如果没有项目具有活动焦点,则忽略关键事件。
  4. 如果具有活动焦点的 QQuickItem 接受密钥事件,则传播将停止。否则,事件将发送到项的父项,直到接受该事件或到达根项。

附加属性所有可视基元都支持Keys 附加属性进行键的处理。

信号属性击具有一个KeyEvent参数,参数名为event,通过event来处理键。

处理完事件后,可以设置event.accepted:true,防止事件在项目层次结构中向上传播

常用属性:

enable是否启动(默认true)
forwardTo:list<item>将事件转发到其他列表
priority

优先级

Keys.BeforeItem (默认)在正常项键处理之前处理键事件。如果事件被接受,它将不会传递给该项目。

Keys.AfterItem   在正常项键处理之后处理键事件。如果该项接受键事件,则不会由键附加属性处理程序处理它。

优先级处理顺序:

 Keys.BeforeItem

  1. 中指定的项目forwaTo
  2. 特定的键处理程序,例如 onReturnPressed
  3. onPressed, onRelease的处理程序
  4. 项目特定的键处理,例如文本输入键处理
  5. 父项

如果优先级为 Keys.AfterItem 则键事件处理的顺序为:

  1. 项目特定的键处理,例如文本输入键处理
  2. 中指定的项目forwardTo
  3. 特定的键处理程序,例如 onReturnPressed
  4. onPressed, onRelease的处理程序
  5. 父项

信号:

asteriskPressed* 被按下时会发出此信号
backPressed按下后退键时会发出此信号
backtabPressed当按下 Shift+Tab 组合键(后退选项卡)时,将发出此信号
callPressed按下呼叫键时会发出此信号
cancelPressed按下取消键时会发出此信号
context1Pressed按下 Context1 键时会发出此信号
context2Pressed按下 Context2 键时会发出此信号
context3Pressed按下 Context3 键时会发出此信号
context4Pressed按下 Context4 键时会发出此信号
deletePressed按下 Delete 键时会发出此信号
digit0Pressed当按下数字“0”时,会发出此信号
digit1Pressed当按下数字“1”时,会发出此信号
digit2Pressed当按下数字“2”时,会发出此信号
digit3-8
digit9Pressed当按下数字“9”时,会发出此信号
downPressed按下向下箭头时会发出此信号
enterPressed按下 Enter 键时会发出此信号
escapePressed按下 Esc 键时会发出此信号
flipPressed按下翻转键时会发出此信号。
hangupPressed按下挂断键时会发出此信号
leftPressed按下向左箭头时会发出此信号
menuPressed按下菜单键时会发出此信号
noPressed按下 No 键时发出此信号
pressed按下某个键时会发出此信号
released释放密钥后会发出此信号
returnPressed按下回车键时会发出此信号
rightPressed按下向右箭头时发出此信号
selectPressed按下选择键时会发出此信号
shortcutOverride当按下可能用作快捷方式的键时
spacePressed按下空格键时会发出此信号
tabPressed按下 Tab 键时会发出此信号
upPressed按下向上箭头时会发出此信号
volumeDownPressed按下音量调低键时会发出此信号
volumeUpPressed按下音量调高键时会发出此信号
yesPressed按下“是”键时发出此信号

按下任意键,图像向右下角移动:

Rectangle{
        id:rect1
        width: 100;height: 100
        x:0;y:0
        color: "red"
        focus: true//获取焦点
        Keys.onPressed: {//按下任意键时
            rect1.x+=50//x的位置+50
            rect1.y+=50//y的位置+50
            event.accepted=true//设置为已处理
        }
    }

按下不同的键执行不同的命令:

按下向上键,向上移动10

按下向下键,向下移动10

按下向左键,向左移动10

按下向右键,向右移动10

Rectangle{
        id:rect1
        width: 100;height: 100
        x:100;y:100
        color: "red"
        focus: true//获取焦点
        Keys.onPressed: {//按下任意键时
            if(event.key==Qt.Key_Left)
                rect1.x-=10;
            else if(event.key==Qt.Key_Right)
                rect1.x+=10
            else if(event.key==Qt.Key_Up)
                rect1.y-=10
            else if(event.key==Qt.Key_Down)
                rect1.y+=10
            else{

            }
            event.accepted=true
        }
    }

KeyNavigation(按键导航)

基于键的用户界面通常允许使用箭头键在可聚焦项目之间导航。KeyNavigation 附加属性通过提供一种方便的方法来指定在按下箭头或 Tab 键时应获得焦点的项,从而实现此行为。

常见的属性:

backtab此属性保存按下 Shift+Tab 组合键(后退表)时要为其分配焦点的项目
down 此属性保存按下向下光标键时要为其分配焦点的项
left 此属性保存按下左光标键时要为其分配焦点的项目
right 

此属性保存按下右光标键时要为其分配焦点的项目。

tab

此属性保存按下 Tab 键时要为其分配焦点的项。

up此属性保存按下向上光标键时要为其分配焦点的项

使用Tab键切换:

Row{
        x:50;y:50
        spacing: 25
        Rectangle{
            id:rect1
            width: 100;height: 100
            radius: 10
            KeyNavigation.tab: rect2//按tab键,跳转到rect2
            focus: true //默认rect1获取焦点
            color:focus?"red":"lightgray"//获取焦点时为红色,没获取焦点时为灰色
            scale: focus?1:0.8//当没获取焦点时大小为0.8倍
            Text{
                anchors.centerIn: parent
                color: parent.focus?"black":"gray"
                font.pointSize: 20
                text:"矩形1"
            }
        }
        Rectangle{
            id:rect2
            width: 100;height: 100
            radius: 10
            KeyNavigation.tab: rect3//按tab键,跳转到rect3
            color:focus?"green":"lightgray"//获取焦点时为绿色,没获取焦点时为灰色
            scale: focus?1:0.8//当没获取焦点时大小为0.8倍
            Text{
                anchors.centerIn: parent
                color: parent.focus?"black":"gray"
                font.pointSize: 20
                text:"矩形2"
            }
        }
        Rectangle{
            id:rect3
            width: 100;height: 100
            radius: 10
            KeyNavigation.tab: rect1//按tab键,跳转到rect1
            color:focus?"blue":"lightgray"//获取焦点时为蓝色,没获取焦点时为灰色
            scale: focus?1:0.8//当没获取焦点时大小为0.8倍
            Text{
                anchors.centerIn: parent
                color: parent.focus?"black":"gray"
                font.pointSize: 20
                text:"矩形3"
            }
        }
    }

 

Shortcut (快捷键)

快捷键类型提供了一种处理键盘快捷键的方法。快捷键可以设置为标准键盘快捷键之一,也可以使用包含激活快捷键所需的最多四次按键序列的字符串来描述。

属性:

sequence 此属性保存快捷方式的键序列。键序列可以设置为标准键盘快捷键之一,也可以使用包含激活快捷键所需的最多四次按键序列的字符串来描述。
sequences:list<>此属性包含快捷方式的多个键序列
enable是否启动该功能
portableText 此属性以“可移植”格式的字符串形式提供快捷方式的键序列
nativeText 此属性将快捷方式的键序列作为特定于平台的字符串提供。这意味着它将被翻译显示
autoRepeat此属性保存快捷方式是否可以自动重复(默认true)

context:enumeration(上下文)

Qt.WindowShortcut当快捷方式的父项位于活动的顶级窗口中时,快捷方式处于活动状态(默认)
Qt.ApplicationShortcut当应用程序的某个窗口处于活动状态时,快捷方式处于活动状态

信号:

activated激活时
activatedAmbiguously当快捷方式被模糊地激活时,会发出此信号,这意味着它与多个快捷方式的开头匹配

快捷键创建格式: 

  1. sequence: "Ctrl+E"               按下Ctrl +E
  2. sequence:"Ctrl+E,Ctrl+W"   先按下Ctrl+E 然后再按下Ctrl+W
  3. sequences:["Ctrl+E","Ctrl+W"]   按下Ctrl+E 或 Ctrl+W

简单的使用:

Rectangle{
        Shortcut{
            sequence: "Ctrl+E"
            onActivated:
                console.log("已按下Ctrl+E")
        }
    }

Rectangle{
        Shortcut{
            sequence: "Ctrl+E,Ctrl+W"
            onActivated:
                console.log("已按下Ctrl+E+Ctrl+W")
        }
    }

 需要先按下Ctrl+E 再按下Ctrl+W才能触发

 

 Rectangle{
        Shortcut{
            sequences: ["Ctrl+E","Ctrl+W"]
            onActivated:
                console.log("已按下Ctrl+E或Ctrl+W")
        }
    }

按下Ctrl+E或按下Ctrl+W

  activated和activatedAmbiguously的区别

  • activated  只能由于单个Shotcut的触发
  • activatedAmbiguously  可以用于快捷键被多个Shotcut触发

当快捷键被多个Shotcut触发时,activated不触发 

Rectangle{
        Shortcut{
            id:s1
            sequence:"Ctrl+E"
            onActivated:
                console.log("s1已按下Ctrl+E")
        }
        Shortcut{
            id:s2
            sequence:"Ctrl+E"
            onActivated:
                console.log("s2已按下Ctrl+E")
        }
    }

 

 当快捷键被多个Shotcut触发时,activatedAmbiguously触发 

触发规则:

  1. 优先触发后面创建的Shortcut对象
  2. 一次只触发一个对象
Rectangle{
        Shortcut{
            id:s1
            sequence:"Ctrl+E"
            onActivatedAmbiguously:
                console.log("s1已按下Ctrl+E")
        }
        Shortcut{
            id:s2
            sequence:"Ctrl+E"
            onActivatedAmbiguously:
                console.log("s2已按下Ctrl+E")
        }
        Shortcut{
            id:s3
            sequence:"Ctrl+E"
            onActivatedAmbiguously:
                console.log("s3已按下Ctrl+E")
        }
    }

按下3次Ctrl+E

 

 Keys中的快捷键覆盖:

使用    onShortcutOverride

当没有快捷键覆盖时:

Rectangle{
        id:rect1
        focus:true
        Keys.onEscapePressed:{
            console.log("Keys.Escape")
        }
    }
    Shortcut{
        sequence: "Escape"
        onActivated: {
            console.log("Shortcut.Escape")
        }
    }

 使用快捷键覆盖:

Rectangle{
        id:rect1
        focus:true
        Keys.onShortcutOverride: event.accepted=(event.key==Qt.Key_Escape)
        Keys.onEscapePressed:{
            console.log("Keys.Escape")
        }
    }
    Shortcut{
        sequence: "Escape"
        onActivated: {
            console.log("Shortcut.Escape")
        }
    }

 控件与焦点:

判断是否为活动焦点:

使用activeFocus来判断是否获取焦点

当有多个控件需要焦点时的处理:(Qt 5.9.9版本下)

子控件:文件名为:Mywidget.qml

import QtQuick 2.9
Rectangle{
    id:rect1
    color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
    Text { id: label1; anchors.centerIn: parent}
    focus: true
    Keys.onPressed: {
        if (event.key == Qt.Key_A)
            label1.text = 'Key A was pressed'
    }
}

主控件: 在Window中添加

Rectangle{
        width: 300;height:300;x:100;y:100;color: "lightBlue"
        focus: true//设置焦点
        Column{
            spacing:25
            Mywidget{  }
            Mywidget{  }
        }
    }

运行的话子控件不会接收焦点

 在第一个子控件中添加焦点

Rectangle{
        width: 300;height:300;x:100;y:100;color: "lightBlue"
        
        Column{
            spacing:25
            Mywidget{ focus: true }
            Mywidget{ }
        }
    }

运行结果:第一个控件响应键盘事件

 

第二个子控件中添加焦点 :

Rectangle{
        width: 300;height:300;x:100;y:100;color: "lightBlue"

        Column{
            spacing:25
            Mywidget{  }
            Mywidget{ focus: true}
        }
    }

运行结果为:还是第一个子控件获取键盘事件

 

 当两个子控件都设置焦点:

Rectangle{
        width: 300;height:300;x:100;y:100;color: "lightBlue"

        Column{
            spacing:25
            Mywidget{ focus: true }
            Mywidget{ focus: true }
        }
    }

运行结果还是第一个子控件获取键盘事件 

由此可见:当有多个组件设置了焦点时,最终只有一种类型可以具有键盘焦点,系统必需决定哪种类型获取焦点。此问题是由于可见性造成的。组件希望具有焦点,但在导入或重用是无法控制焦点。同样,组件无法知道其导入的组件是否正在请求焦点。

为了解决这个问题QML引入了焦点范围的概念:

 

FocusScope(焦点范围) 

  • 在每个焦点范围内,一个对象可能已设置为 。如果设置了多个 Item 属性,则要设置的最后一个类型将具有焦点,而其他类型将未设置,类似于没有焦点范围的情况。
  • 当焦点范围收到活动焦点时,包含的已设置类型(如果有)也会获取活动焦点。如果此类型也是焦点范围,则代理行为将继续。焦点范围和子焦点项都将设置属性。
  •  FocusScope 类型不是视觉对象类型,因此需要向 FocusScope 的父项公开其子项的属性

例子:实现使用鼠标点击切换焦点

子控件:

FocusScope {

    id: scope

    //公开子项的属性
    property alias color: rectangle.color
    x: rectangle.x; y: rectangle.y
    width: rectangle.width; height: rectangle.height

    Rectangle {
        id: rectangle
        anchors.centerIn: parent
        color: "lightsteelblue"; width: 175; height: 25; radius: 10; antialiasing: true
        Text { id: label; anchors.centerIn: parent }
        focus: true
        Keys.onPressed: {
            if (event.key == Qt.Key_A)
                label.text = 'Key A was pressed'
    }
    //鼠标点击获取焦点
    MouseArea { anchors.fill: parent; onClicked: { scope.focus = true } }
    }
}

主控件:

Rectangle{
        width: 300;height:300;x:100;y:100;color: "lightBlue"

        Column{
            spacing:25
            Mywidget{focus: true }
            Mywidget{  }
        }
    }

运行结果:

1.按下A键

2.鼠标点击第二个子控件,再按下A键 

 

使用FocusScope设计一个登录界面。

标签和输入框的设计:

import QtQuick 2.9
FocusScope{

    property alias label:label.text

    Row{
        spacing: 10
        Text{
            id:label
            text:"标签"
        }
        Rectangle{
            width:100
            height: 20
            color: "white"
            border.color: "gray"
            TextInput{
                id:input
                anchors.fill: parent//充满整个矩形
                anchors.margins: 4  //设置边距
                focus: true;//获取焦点
            }
        }
    }
}

主窗口显示:

Rectangle{
        anchors.fill: parent
        property alias mouseArea: mouseArea
        focus: true
        color: "lightgray"
        MouseArea{
            id:mouseArea
            anchors.fill:parent//充满整个矩形
        }
        Mywidget{
            id:widget1;x:100;y:100
            label:"账号"//设置标签
            KeyNavigation.tab:widget2

        }
        Mywidget{
            x:100
            y:150
            id:widget2;
            label: "密码"//设置标签
            KeyNavigation.tab:widget1
        }

    }

运行效果:

 

 参考文档:

Keyboard Focus in Qt Quick | Qt Quick 5.15.12

Keys QML Type | Qt Quick 5.15.12

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

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

相关文章

keepalived学习记录:对其vip漂移过程采用gdb跟踪

对其vip漂移过程采用gdb跟踪keepalived工具主要功能产生vip漂移过程两种情况gdb调试常用命令gdb调试时打到的函数栈&#xff08;供学习参考&#xff09;函数栈的图是本人理解下画的&#xff0c;不对请多指正 keepalived主要有三个进程&#xff0c;父进程是core进程&#xff0c;…

python编程:查找某个文件夹下所有的文件,包括子文件加下的所有文件,读取指定类型的文件

目录 一、实现要求 二、代码实现 三、效果测试 一、实现要求 1、在电脑上有一个文件夹&#xff0c;该文件夹下面还有子文件夹&#xff0c;具体层级不清楚&#xff0c;需要实现将该文件夹下所有的文件路径读取出来&#xff1b; 2、在1的基础上&#xff0c;只需读取指定类型的文…

论文复现-2:代码部分

以CONLL03数据集为例 文章目录1 整体框架2 数据结构2.1 原始数据集2.2 处理之后的数据集3 代码部分3.0 模型参数3.1 数据预处理3.2 模型方法3.1.1 定义表示的学习权重项的学习双塔模型3.2.2 forward3.3 损失函数3.4 训练与推理Ablation study训练实例1 整体框架 任务是实体识别…

MVVM模式下如何正确【视图绑定+数据】

概述 我如何&#xff08;不在后面的代码中使用代码&#xff09;自动绑定到我想要的视图&#xff1f;据我了解&#xff0c;如果正确完成&#xff0c;这就是模式应该如何工作。我可以使用主窗口 xaml 中的代码实现这一切&#xff0c;我甚至正确创建了一个资源字典&#xff08;因…

python Pytest生成alluer测试报告的完整教程

1.下载allure包到本地&#xff0c;解压 网上很多资料&#xff0c;这边不提供了 2.配置环境变量 将上面解压后bin文件的路径复制&#xff0c;添加到环境变量Path下 3.验证环境变量配置是否功 在cmd中输入allure&#xff0c;回车 。查看allure是否成功&#xff1a; 4.pyc…

Spring Boot 整合Redis使用Lua脚本实现限流

目录一、简介二、maven依赖三、编码实现3.1、配置文件3.2、配置类3.3、注解类3.4、切面类3.5、lua脚本3.6、自定义异常和全局异常3.7、控制层四、验证4.1、单用户限流4.2、接口限流结语一、简介 本篇文章主要来讲Spring Boot 整合Redis使用Lua脚本实现限流&#xff0c;实现限流…

Lsof命令介绍

LSOF&#xff08;List Open Files&#xff09;是一款功能强大的开源工具&#xff0c;用于列出当前系统上打开的文件和进程。该工具可以帮助系统管理员和开发人员快速查找正在使用某个文件的进程&#xff0c;以及在系统上使用磁盘空间最多的进程。 本文将介绍LSOF的基本用法和常…

计算机网络自检

1 计网体系结构 因特网结构&#xff1a; 计网三个组成成分&#xff1a; 工作方式-其中2个部分&#xff1a; 功能-两个子网&#xff1a; 5个XAN分别是&#xff1a; 传输技术&#xff0c;两者的主要区别&#xff1a; 4种基本网络拓扑结构&#xff1a; 3种交换技术&#xff1a; 协…

南卡NEO骨传导首发新机,超前无线充设计,树立行业标杆!!!

​3月2号&#xff0c;更专业的骨传导运动耳机——南卡&#xff0c;发布了以轻运动为全新方向系列的南卡NEO&#xff0c;通过迭代升级的声学技术进一步的优化了音质&#xff0c;打造更强一代的音质体验。 音质全新升级&#xff0c;分”響“全新体验 一直以来南卡专业的实验团队…

计算机网络第5章(运输层)学习笔记

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

linux环境创建anaconda虚拟环境安装tensorflow-gpu版本

linux环境创建anaconda虚拟环境安装tensorflow-gpu版本1.找到相应版本2.下载步骤2.1选择下载版本2.2 创建虚拟环境2.3 进入虚拟环境2.5 更新三个包2.6 安装tensorflow和keras2.7 验证是否安装成功2.8 检验GPU是否可用2.9 测试代码3.成功&#xff0c;终于成功了&#xff01;&…

spring-boot rabbitmq整合

文章请参考&#xff1a;Springboot 整合RabbitMq &#xff0c;用心看完这一篇就够了 mven依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></depende…

张大大直播爆火?跨境电商直播能从中学到什么

最近这个张大大的直播间确实很火哈&#xff0c;连龙哥这个不怎么看娱乐新闻的也经常刷到。龙哥专门去看了几次张大大的这个直播&#xff0c;确实有点东西。每场都可以做到这么高流量着实是不容易。龙哥就凭借自己一些电商直播经验&#xff0c;给大家总结一下&#xff0c;我们可…

年薪20W软件测试工程师必备的6大技能(建议收藏)

软件测试 随着软件开发行业的日益发展&#xff0c;岗位需求量和行业薪资都不断增长&#xff0c;想要入行的人也是越来越多&#xff0c;但不知道从哪里下手&#xff0c;今天&#xff0c;就给大家分享一下&#xff0c;软件测试行业都有哪些必会的方法和技术知识点&#xff0c;作…

Java知识补充

ArrayList 继承结构 为什么要先继承AbstractList&#xff0c;而让AbstractList先实现List&#xff1f;而不是让ArrayList直接实现List&#xff1f; 这里是有一个思想&#xff0c;接口中全都是抽象的方法&#xff0c;而抽象类中可以有抽象方法&#xff0c;还可以有具体的实现方…

无聊小知识.03 Springboot starter配置自动提示

1、前言Springboot项目配置properties或yaml文件时候&#xff0c;会有很多spring相关的配置提示。这个是如何实现的&#xff1f;如果我们自己的配置属性&#xff0c;能否也自动提示&#xff1f;2、Springboot配置自动提示其实IDE是通过读取配置信息的元数据而实现自动提示的。S…

HCIE-Cloud Computing LAB备考第二步:逐题攻破--第一题:FusionCompute--合并小节

FusionCompute 三大要求&#xff1a;扩容对接共享存储windows版本的FC操作 FCWindows题目思维导图 扩容一台CNA节点&#xff0c;配置管理地址设置为&#xff1a;192.168.100.212。密码设置为&#xff1a;Cloud12#$。主机名设置为CNA2。【安装CNA 】【ctrlaltdel之后按esc选择…

双向链表+循环链表

循环链表双向链表 循环链表 循环链表是头尾相接的链表(即表中最后一个结点的指针域指向头结点&#xff0c;整个链表形成一个环)(circular linked list) **优点&#xff1a;**从表中任一结点出发均可访问全部结点 循环链表与单链表的主要差别当链表遍历时&#xff0c;判别当前…

精准测试对于覆盖率技术的全新诠释

对于白盒测试有深入研究的技术人员可能会问到&#xff0c;精准测试还是很多用到了覆盖率技术&#xff0c;这些本来不就是有开源的工具吗?下面我们来比较一下&#xff1a; 开源的覆盖率工具&#xff1a; 1、 将所有的测试产生的覆盖率混在一起&#xff0c;不具备快速定位缺陷与…

Pycharm补丁包使用教程

虽然社区版在大多情况下已经够用&#xff0c;但是有很多功能都是没有的&#xff0c;对照起一些教程之类的就很不方便 现在直接教一种简单中的简单的补丁包使用方法 我这里用的是 pycharm 19.2.6 注意右下角的configure 一般别的方法都是 打开&#xff0c;然后添加路径&#…