一、简述

前段时间在使用setWindowFlags方法时遇到了一个坑,具体情况是想通过窗口界面上一个checkBox来控制窗口当前状态是否置顶,而Qt提供了Qt::WindowStaysOnTopHint标志,能够让窗口始终保持在其他窗口前端,也就是将窗口置顶。

理论上,我们在勾选上checkBox之后将Qt::WindowStaysOnTopHint标志设置上,就会将窗口置顶,结果却将窗口隐藏了。那么为什么第二次调用setWindowFlags设置窗口标志位时窗口会隐藏了呢(实际上调用了hide()方法),下面就看一下具体是什么原因导致的。

Qt::WindowStaysOnTopHint

Informs the window system that the window should stay on top of all other windows. Note that on some window managers on X11 you also have to pass Qt::X11BypassWindowManagerHint for this flag to work correctly.

二、分析窗口隐藏原因

首先我们看一下代码,在构造函数中我们绑定checkBox,然后设置窗口属性。

this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
connect(ui.checkBox, SIGNAL(stateChanged(int)), this, SLOT(onStateChanged(int)));

checkBox状态变化槽函数

void onStateChanged(int state)
{
if (state == Qt::Unchecked)
{
// 未勾选时不置顶;
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
}
else if (state == Qt::Checked)
{
// 勾选时置顶;
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowStaysOnTopHint);
}
}

想要查找原因,那就得直接看Qt源码呀,所以就直接跟进了qwidget.cpp中的setWindowFlags方法。

调试之后,发现进入了setParent方法,我们仔细看一下,在setParent方法中确实会调用hide方法,那什么时候会调用呢,首先是判断窗口是否被创建,然后是窗口是否被隐藏,也就是如果窗口被创建并且没有被隐藏时会调用hide方法。下面是在构造函数中调用setWindowFlags时,wasCreated为false,也不会调用hide,而且当时窗口并未创建,所以在窗口未创建时无论调用多少次setWindowFlags方法,都会以最后一次调用时传入的参数为准。


下面是在窗口中勾选了checkBox,然后再次调用了setWindowFlags方法,此时满足窗口被创建并且没有被隐藏条件,所以这里调用了hide方法将窗口隐藏了,终于找到了原因。


那么也不是没有办法解决窗口置顶问题,windows提供了SetWindowPos方法解决了窗口置顶的问题。如果我们想一直保持窗口置顶状态也可以在窗口初始化时调用setWindowFlags方法传入Qt::WindowStaysOnTopHint标志即可使窗口置顶。

如果两个窗口都是置顶状态,如果层叠在一起也会相互覆盖。

void onStateChanged(int state)
{
if (state == Qt::Unchecked)
{
::SetWindowPos((HWND)this->winId(), HWND_NOTOPMOST, this->pos().x(), this->pos().y(), width(), height(), SWP_SHOWWINDOW);
}
else if (state == Qt::Checked)
{
::SetWindowPos((HWND)this->winId(), HWND_TOPMOST, this->pos().x(), this->pos().y(), width(), height(), SWP_SHOWWINDOW);
}
}
 
 

http://blog.csdn.net/goforwardtostep/article/details/68938965

