原文连接:Qt无边框窗体-模拟模态窗体抖动效果windows
用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来讲也不错。再加上qss的辅助,那么一个漂亮的界面就不在话下了。less
想要作出漂亮的界面,重写一个标题栏是必不可少的,那么咱们确定是须要使用Qt给咱们提供的一个无边框Qt::FramelessWindowHint窗体属性。可是设置了这个属性之后,随之而来的就是一系列的问题,好比说标题栏拖拽须要咱们本身搞;窗口放大缩小须要本身实现;最要命的是一些模态窗体原生的抖动效果没有了。函数
既然出现问题,那么咱们就得想办法解决。性能
窗口放大缩小和拖拽在Qt的早期版本是提供了一个类文件支持的,做者本人也对这个文件进行了二次开发,能够提供更为丰富的功能。因为拖拽和缩放跟本篇文章关系不大,所以这里不作说明,感兴趣的同窗能够到Qt无边框窗体-最大化时支持拖拽还原这里查看this
本篇文章咱们就来讲一说当模态窗体弹出来时,若是点击了非模态窗体之外的应用程序界面,怎么实现一个闪动的效果。搜索引擎
闪动只是一个对外的信息交互,若是你们想要一些其余交互效果,能够自行实现。spa
如效果图所示,作了一个简单的效果.net
实现窗口抖动效果,首先须要了解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
,若是不知道函数的具体名字或者功能名字,最好进行模糊搜索。
不搜不知道,一搜吓一跳,原来还有很多接收原生消息的函数,以下不所示。
上图中总共有以下几个函数
看到这里你们卡能会有些迷茫,好像都差很少呀!其实否则,仍是有却别的,感兴趣的同窗能够看看我以前写的几篇相关文章,都使用了接收全局windows消息来实现先关功能,具体一点来讲就是使用上述的方法2+方法4来完成。
除过方法2和方法4搭配起来使用外,方法1和方法2也能够一块儿搭配使用,言外之意就是方法2是按照事件过滤器的,方法1和方法4只是事件过滤器的回调处理接口而已。
为何这么说呢,你们能够来验证一下,仍是打开帮助文档,咱们输入关键字installNativeEventFilter
,回车就会发现,事件过滤器能够被安装到两个对象上,一个是咱们熟知的QCoreApplication,另一个看着好像也会牛逼的样子,好像仍是一个全局的抽象事件派发器。恭喜你,答对了,这两个对象都很牛逼,都能优先处理到Qt的全局事件。
本篇文章咱们只是要实现一个模态窗体的抖动而已,所以就不须要大材小用了,咱们使用QWidget的nativeEvent函数便可,一样能达到咱们的目的。
大方向都定了,那么还等什么
打开vs,新建了一个demo。哐哐哐,就是一顿干。。。。
发现还真好使,窃喜中。。。
下面是实现的核心代码,因为是demo,因此写的比较粗糙,你们在写到项目里时最好能规范下代码。
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); }
重点强调
这里还须要说一点,有些同窗按照文档操做了,调试时代码也走到相关位置了,可是发现没有效果,而后就开始怀疑人生了。
这里博主重点说几个可能出现错误的地方
第二点是很是关键的,不少同窗都是没有设置这个属性,致使失去了效果。
值得一看的优秀文章:
![]() |
![]() |
很重要--转载声明