Qt使用QQuickWidget的输入法问题(Qt5.12及以前)

news2024/9/21 13:52:06

Qt使用QQuickWidget的输入法问题(Qt5.12及以前)

最近有网友表示,在使用QQuickWidget嵌入到QWidget时,QML内部的输入法会有问题。

主要表现是,当焦点从QWidget(比如QLineEdit)切换到QQuickWidget内(比如TextInput),不能切换输入法;而当切换到其他应用程序,在切换回Qt程序时,输入法状态可正常切换。

我个人只有 5.6.3、5.12.2、5.15.2 三个版本环境,经过测试,5.15.2 已经修复了这个bug。而 Qt5.6 到 5.12,一些接口和机制有变化,所以解决方案不一样。本文主要讨论一下这个bug形成的具体原因。

Qt的焦点与输入法

Qt窗口内的子控件,有的可以唤起输入法(比如QLineEdit),有的不能(比如QPushButton)。当焦点从一个QWidget切换到另一个QWidget,Qt通过会向焦点控件发送QInputMethodQueryEvent事件,将系统感兴趣的信息返回给系统。

而QQuickWidget内部的不同元素,有自己的焦点,有不同的输入法状态。

当混合使用QWidget与QQuickWidget(继承自QWidget)时,对于上层QApplication而言,只会感知到QWidget的焦点变化,QML内元素的输入法状态会经过QQuickWidget这一层来返回给系统。

Bug原因

所以bug本质原因是,鼠标点击QML内输入框时,QQuickWidget会获得焦点,随即触发QInputMethodQueryEvent事件,QQuickWidget处理该事件。而此时,QML的焦点状态不对,或者Qt内部Bug,导致没有正确将事件发送给焦点QQuickItem。

而当窗口由非激活切换为激活状态,Qt内部能正确将事件发送给焦点对象,输入法正常。

解决办法

不同Qt版本可能机制和接口有变化,建议通过相关事件、信号、焦点状态来找到合适的解决办法。

下面时5.6.3和5.12.2版本的解决方案:

  • Qt.5.6.3

    该版本里,QQuickWidget收到输入法事件时,将事件发送给了QQuickWindow,QQuickWindow虽然保存了当前QML的焦点元素,但实际源码什么都没做。

    Qt 源码:

    在这里插入图片描述

    所以,可以对QQuickWidget注册事件过滤器或者重写event方法,通过QQuickWidget::quickWindow拿到关联的QQuickWindow,再由QQuickWindow::activeFocusItem获取到焦点元素,将事件发送给它。

    bool Widget::eventFilter(QObject *watched, QEvent *event)
    {
        if(watched == quickWidget && event->type() == QEvent::InputMethodQuery)
        {
        	// 重新发送该消息。
            QApplication::sendEvent(quickWidget->quickWindow()->focusObject(), event);
            return true;
        }
        return false;
    }
    

    (Qt 5.6.3的QQuickWindow会始终保存焦点元素,即便焦点切换到外部,内部仍然保持了自己的焦点。)

  • Qt.5.12.2

    该版本里,Qt的逻辑有了变化,QQuickWidget 处理了输入法事件,向当前的焦点元素发送事件,但此时焦点元素不准确,实际焦点有些滞后。

    Qt源码:
    在这里插入图片描述

    但相比Qt5.6.3,QML的焦点能准确变换。

    所以,可以绑定QQuickWindow::focusObjectChanged信号,当QML的焦点变化时,更新输入法。

    connect(quickWidget->quickWindow(), &QQuickWindow::focusObjectChanged, this, [this](QObject *){
    	// 限定一下,判断当前焦点
        if(QApplication::focusWidget() == quickWidget)
            QGuiApplication::inputMethod()->update(Qt::ImQueryAll);
    });
    

    ( Qt 5.6.3里,QQuickWiget失去焦点并不会导致QQuickItem失去焦点,内部总是维持了焦点,所以再切回时,不会触发该信号…)

