目录
一, 概述
二, 效果展示
三, 功能实现
一, 概述
用 Qt 开发 Windows 客户端界面确实是一大利器, 兼顾性能的同时, 速度相对来说也不错. 再加上 qss 的辅助, 那么一个漂亮的界面就不在话下了.
想要做出漂亮的界面, 重写一个标题栏是必不可少的, 那么我们肯定是需要使用 Qt 给我们提供的一个无边框 Qt::FramelessWindowHint 窗体属性. 但是设置了这个属性以后, 随之而来的就是一系列的问题, 比如说标题栏拖拽需要我们自己搞; 窗口放大缩小需要自己实现; 最要命的是一些模态窗体原生的抖动效果没有了.
既然出现问题, 那么我们就得想办法解决.
窗口放大缩小和拖拽在 Qt 的早期版本是提供了一个类文件支持的, 作者本人也对这个文件进行了二次开发, 可以提供更为丰富的功能. 由于拖拽和缩放跟本篇文章关系不大, 因此这里不做说明, 感兴趣的同学可以到 Qt 无边框窗体 - 最大化时支持拖拽还原这里查看
本篇文章我们就来说一说当模态窗体弹出来时, 如果点击了非模态窗体以外的应用程序界面, 怎么实现一个闪动的效果.
闪动只是一个对外的信息交互, 如果大家想要一些其他交互效果, 可以自行实现.
二, 效果展示
如效果图所示, 做了一个简单的效果
点击主应用程序时, 弹出的模态窗体边框颜色发生了变动, 实现了一个抖动的效果.
点击桌面时, 模态窗体也有一个失去焦点时的状态变化.
三, 功能实现
实现窗口抖动效果, 首先需要了解 Windows 的消息 ID, 知道我们要接受哪个 Windows 消息来完成闪动效果, 其次就是 Qt 怎么接收这样的原生 Windows 消息.
windowws 消息
了解 Windows 消息 ID, 随手打开一个搜索引擎, 输入关键字 Windows 消息 ID, 然后就能找到大量的文章专门讲述 windwos 消息, 博主这里找了一篇整理 Windows 消息列表的文章 Windows 消息 ID 说明, 文章中的消息基本上都有中文注释, 因此阅读起来比较容易.
然后我们就会发现有这样一个消息, 可能是我们需要的, 如下图所示.
第 130 条内容, ID 为 86 的 WM_NCACTIVATE 消息. 消息触发的实际是当某个窗口它的非客户区需要被改变来显示是激活还是非激活状态时. 听着有点儿意思, 好像是我们需要的, 然后就试呗.
Qt 接收原生消息
既然锁定了消息 ID, 那么接下来就是接收这个消息, 然后实现响应的 UI 交互效果即可.
那么问题来了, Qt 窗口怎么接收 Windows 原生消息呢!
这个问题当然难不倒我们了. Qt 为啥这么火, 可不仅仅是因为库封装的好, 而是它帮助文档更全. 下一步大家应该知道该干什么了吧, 打开帮助文档, 然后搜索关键字 nativeEv, 如果不知道函数的具体名字或者功能名字, 最好进行模糊搜索.
不搜不知道, 一搜吓一跳, 原来还有不少接收原生消息的函数, 如下不所示.
上图中总共有如下几个函数
filterNativeEvent: 安装事件过滤器的回调函数
installNativeEventFilter: 安装事件过滤器, 回调函数是第 4 个函数
nativeEvent: 窗口原生事件回调
nativeEventFilter: 事件过滤器回调函数, 使用方法 2 安装
- bool XXX::nativeEvent(const QByteArray &eventType, void *message, long *result)
- {
- if ("windows_generic_MSG" == eventType)
- {
- MSG * pMsg = reinterpret_cast<MSG *>(message);
- if (pMsg->message == WM_NCACTIVATE)
- {
- bool active = (bool)(pMsg->wParam);
- if (active)
- {
- setStyleSheet("border:2 solid blue;background:gray;");
- }
- else
- {
- setStyleSheet("border:2 solid red;background:gray;");
- }
- style()->unpolish(this);
- style()->polish(this);
- }
- }
- return QDialog::nativeEvent(eventType, message, result);
- }
来源: https://www.cnblogs.com/swarmbees/p/11568821.html