Qt之使用setWindowFlags方法遇到的问题
2017-03-31 23:58
357 查看
一、简述
前段时间在使用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); } }
解决办法二:
void onStateChanged(int state) { if (state == Qt::Unchecked) { // 未勾选时不置顶; this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint); // 如果当前窗口不可见,则显示出来; if (!this->isVisible()) { setVisible(true); } } else if (state == Qt::Checked) { // 勾选时置顶; this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowStaysOnTopHint); // 如果当前窗口不可见,则显示出来; if (!this->isVisible()) { setVisible(true); } } }
更新于2017_7_12。
相关文章推荐
- Qt之使用setWindowFlags方法遇到的问题(追踪进入QWidget的源码分析原因,最后用WINAPI解决问题)good
- QT使用遇到的种种问题和解决方法
- 使用eclipse编译qt程序遇到问题的解决方法
- QT使用时遇到的乱码问题解决方法
- 使用SourceSafe管理软件开发可能遇到的问题及解决方法
- Infragistics的NetAdvantage控件使用中遇到的问题及解决方法
- java使用String.split方法时遇到的问题(转载)
- 虚拟IP实验,遇到场景启用使用虚拟IP就报错,不启用可以正常运行的问题,解决方法
- Java使用Oracle遇到的最大游标超出问题及其解决方法
- 使用密匙让putty(或ssh)自动登录Linux遇到几个问题的解决方法
- 在xp和Win7上使用Tomcat 6.0经常遇到的几个问题及其解决方法
- 最新的PHP java bridge使用方法和遇到的问题
- 在.NET中发送邮件,使用回执功能中遇到问题的解决方法[在NOTES服务器上,C#,.NET2.0环境]
- LoadRunner在使用时遇到的问题及解决方法
- FckEditor使用时遇到的两个问题,未能加载xxxx和上传图片无响应的解决方法
- asp.net mvc 2 简简单单做开发 使用DataContext扩展方法Find<TEntity>(TEntity obj) 遇到的问题
- 使用pbrt 1.03遇到的问题和解决方法
- 使用window.open()方法时遇到的问题
- 使用Adobe PDF Reader组件遇到问题之解决方法
- 使用VIM开发软件项目 - (16) vim编译中遇到的问题及解决方法