当前位置: 首页 > news >正文

QT窗口无法激活弹出问题排查记录

问题背景

问题环境

            操作系统: 银河麒麟V10SP1qt版本  : 5.12.12

碰见了一个问题应用最小化,然后激活程序窗口无法弹出

            这里描述一下代码的逻辑,使用QLocalServer实现一个单例进程,具体的功能就是在已存在一个程序A进程时,再启动这个程序A,新的程序A进程会被杀死,然后激活已存在的进程,使窗口弹出

跟踪代码发现走到了激活函数(如下所示)

            this->raise();this->activateWindow();
问题现象如下,确实是有激活效果,图标闪烁了,但是窗口在最小化的情况不会弹


排查过程

        首先,我想写个简易的demo来复现这个问题,但是下面所示的代码并不能复现出上面提到的问题,最小化窗口可以被激活弹出,所以我还是得用原来的代码进行排查

              MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){ui->setupUi(this);//使用定时器触发执行槽函数QObject::connect(&m_timer, &QTimer::timeout, this,&MainWindow::slottimer);}MainWindow::~MainWindow(){delete ui;}//3秒钟执行一次void MainWindow::on_pushButton_clicked(){m_timer.start(3000);}//激活窗口void MainWindow::slottimer(){this->raise();this->activateWindow();}

为了排除操作系统的影响,我选择用同一份代码在不同系统上测试一下,看看效果

这里我测试了kylin、ubuntu都有这种问题,说明大概率和操作系统无关,uos因为操作系统镜像不好下载我就没测

和系统没关系,执行的时候也走了对应的函数,那么现在只能跟踪qt代码看看为什么没有弹出了,跟踪后有如下发现

            最后进入了QXcbWindow::requestActivateWindow()函数执行xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,(const char *)&event);

可以看到激活窗口实际是调用xcb模块的功能

            xcb介绍,XCB是X协议的一个C语言绑定,它提供了一种更现代、更高效的方式来与X Window System进行交互。xcb官网  https://xcb.freedesktop.org/

我分别在使用wayland和X协议的系统上进行测试,最后代码都走到了xcb_send_event方法

        接下来我就开始尝试对xcb_send_event的传参进行修改,重点是修改第二和第四个传参,其实这一步修改就是瞎改,也没有什么修改逻辑,我做的尝试如下:

            0  ->  1XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT  在此基础上增加或者减少事件掩码

        在修改测试过程中,发现偶尔能弹出来,但概率很低,然后我再把参数都恢复,发现也能偶尔弹出来,此刻我感觉和修改xcb_send_event参数没有什么关系了

        再结合前面我自己写的demo可以正常弹出的情况,我觉得代码中使用QLocalServer实现单例进程并且杀死新进程的方法可能会造成激活窗口操作失效(纯猜测,但改变了我的解决思路)

        所以还是要从应用调用代码的角度去解决


解决方案

如上所述,激活窗口一次没有没有生效,是不是多执行几次激活是不是就可以了?

       所以我修改激活窗口的方式,在原先激活窗口的位置开启定时器(定时器触发时间间隔500Ms~2s即可),在槽函数中执行激活窗口操作,当窗口激活成功就停止定时器

       在测试中发现,定时器第一次触发激活窗口的现象只是任务栏的图标闪烁,但窗口不弹出,而在第二次触发时窗口从任务栏中弹出,一般情况下第二次触发就能弹出了


后记

      为什么第一次触发激活窗口没有成功?目前还没有找到根源,我猜测可能是因为起第二进程再杀死导致了一些时序错误或者影响了堆栈,后续还要验证

      如果单纯从解决窗口不弹出的角度来说,还有一个方法就是调用命令wmctrl,但也可能存在失效的问题

            QProcess myProcess;QString program = "wmctrl";QStringList arguments;arguments << "-a" << w->windowTitle();myProcess.start(program,arguments);myProcess.waitForFinished();

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • EMCC13.5 图形化部署AGENT ,报错
  • Transformer推理结构简析(Decoder + MHA)
  • 在Windows系统上安装的 Arrow C++ 库
  • Java项目实战II基于Java+Spring Boot+MySQL的网上租贸系统设计与实现(开发文档+源码+数据库)
  • Vue3组件通信
  • 红外绝缘子数据集
  • Can‘t connect to local MySQL server through socket
  • PHP、Java等其他语言转Go时选择GoFly快速快速开发框架指南
  • layui table中的checkbox禁用问题
  • Linux嵌入式驱动开发指南(速记版)---Linux基础篇
  • 【动态规划】两个数组的 dp 问题二
  • Maven进阶-二、依赖
  • [答疑]《分析模式》2020中译本翻译水平怎样
  • 线性调频信号脉冲压缩并非是一个门信号
  • WPF入门教学五 布局容器入门
  • __proto__ 和 prototype的关系
  • 【RocksDB】TransactionDB源码分析
  • ES6系列(二)变量的解构赋值
  • golang中接口赋值与方法集
  • markdown编辑器简评
  • mysql常用命令汇总
  • node-glob通配符
  • PHP 小技巧
  • react-native 安卓真机环境搭建
  • 给初学者:JavaScript 中数组操作注意点
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 经典排序算法及其 Java 实现
  • 前端设计模式
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 我的zsh配置, 2019最新方案
  • 06-01 点餐小程序前台界面搭建
  • ​​​​​​​​​​​​​​Γ函数
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #微信小程序:微信小程序常见的配置传旨
  • (zhuan) 一些RL的文献(及笔记)
  • (纯JS)图片裁剪
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net core 依赖注入的基本用发
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .net经典笔试题
  • @Slf4j idea标红Cannot resolve symbol ‘log‘
  • [\u4e00-\u9fa5] //匹配中文字符
  • [1]从概念到实践:电商智能助手在AI Agent技术驱动下的落地实战案例深度剖析(AI Agent技术打造个性化、智能化的用户助手)
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [AIGC] 深入浅出 Python中的`enumerate`函数
  • [BUUCTF]-PWN:[极客大挑战 2019]Not Bad解析
  • [Docker]六.Docker自动部署nodejs以及golang项目
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [HNCTF 2022 WEEK2]easy_include 文件包含遇上nginx
  • [iphone-cocos2d]关于Loading的若干处理和讨论
  • [LeetBook]【学习日记】获取子字符串 + 颠倒子字符串顺序
  • [leetcode]56. Merge Intervals归并区间