总结

输入法状态异常的解决办法,实际就是需要让正确的焦点对象处理 QInputMethodQueryEvent。如果上述两个解决办法不能解决其他版本问题,就需要看源码,从下面几个问题入手:

  • QQuickWidget是怎么处理输入法事件
  • 焦点切换时,QApplication::focusWidget、QQuiApplication::focusObject是什么
  • QQuickWindow::focusObjectChanged有没有正确触发
  • 窗口非激活到激活状态,是怎么触发输入法事件,焦点是谁

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

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

相关文章

Spring学习笔记——1

Spring学习笔记——1 一、Spring入门1.1、学习路线1.2、传统Javaweb开发困惑及解决方法1.3、三种思想的提出和框架概念1.3.1、IoC、DI和AOP思想提出1.3.2、框架的基本特点 1.4、Spring概述1.5、BeanFactory快速入门1.6、ApplicationContext快速入门1.7、BeanFactory与Applicati…

复习第四章集合+多线程

一、集合 Collection派生 我们在使用集合的时候其实更多的是使用List、Set、Map集合进行操作,List、Set又继承自Collection Collection下的集合为单列集合,可以理解为一个集合当中的数据只代表一个“对象”。 Map派生 Map代表的是存储key-value对的集…

为高性能计算构建,由亚马逊云科技Amazon Graviton3E驱动的最新实例正式可用

亚马逊云科技宣布两款基于最新一代自研芯片Amazon Graviton3E的新实例Amazon Elastic Compute Cloud(Amazon EC2)Hpc7g和Amazon EC2 C7gn正式可用。 其中,Hpc7g实例专为计算和网络密集型高性能计算(HPC)工作负载而构建…

K8s安全配置:CIS基准与kube-bench工具

01、概述 K8s集群往往会因为配置不当导致存在入侵风险,如K8S组件的未授权访问、容器逃逸和横向攻击等。为了保护K8s集群的安全,我们必须仔细检查安全配置。 CIS Kubernetes基准提供了集群安全配置的最佳实践,主要聚焦在两个方面:主…

axios 网络应用 axios基本使用

之前学了vue本地应用,通过Vue提供的各种指令,对本地的数据进行操作。 但是现在很少有纯本地的应用了,或多或少都会进行网络数据的交互。这个就想要axios,内部是阿贾克斯,封装之后使用起来更加便捷,并且功能…

【Java练习题汇总】《第一行代码JAVA》综合测试一,汇总Java练习题

Java练习题 综合测试一 1️⃣ 综合测试一 1️⃣ 综合测试一 下面关于Java 的特点不正确的一项是( )。 A. Java 具备跨平台性,可以在任意的操作系统间进行移植 B. Java 编写的程序可以直接解释执行,属于解释型的编程语言类型 C. Java 中具备垃圾收集机制…

Linux安装VScode

从本篇开始,打算有时间就写写在VScode中编写一些ros相关的案例程序用于学习记录。本篇是如何在Linux安装VScode的第一篇。 一、下载VScode 在Linux中打开浏览器输入:https://code.visualstudio.com/Download,选择与你电脑相匹配的版本下载&…

java版本spring cloud 企业工程系统管理 工程项目管理系统源码

 Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个&…

浅谈Java转义符\|

浅谈Java转义符\| 看一段程序 String t "a||b||c||d"; String[] temp t.split("\\|\\|"); System.out.println(temp.length); 主要是:"\\|\\|" 代表什么意思? 开始有点蒙,后来仔细一看明白了&#xff0…

易基因:单细胞DNA甲基化与转录组分析揭示猪生发泡卵母细胞成熟的关键调控机制|项目文章

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 在哺乳动物中,窦卵泡内的生发泡(germinal vesicle,GV) 卵母细胞可以保持数月或数年的静止状态。促黄体生成素(luteinizing hormone,LH)激增促进了减数…