Qt之使用setWindowFlags方法遇到的问题(追踪进入QWidget的源码分析原因,最后用WINAPI解决问题)good的更多相关文章

  1. equals和==方法比较(三)--Long中LongCache源码分析

    下面我们来分析,上篇博客中遗留的问题,为什么下方的两个一个是true,两一个是false那? //true Long l1=123l; Long l2=123l; System.out.println ...

  2. equals和==方法比较(二)--Long中equals源码分析

    接上篇,分析equals方法在Long包装类中的重写,其他类及我们自定义的类,同样可以根据需要重新equals方法. equals方法定义 equals方法是Object类中的方法,java中所有的对 ...

  3. QT源码分析(从QApplication开始)

    QT源码分析 转载自:http://no001.blog.51cto.com/1142339/282130 今天,在给同学讲东西的时候,谈到了Qt源代码的问题,才发现自己对Qt机制的了解是在太少了,而 ...

  4. ABP源码分析十五:ABP中的实用扩展方法

    类名 扩展的类型 方法名 参数 作用 XmlNodeExtensions XmlNode GetAttributeValueOrNull attributeName Gets an   attribu ...

  5. jQuery实现DOM加载方法源码分析

    传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但 ...

  6. jQuery原型方法.pushStack源码分析

    这次分析的方法跟前面不同,虽然pushStack也是原型方法之一,但是我们几乎从不用在页面调用,在参考手册里面也没有这个方法的使用说明,但是这个方法还是非常重要的,在使用很多jQuery的其他方式都会 ...

  7. jQuery原型属性constructor,selector,length,jquery和原型方法size,get,toArray源码分析

    首先看一下在jQuery1.7.1中定义的原型属性和方法有哪些? init方法作为实际的构造函数已经详细分析过了,需要了解可以参考http://www.cnblogs.com/yy-hh/p/4492 ...

  8. jQuery.extend()方法和jQuery.fn.extend()方法源码分析

    这两个方法用的是相同的代码,一个用于给jQuery对象或者普通对象合并属性和方法一个是针对jQuery对象的实例,对于基本用法举几个例子: html代码如下: <!doctype html> ...

  9. jQuery.clean()方法源码分析(一)

    在jQuery 1.7.1中调用jQuery.clean()方法的地方有三处,第一次就是在我之前的随笔分析jQuery.buildFramgment()方法里面的,其实还是构造函数的一部分,在处理诸如 ...

随机推荐

  1. C++对象模型——对象成员的效率 (Object Member Efficiency)(第三章)

    3.5 对象成员的效率 (Object Mem ber Efficiency) 以下某个測试,目的在測试聚合(aggregation).封装(encapsulation),以及继承(Inheritan ...

  2. PHP移动互联网开发笔记(4)——自定义函数及数组

    一.自定义函数 自定义函数就是我们自己定义的函数,在PHP中自定义函数格式如下: function funname(arg1, arg2, arg3......){ //TODO return val ...

  3. php正则怎么使用(最全最细致)

    php正则怎么使用(最全最细致) 一.总结 一句话总结: 1.正则中的行定位符是什么? 解答:(^与$) 2.正则中什么时候用行定位符? 解答:如"^de",表示以de开头的字符串 ...

  4. Erlang 杂记

    学习Erlang的时候在书的留白处随手记录了一些东西,还有一些记录在了demo的注释里面,今天抽时间整理出来了一部分,分享一下. Erlang的设计哲学是为每一个独立的事件创建一个新进程. Erlan ...

  5. 【序列操作IV】树状数组套线段树/树套树

    题目描述 给出序列 a1,a2,…,an(0≤ai≤109),有关序列的两种操作. 1. ai(1≤i≤n)变成 x(0≤x≤109). 2. 求 al,al+1,…,ar(1≤l≤r≤n)第 k(1 ...

  6. hive 分区表与数据产生关联的三种方式

    所谓关联,可以理解为能够使用select查询到 1.load 这是最常用的一种方式 load data [local] inpath "数据路径" into table table ...

  7. Android菜鸟的成长笔记(21)——跨进程调用Service

    我们都知道在Android中的每一个应用是一个进程,其实每一个应用就相当于Linux系统里面的一个用户,进程和进程之间的通信其实就相当于用户和用户之间的通信,为了实现这种跨进程通信,Android提供 ...

  8. Spring4+Springmvc+quartz实现多线程动态定时调度

    scheduler定时调度系统是大多行业项目都需要的,传统的spring-job模式,个人感觉已经out了,因为存在很多的问题,特别是定时调度的追加.修改.删除等,需要修改xml,xml的配置生效无非 ...

  9. JS事件处理函数中return false到底是什么东西

    在<JS DOM编程艺术>一书中,用return false来阻止事件默认行为,可是js高程3里没有这种用法,那这到底是什么呢. 先看一下知乎的一个解释 就此问题,首先要纠正两个观点: 1 ...

  10. 多线程编程 CreateThread(解释了TContext)

    function CreateThread( lpThreadAttributes: Pointer;           {安全设置} dwStackSize: DWORD;             ...