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

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.hqwc.cn/news/53568.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 用数组名作函数参数

当用数组名作函数参数时,如果形参数组中各元素的值发生变化,实参数组元素的值随之变化。 1.数组元素做实参的情况: 如果已经定义一个函数,其原型为 void swap(int x,int y);假设函数的作用是将两个形参(x,y&#xf…

在java中存储对象到redis出现类型转换异常的解决方法

**出现的问题,**此时的redisCatch已经注入 原因:这里传进来的是一个对象,redis不能直接将对象存到String中,必须将对象进行序列化转成json字符串再存储,其次.传进来的对象不能是null 再重新启动就行了

三、PWM呼吸灯

1. 什么是呼吸灯 如下图中的蓝色LED灯,不再是亮灭交替,而是慢慢亮慢慢灭,这就是呼吸灯 生活中常见 2. 怎样实现? 答:用PWM

瞄准产业应用,大模型加持的深兰科技AI虚拟数字人落地业务场景

伴随ChatGPT的问世,在技术与商业运作上都日渐发展成熟的AI数字人产业正持续升温。 目前的AI数字人不仅拥有超高“颜值”,同时还拥有更为丰富的、细腻的表情和动作。更有甚者,AI数字人已经具备自定义构建知识图谱、自主对话、不断学习成长的能…

vivo全球商城:电商交易平台设计

一、背景 vivo官方商城经过了七年的迭代,从单体架构逐步演进到微服务架构,我们的开发团队沉淀了许多宝贵的技术与经验,对电商领域业务也有相当深刻的理解。 去年初,团队承接了O2O商城的建设任务,还有即将成立的礼品中…

【单片机】51单片机,TLC2543,驱动程序,读取adc

TLC2543 是一款 12 位精密模数转换器 (ADC)。 1~9、11、12——AIN0~AIN10为模拟输入端; 15——CS 为片选端; 17——DIN 为串行数据输入端;(控制字输入端,用于选择转换及输出数据格式) 16——…

ChatGPT下架官方检测工具,承认无法鉴别AI内容

去年底,OpenAI 推出的 ChatGPT ,带来了生成式人工智能涌现的热潮。它不仅能够协助完成撰写邮件、视频脚本、文案、翻译、代码等任务,还能通过学习和理解人类的语言来进行对话,并根据聊天的上下文进行互动。 但随之而来的争议也让人…

无向图-已知根节点求高度

深搜板子题&#xff0c;无向图&#xff0c;加边加两个&#xff0c;dfs输入两个参数变量&#xff0c;一个是当前深搜节点&#xff0c;另一个是父节点&#xff08;避免重复搜索父节点&#xff09;&#xff0c;恢复现场 ///首先完成数组模拟邻接表#include<iostream> #incl…

selenium 遇到更新chorme驱动

打开浏览器,在地址栏输入chrome://version/便可以查看到谷歌当前的版本号 谷歌浏览器驱动的下载网址 http://chromedriver.storage.googleapis.com/index.htmlhttp://chromedriver.storage.googleapis.com/index.html 解压后把chromedriver.exe 放到python安装的目录下&am…

openGauss学习笔记-30 openGauss 高级数据管理-别名

文章目录 openGauss学习笔记-30 openGauss 高级数据管理-别名30.1 语法格式30.1.1 列别名语法30.1.2 表别名语法 30.2 参数说明30.3 示例 openGauss学习笔记-30 openGauss 高级数据管理-别名 SQL可以重命名一张表或者一个字段的名称&#xff0c;这个名称为该表或该字段的别名。…

本地pycharm远程连接服务器运行自己的项目

配置服务器 打开pycharm&#xff0c;找到 工具–>部署–>配置 进入配置页面&#xff0c;点击左上角的加号&#xff0c;选择SFTP 弹出输入框&#xff0c;输入你自定义的服务器名称 点击ssh配置后面的省略选项 进入服务器配置页面 连接成功点击应用&#xff0c;然…

抖音seo矩阵系统源码搭建开发详解

抖音SEO矩阵系统是一个用于提高抖音视频在搜索引擎排名的工具。如果你想开发自己的抖音SEO矩阵系统&#xff0c;以下是详细的步骤&#xff1a; 开发步骤详解&#xff1a; 确定你需要的功能和算法 抖音SEO矩阵系统包含很多功能&#xff0c;比如关键词研究、内容优化、链接建设、…