740.删除并获得点数

目录 一、题目 二、代码 一、题目 740. 删除并获得点数 - 力扣&#xff08;LeetCode&#xff09; 二、代码 转换成打家劫舍问题 class Solution { public:int deleteAndEarn(vector<int>& nums) {int Max nums[0];//nums中的最大点数for(int i0;i<nums.size(…

iTOP-RK3588开发板Debian系统使用 VNC 远程控制桌面-客户端连接

在 360 软件管家里面下载 VNC Viewer 软件&#xff0c;如下图所示&#xff1a; 然后打开软件&#xff0c;之后如下图所示&#xff1a; 然后我们点击左上角 file-》New connection&#xff0c;如下图所示设置&#xff0c;我们的 VNC Server 设为 192.168.1.14:1&#xff0c;其中…

柴洪峰院士:大模型赋能金融科技思考与展望

本文整理自7月7日世界人工智能大会“AI生成与垂直大语言模型的无限魅力”论坛上中国工程院院士、复旦大学金融科技研究院院长柴洪峰《大模型赋能金融科技思考与展望》的主题分享&#xff0c;从金融垂直模型构建、金融知识图谱与大模型融合以及金融大模型的监管三个方面进行介绍…

大数据Flink(五十五):Flink架构体系

文章目录 Flink架构体系 一、 Flink中的重要角色 二、Flink数据流编程模型 三、Libraries支持

风辞远的科技茶屋:来自未来的信号枪

很久之前&#xff0c;有位朋友问我&#xff0c;现在科技资讯这么发达了&#xff0c;你们还写啊写做什么呢&#xff1f; 我是这么看的。最终能够凝结为资讯的那个新闻点&#xff0c;其实是一系列事情最终得出的结果&#xff0c;而这个结果又会带来更多新的结果。其中这些“得出”…

Ae 效果:CC Kernel

颜色校正/CC Kernel Color Correction/CC Kernel CC Kernel&#xff08;CC 卷积核&#xff09;效果主要用于图像的卷积处理&#xff0c;通过在卷积矩阵中设置不同的权重值&#xff0c;可以实现图像的锐化 Sharpen、模糊 Blur、查找边缘 Find Edges以及浮雕 Emboss等效果。 ◆ …

电脑剪辑视频的软件有哪些?试试这几种视频剪辑工具

视频剪辑可以帮助人们在不同情境下更好地理解和消化视频内容。通过剪辑&#xff0c;可以去除不必要的素材并突出重点&#xff0c;使观看者能够更快地获取信息&#xff0c;并且更容易保持注意力的集中。此外&#xff0c;剪辑可以提高视频质量&#xff0c;例如通过添加音乐、图形…

CAD如何转成JPG图片?学会这招轻松完成转换

当我们使用CAD软件创建设计或模型时&#xff0c;这些文件可能会很大且难以共享。将它们转换为图片可以使它们更易于使用和查看。图片格式通常支持各种软件和平台&#xff0c;这使得它们更容易被打开和共享&#xff0c;而不需要安装CAD软件。此外&#xff0c;图片文件通常比CAD文…

Java多线程面试21题

并行和并发有什么区别&#xff1f; 并行是指两个或者多个事件在同一时刻发生&#xff1b;而并发是指两个或多个事件在同一时间间隔发生。 并行是在不同实体上的多个事件&#xff0c;并发是在同一实体上的多个事件。 在一台处理器上“同时”处理多个任务&#xff0c;在多台处理…

【C++医学影像】支持三维影像后处理PACS系统源码

PACS系统源码是按照DICOM3.0和HL7标准,遵循IHE标准工作流程&#xff0c;以医学影像的采集、传输、存储和诊断为核心&#xff0c;集流程质控、患者信息管理应用和患者关注服务于一体的&#xff0c;覆盖放射、超声、内窥镜和病理等科室的C/S架构的综合医院应用系统。集成三维影像…