Qt之使用setWindowFlags方法遇到的問題(追蹤進入QWidget的源碼分析原因,最后用WINAPI解決問題)good


一、簡述

前段時間在使用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM