惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
B
Blog
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
爱范儿
爱范儿
博客园_首页
博客园 - 聂微东
量子位
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
F
Fortinet All Blogs
The Cloudflare Blog
T
Tailwind CSS Blog
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
腾讯CDC

涛哥的博客

玩转QtQuick(2)-默认渲染器 | 涛哥的博客 玩转QtQuick(2)-默认渲染器 | 涛哥的博客 玩转QtQuick(1)-SceneGraph场景图简介 | 涛哥的博客 玩转QtQuick(1)-SceneGraph场景图简介 | 涛哥的博客 玩转Qml(18)-用户向导 | 涛哥的博客 玩转Qml(18)-用户向导 | 涛哥的博客 玩转Qml(17)-树组件的定制 | 涛哥的博客 玩转Qml(17)-树组件的定制 | 涛哥的博客 玩转Qt(15)-操控Web小车案例 | 涛哥的博客 玩转Qt(15)-操控Web小车案例 | 涛哥的博客 玩转Qt(14)-Qt与Web混合开发 | 涛哥的博客 玩转Qt(14)-Qt与Web混合开发 | 涛哥的博客 玩转Qt(13)-安卓5.12.4环境搭建 | 涛哥的博客 玩转Qt(13)-安卓5.12.4环境搭建 | 涛哥的博客 玩转Qt(12)-github-Actions缓存优化 | 涛哥的博客 玩转Qt(12)-github-Actions缓存优化 | 涛哥的博客 玩转Qt(11)-github-Actions自动化发行 | 涛哥的博客 玩转Qt(11)-github-Actions自动化发行 | 涛哥的博客 玩转Qt(10)-github-Actions自动化编译 | 涛哥的博客 玩转Qt(10)-github-Actions自动化编译 | 涛哥的博客 玩转Qt(9)-程序发布指南 | 涛哥的博客 玩转Qt(9)-程序发布指南 | 涛哥的博客 玩转Qt(8)-掌握信号槽使用细节 | 涛哥的博客 玩转Qt(8)-掌握信号槽使用细节 | 涛哥的博客 玩转Qt(7)-窥探信号槽的实现细节 | 涛哥的博客 玩转Qt(7)-窥探信号槽的实现细节 | 涛哥的博客 玩转Qt(6)-认清信号槽的本质 | 涛哥的博客 玩转Qt(6)-认清信号槽的本质 | 涛哥的博客 玩转Qt(5)-理解事件循环 | 涛哥的博客 玩转Qt(5)-理解事件循环 | 涛哥的博客
QQuickWidget中文输入法问题的正确解法 | 涛哥的博客
2020-11-30 · via 涛哥的博客
  • QQuickWidget中文输入法问题的正确解法
    • Qt的bug
    • 旧的解法
    • 正确的解法

本文分享特定问题的解法,用不到的可以忽略。

Qt的bug

使用QQuickWidget的时候,遇到过这个问题:界面的TextInput 或者TextEdit, 鼠标点击聚焦后,切换为光标输入状态,此时切换系统中文输入法,会发现无法输入。

(系统任务栏的输入法状态是正确的,界面上输入字符,直接显示英文,无法显示输入法的候选框)

需要把界面切到其它软件,再切换回来,之后就能够输入了。

可以参考Qt官方bug报告:

https://bugreports.qt.io/browse/QTBUG-61475

旧的解法

这个Bug是2018年报告的,我们当时做项目,也被这个Bug坑到了。

当时我给出了一个弱化版本的解法,原理是在第一次聚焦的时候,清理掉QQuickWidget的焦点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
QuickWidget::QuickWidget(QWidget *parent)
: QQuickWidget(parent)
{
...
connect(quickWindow(), &QQuickWindow::activeFocusItemChanged, this, &QuickWidget::onClearFocus);
...
}
void QuickWidget::onClearFocus()
{
QQuickItem *pItem = quickWindow()->activeFocusItem();
if (pItem && (pItem->inherits("QQuickTextInput") || pItem->inherits("QQuickTextField")))
{
disconnect(quickWindow(), &QQuickWindow::activeFocusItemChanged, this, &QuickWidget::onClearFocus);
QuickWidget::clearFocus();
}
}

此方法勉强能用,一些细节上体验不太好。

当时找不到更好的方法,就这样用着了。

正确的解法

2020年Qt官方终于派出了资深的专家,在Qt5.15.2中,彻底解决了这个问题。

(看到有不少博客、论坛,还在流传我提供的旧版本,于心不忍)

于是我从新版本里面,提炼出来了代码,给使用旧版本的同学解决此问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
QuickWidget::QuickWidget(QWidget *parent)
: QQuickWidget(parent)
{
...

#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
connect(quickWindow(), &QQuickWindow::focusObjectChanged, this, &QuickWidget::propagateFocusObjectChanged);
#endif

...
}

#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
bool QuickWidget::event(QEvent *e)
{
switch (e->type())
{
case QEvent::FocusAboutToChange:
return QCoreApplication::sendEvent(quickWindow(), e);
default:
break;
}
return Super::event(e);
}
void QuickWidget::propagateFocusObjectChanged(QObject *focusObject)
{
if (QApplication::focusObject() != this)
return;
if (this->window()->windowHandle()) {
emit this->window()->windowHandle()->focusObjectChanged(focusObject);
}
}
#endif