QT Linux下无法使用CTRL+ALT+P快捷键,不生效

文章目录

      • 一、背景
      • 二、排查
        • (1)检查创建,发现没问题。
        • (2)查看 shortcutMap 是否注册
        • (3)排查xcb有没有获取到该事件
        • (4)排查是否是系统的问题
        • (5)www.google.com
        • (6)xcb可以正常获取到键值
        • (7)继续调试 qt 代码
        • (8)被拦截
        • (9)谁拦截
        • (10)fcitx
        • (11)解决
          • 1、通过fcitx配置工具修改
          • 2、通过配置文件修改

一、背景

该快捷键在 Windows 中是被 Microsoft Office中使用,我们的程序为了和它保持统一,也是使用的该快捷键方式,在 Window 中是正常的,但在 Linux 下,使用该快捷键无效,虽然使用的是一套代码,但在不同平台下某些插件的实现还是有差异的。

二、排查

(1)检查创建,发现没问题。

代码中使用了 QShortcut 类添加快捷键,绑定激活信号,槽函数执行动作。QShortcut 创建后,会将其添加到全局变量 shortcutMap ,在 qguiapplication_p.h 文件中定义。在代码中打印后,也确实发现了包含了该快捷键。

QKeySequence keySeq(Qt::ControlModifier + Qt::AltModifier + Qt::Key_P);
QShortcut *pShortcut = new QShortcut(keySeq, parent); 
connect(pShortcut, &QShortcut::activated, this, [=](){});

(2)查看 shortcutMap 是否注册

每次按键后,qt从xcb事件分发器收集key事件后,都会尝试去捕获有没有注册的快捷键,这里可以打印到用户所有注册到shortcutMap中的快捷键。打印后,包含该快捷键。

bool QShortcutMap::tryShortcut(QKeyEvent *e)
{Q_D(QShortcutMap);if (e->key() == Qt::Key_unknown)return false;QVector<QShortcutEntry> vec = d->sequences;for (int i = 0; i < vec.size(); i++){qDebug() << vec[i].keyseq;}...
}

(3)排查xcb有没有获取到该事件

xcb是Linux下的底层系统库,所有的鼠标,键盘事件都从这个库收集上来,qt会对所有的事件进行转换为qt内部定义的事件,然后分发给应用程序。如果xcb都没有获取到,那肯定不是应用程序能够兼容的。还是从这个函数内加打印信息,查看到当次按键的键码描述符和键码。

结果:按下CTRL+ALT+P后,键码值是16777219,理论上应该是80,因为上一个键是O,是正常的,其值是79。所以怀疑是xcb底层获取的有问题。

