原文链接:Qt无边框窗体-模拟模态窗体抖动效果

一、概述

用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错。再加上qss的辅助,那么一个漂亮的界面就不在话下了。

想要做出漂亮的界面,重写一个标题栏是必不可少的,那么我们肯定是需要使用Qt给我们提供的一个无边框Qt::FramelessWindowHint窗体属性。但是设置了这个属性以后,随之而来的就是一系列的问题,比如说标题栏拖拽需要我们自己搞;窗口放大缩小需要自己实现;最要命的是一些模态窗体原生的抖动效果没有了。

既然出现问题,那么我们就得想办法解决。

窗口放大缩小和拖拽在Qt的早期版本是提供了一个类文件支持的,作者本人也对这个文件进行了二次开发,可以提供更为丰富的功能。由于拖拽和缩放跟本篇文章关系不大,因此这里不做说明,感兴趣的同学可以到Qt无边框窗体-最大化时支持拖拽还原这里查看

本篇文章我们就来说一说当模态窗体弹出来时,如果点击了非模态窗体以外的应用程序界面,怎么实现一个闪动的效果。

闪动只是一个对外的信息交互,如果大家想要一些其他交互效果,可以自行实现。

二、效果展示

如效果图所示,做了一个简单的效果

  1. 点击主应用程序时,弹出的模态窗体边框颜色发生了变动,实现了一个抖动的效果。
  2. 点击桌面时,模态窗体也有一个失去焦点时的状态变化。

三、功能实现

实现窗口抖动效果,首先需要了解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,如果不知道函数的具体名字或者功能名字,最好进行模糊搜索。

不搜不知道,一搜吓一跳,原来还有不少接收原生消息的函数,如下不所示。

上图中总共有如下几个函数

  1. filterNativeEvent:安装事件过滤器的回调函数
  2. installNativeEventFilter:安装事件过滤器,回调函数是第4个函数
  3. nativeEvent:窗口原生事件回调
  4. nativeEventFilter:事件过滤器回调函数,使用方法2安装

看到这里大家卡能会有些迷茫,好像都差不多呀!其实不然,还是有却别的,感兴趣的同学可以看看我之前写的几篇相关文章,都使用了接收全局windows消息来实现先关功能,具体一点来说就是使用上述的方法2+方法4来完成。

  1. Qt之自定义QLineEdit右键菜单
  2. qt捕获全局windows消息
  3. Qt之股票组件-股票检索--支持搜索结果预览、鼠标、键盘操作

除过方法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);
}

重点强调

这里还需要说一点,有些同学按照文档操作了,调试时代码也走到相关位置了,但是发现没有效果,然后就开始怀疑人生了。

这里博主重点说几个可能出现错误的地方

  1. 我们的模态窗体一定要指定模态的父窗体是谁
  2. 窗体一定要设置上Qt::Dialog属性

第二点是非常关键的,很多同学都是没有设置这个属性,导致失去了效果。

四、相关文章

  1. Qt自定义的无边框Dialog 在点击其他窗口时处理闪烁效果
  2. Qt无边框窗体-最大化时支持拖拽还原
  3. Qt之自定义QLineEdit右键菜单
  4. qt捕获全局windows消息
  5. Qt之股票组件-股票检索--支持搜索结果预览、鼠标、键盘操作

值得一看的优秀文章:

  1. 财联社-产品展示
  2. 广联达-产品展示
  3. Qt定制控件列表
  4. 牛逼哄哄的Qt库
如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


Qt无边框窗体-模拟模态窗体抖动效果的更多相关文章

  1. Qt无边框窗体-最大化时支持拖拽还原

    目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...

  2. Qt 无边框拖拽实现

    Qt 无边框拖拽实现 头文件定义: class TDragProxy:public QObject { Q_OBJECT public: TDragProxy(QWidget* parent); ~T ...

  3. Qt 无边框窗体改变大小 完美实现(全部自己实现)

    近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...

  4. Qt 无边框窗体改变大小 完美实现

    近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...

  5. C#之设置无边框后如何移动窗体(转)

    转载:http://www.cnblogs.com/techmango/archive/2012/03/31/2427523.html 第一种,利用windows的消息机制来实现: 首先﹐.定义鼠標左 ...

  6. Qt无边框MainWindow如何拖动四周改变大小

    原来还有winEvent(), x11Event() and macEvent() 这些东西...不过貌似还需要找更好的办法,否则就无法跨平台了. 你需要重新处理部分窗体事件,以下代码适用于Windo ...

  7. Qt无边框,可移动窗口

    QPoint dragPosition; void MainWindow::mousePressEvent(QMouseEvent *event) { if(event->button()==Q ...

  8. Qt无边框窗口的移动、拉伸边框、鼠标滚轮缩放大小

    主要是处理窗口上鼠标的几个事件,具体代码请看下面的截图, 完整代码的下载链接在此:http://download.csdn.net/detail/beyond0824/9657110, 本示例代码中, ...

  9. 模拟QQ窗口抖动效果(通过MoveWindow和Sleep进行模拟)

    RECT rtWindow; GetWindowRect(&rtWindow); //long x = 400; //long y = 200; long x = rtWindow.left; ...

随机推荐

  1. react中babel的使用

    在开发中经常会使用到es6语法,那么如何能够很好兼容es6写法呢

  2. Json对象转Ts类

    一 目标 推荐一款在线将Json对象转换为Ts类的工具:https://apihelper.jccore.cn/jsontool 可以帮助前端开发人员提高开发效率. 二 背景 Json是一种轻量级的数 ...

  3. maven学习(3)pom.xml文件说明以及常用指令

    pom.xml文件的结构: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...

  4. 驰骋工作流引擎-ccflow单据模式介绍与使用

    Ccflow单据模式 关键字: 驰骋工作流程快速开发平台 工作流程管理系统 工作流引擎 asp.net工作流引擎 java工作流引擎.  表单引擎  表单单据模式增删改查   应用场景: 一些客户在使 ...

  5. python的魔术方法大全

    在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中有相应描述,这 ...

  6. 利用递归,反射,注解等,手写Spring Ioc和Di 底层(分分钟喷倒面试官)了解一下

    再我们现在项目中Spring框架是目前各大公司必不可少的技术,而大家都知道去怎么使用Spring ,但是有很多人都不知道SpringIoc底层是如何工作的,而一个开发人员知道他的源码,底层工作原理,对 ...

  7. Spring源码剖析7:AOP实现原理详解

    前言 前面写了六篇文章详细地分析了Spring Bean加载流程,这部分完了之后就要进入一个比较困难的部分了,就是AOP的实现原理分析.为了探究AOP实现原理,首先定义几个类,一个Dao接口: pub ...

  8. 设计模式(C#)——01单例模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321       为什么要学习设计模式呢?我以前也思考过很多次这个问题,现在也还困惑.为什么我最后还是选择了学设计模式呢?因为在游戏中 ...

  9. [转]Android中设置TextView的颜色setTextColor

    [转自]http://txlong-onz.iteye.com/blog/1249609 Android中设置TextView的颜色setTextColor android中设置TextView的颜色 ...

  10. javascript简单实现深浅拷贝

    深浅拷贝知识在我们的日常开发中还算是用的比较多,但是之前的状态一直都是只曾听闻,未曾使用(其实用了只是自己没有意识到),所以今天来跟大家聊一聊js的深浅拷贝: 首先我们来了解一下javascript的 ...