bool QShortcutMap::tryShortcut(QKeyEvent *e)
{Q_D(QShortcutMap);if (e->key() == Qt::Key_unknown)return false;qDebug() << __FUNCTION__ << e->key() << e->modifiers();...

(4)排查是否是系统的问题

旁边同事有的机器是ok的,有的不行。而且测试机x64、arm、也有问题,排除架构的问题。ubuntu和麒麟v10也有问题排除系统。xfce和gnome也有问题排除桌面环境的问题。


(5)www.google.com

有人遇到了这个问题,也是该快捷键不生效,可能是clipit这个软件造成的原因,其在低版本会占用并锁定五个快捷键,导致它和别的软件都不能使用。在clipit最新的版本修复了这个问题,或者卸载该程序,使用其他程序代替。而我的电脑恰好有这个软件,导致xcb获取错误。

CTRL+ALT+O
CTRL+ALT+P
CTRL+ALT+H
CTRL+ALT+F
CTRL+ALT+A

tips:可以使用xev程序检测,按CTRL+ALT+P,发现P键值为空,什么信息都没有,显示两行0。如果未被锁定,其显示正常的键值,比如下图Shift_L为50。

在这里插入图片描述


(6)xcb可以正常获取到键值

不想升级这个程序,我直接卸载了,然后通过xev检测,发现可以抓取到该快捷键,通过调试qt 程序,发现,tryShortcut函数可以正常获取到该事件了,但是应用程序依然无法使用。


(7)继续调试 qt 代码

1、将xcb事件转换为qt内部的事件

在这里插入图片描述

2、qt再将内部事件转发下去。


3、如果keyEvent也是个handleShortcutEvent,则将其转发到快捷键事件中。

在这里插入图片描述4、尝试发送快捷键

在这里插入图片描述5、对shortcutMap进行查询,如果匹配到注册的,就发送激活信号。

在这里插入图片描述
tips:如果是正常的链路,则是按如下调用方式。

tryShortcut() => nextState() => find() => dispatchEvent()
尝试调用快捷键 => 状态机查询匹配 => 查找快捷键 =>分发事件(通过CoreApplication::sendEvent)


(8)被拦截

最上层void QXcbKeyboard::handleKeyEvent,获取到了正确的快捷键事件,但是传递到后面就没有了,怀疑是被拦截了,调试代码后最终发现,在调用filterEvent中被拦截了。

在这里插入图片描述

(9)谁拦截

linux qt平台下,集成了两种输入法,我当前环境是fcitx,所以走的是上面。而ok的同事使用的是ibus输入法,所以应该是fcitx过滤了。

在这里插入图片描述

在这里插入图片描述


(10)fcitx

qt中包含了两个fcitx版本的接口,分别是org.freedesktop.portal.Fcitxorg.fcitx.Fcitx-0,我的本机使用了第二种,它会通过QDUBS去请求,看是否会过滤,其结果通过processKeyEventResult返回,返回true,说明fcitx内部进行了处理,qt层不用处理了,需要过滤,那么该事件就被reset,那么也就收不到了。如果fcitx没处理,那么通过forwardEvent,将其发送。

在这里插入图片描述

(11)解决

猜测fcitx内部占用了该快捷键,取消即可,自己的应用程序就能使用了。

1、通过fcitx配置工具修改

在这里插入图片描述

2、通过配置文件修改

如果fcitx config tool版本过低,可以通过配置文件修改

sudo vim ~/.config/fcitx/config
// 将这一行
#SwitchPreedit=CTRL_ALT_P
// 改为这一行,保存后,重启电脑即可
SwitchPreedit=

tips:#必须去掉,虽然注释了,fcitx依然会使用默认该快捷键。

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

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

相关文章

【Java】DI依赖注入详解

DI注入时有以下几种方式 1、属性注入&#xff1a;Autowired注解 通过Autowired直接进行属性注入 Service public class UserService {public void sayHi(){System.out.println("Hi,service");} } Controller public class UserController {Autowiredprivate Use…

docker核心技术

一. 从系统架构谈起 传统分层架构 vs 微服务 微服务改造 分离微服务的方法建议: 审视并发现可以分离的业务逻辑业务逻辑,在对业务领域不是特别熟悉的时候,按照部门职能进行划分,例如账号、财务等寻找天生隔离的代码模块,可以借助于静态代码分析工具如果可以闭环的解决一…

蓝桥杯Web应用开发-display属性

display 属性 专栏持续更新中 display 属性可以用来设置元素在页面上的排列方式&#xff0c;也可用来隐藏元素。 display 属性值的说明如下表所示。 属性值说明block元素以块级方式展示。inline元素以内联方式展示。inline-block元素以内联块的方式展示。none隐藏元素。 b…

ubuntu换源

参考链接 首先去清华源官方sudo vim /etc/apt/sources.list 最好备份一下sudo apt-get update && sudo apt-get upgrade 可能会遇到的问题 cd /tmp wget http://archive.ubuntu.com/ubuntu/pool/main/c/ca-certificates/ca-certificates_20210119~20.04.2_all.deb …

基于ESP8266 开发板(MCU)遥控小车

遥控小车 ​ 遥控界面 ​ 【项目源码】 第一版ESP8266 https://github.com/liyinchigithub/esp8266_car_webServerhttps://github.com/liyinchigithub/esp8266_car_webServer 第二版ESP32 GitHub - liyinchigithub/esp32-wroom-car: 嵌入式单片机 ESP32 Arduino 遥控小车&a…

Kong 负载均衡

负载均衡是一种将API请求流量分发到多个上游服务的方法。负载均衡可以提高整个系统的响应速度&#xff0c;通过防止单个资源过载而减少故障。 在以下示例中&#xff0c;您将使用部署在两台不同服务器或上游目标上的应用程序。Kong网关需要在这两台服务器之间进行负载均衡&…

Hudi学习 6:Hudi使用

准备工作&#xff1a; 1.安装hdfs https://mp.csdn.net/mp_blog/creation/editor/109689143 2.安装spark spark学习4&#xff1a;spark安装_hzp666的博客-CSDN博客 3.安装Scala Hudi学习6&#xff1a;安装和基本操作_hzp666的博客-CSDN博客 spark-shell 写入和读取hudi 2.…

docker proxy 【docker 代理】

第一种 创建代理配置文件 mkdir -p /etc/systemd/system/docker.service.d/ cat <<EOF > /etc/systemd/system/docker.service.d/http-proxy.conf Environment"HTTP_PROXYhttp://192.168.21.101:7890" Environment"HTTPS_PROXYhttp://192.168.21.1…

Transformer实战-系列教程6:Vision Transformer 源码解读4

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 Vision Transformer 源码解读1 Vision Transformer 源码解读2 Vision Transformer 源码解读3 Vis…

华为交换机配置Qos

QoS在企业网中的应用 在企业网络中&#xff0c;QoS的一系列技术不要求在同一台设备上应用&#xff0c;而应根据业务需要在不同位置应用。 图5 QoS技术在企业网络中的应用 理论上来说&#xff0c;各层次设备的功能如下&#xff1a; l 接入层业务识别 接入交换机LSW1作为边界…

Flume多进程传输

1.Flume介绍 Flume 是一种分布式、可靠且可用的服务&#xff0c;用于高效收集、聚合和移动大量日志数据。它具有基于流数据流的简单而灵活的架构。它具有鲁棒性和容错性&#xff0c;具有可调的可靠性机制和许多故障转移和恢复机制。它使用简单的可扩展数据模型&#xff0c;允许…

[鹤城杯 2021]easy_crypto

下载一看发现是核心价值观编码 核心价值观编码