目錄
* 一、概述 <https://www.cnblogs.com/swarmbees/p/11568821.html#一概述>
* 二、效果展示 <https://www.cnblogs.com/swarmbees/p/11568821.html#二效果展示>
* 三、功能實(shí)現(xiàn) <https://www.cnblogs.com/swarmbees/p/11568821.html#三功能實(shí)現(xiàn)>
* 四、相關(guān)文章 <https://www.cnblogs.com/swarmbees/p/11568821.html#四相關(guān)文章>
原文鏈接:Qt無邊框窗體-模擬模態(tài)窗體抖動(dòng)效果 <https://www.cnblogs.com/swarmbees/p/11568821.html>
一、概述
用Qt開發(fā)windows客戶端界面確實(shí)是一大利器,兼顧性能的同時(shí),速度相對(duì)來說也不錯(cuò)。再加上qss的輔助,那么一個(gè)漂亮的界面就不在話下了。
想要做出漂亮的界面,重寫一個(gè)標(biāo)題欄是必不可少的,那么我們肯定是需要使用Qt給我們提供的一個(gè)無邊框Qt::FramelessWindowHint窗體屬性。但是設(shè)置了這個(gè)屬性以后,隨之而來的就是一系列的問題,比如說標(biāo)題欄拖拽需要我們自己搞;窗口放大縮小需要自己實(shí)現(xiàn);最要命的是一些模態(tài)窗體原生的抖動(dòng)效果沒有了。
既然出現(xiàn)問題,那么我們就得想辦法解決。
窗口放大縮小和拖拽在Qt的早期版本是提供了一個(gè)類文件支持的,作者本人也對(duì)這個(gè)文件進(jìn)行了二次開發(fā),可以提供更為豐富的功能。由于拖拽和縮放跟本篇文章關(guān)系不大,因此這里不做說明,感興趣的同學(xué)可以到
Qt無邊框窗體-最大化時(shí)支持拖拽還原 <https://www.cnblogs.com/swarmbees/p/11415829.html>這里查看
本篇文章我們就來說一說當(dāng)模態(tài)窗體彈出來時(shí),如果點(diǎn)擊了非模態(tài)窗體以外的應(yīng)用程序界面,怎么實(shí)現(xiàn)一個(gè)閃動(dòng)的效果。
閃動(dòng)只是一個(gè)對(duì)外的信息交互,如果大家想要一些其他交互效果,可以自行實(shí)現(xiàn)。
二、效果展示
如效果圖所示,做了一個(gè)簡單的效果
* 點(diǎn)擊主應(yīng)用程序時(shí),彈出的模態(tài)窗體邊框顏色發(fā)生了變動(dòng),實(shí)現(xiàn)了一個(gè)抖動(dòng)的效果。
* 點(diǎn)擊桌面時(shí),模態(tài)窗體也有一個(gè)失去焦點(diǎn)時(shí)的狀態(tài)變化。
三、功能實(shí)現(xiàn)
實(shí)現(xiàn)窗口抖動(dòng)效果,首先需要了解windows的消息ID,知道我們要接受哪個(gè)windows消息來完成閃動(dòng)效果,其次就是Qt怎么接收這樣的原生windows消息。
windowws消息
了解windows消息ID,隨手打開一個(gè)搜索引擎,輸入關(guān)鍵字Windows消息ID
,然后就能找到大量的文章專門講述windwos消息,博主這里找了一篇整理windows消息列表的文章Windows消息ID說明
<https://www.cnblogs.com/easypass/archive/2011/04/25/2028629.html>
,文章中的消息基本上都有中文注釋,因此閱讀起來比較容易。
然后我們就會(huì)發(fā)現(xiàn)有這樣一個(gè)消息,可能是我們需要的,如下圖所示。
第130條內(nèi)容,ID為86的WM_NCACTIVATE消息。消息觸發(fā)的實(shí)際是當(dāng)某個(gè)窗口它的非客戶區(qū)需要被改變來顯示是激活還是非激活狀態(tài)時(shí)。
聽著有點(diǎn)兒意思,好像是我們需要的,然后就試唄。
Qt接收原生消息
既然鎖定了消息ID,那么接下來就是接收這個(gè)消息,然后實(shí)現(xiàn)響應(yīng)的UI交互效果即可。
那么問題來了,Qt窗口怎么接收windows原生消息呢!
這個(gè)問題當(dāng)然難不倒我們了。Qt為啥這么火,可不僅僅是因?yàn)閹旆庋b的好,而是它幫助文檔更全。下一步大家應(yīng)該知道該干什么了吧,打開幫助文檔,然后搜索關(guān)鍵字
nativeEv,如果不知道函數(shù)的具體名字或者功能名字,最好進(jìn)行模糊搜索。
不搜不知道,一搜嚇一跳,原來還有不少接收原生消息的函數(shù),如下不所示。
上圖中總共有如下幾個(gè)函數(shù)
* filterNativeEvent:安裝事件過濾器的回調(diào)函數(shù)
* installNativeEventFilter:安裝事件過濾器,回調(diào)函數(shù)是第4個(gè)函數(shù)
* nativeEvent:窗口原生事件回調(diào)
* nativeEventFilter:事件過濾器回調(diào)函數(shù),使用方法2安裝
看到這里大家卡能會(huì)有些迷茫,好像都差不多呀!其實(shí)不然,還是有卻別的,感興趣的同學(xué)可以看看我之前寫的幾篇相關(guān)文章,都使用了接收全局windows消息來實(shí)現(xiàn)先關(guān)功能,具體一點(diǎn)來說就是使用上述的方法2+方法4來完成。
* Qt之自定義QLineEdit右鍵菜單 <https://www.cnblogs.com/swarmbees/p/6044361.html>
* qt捕獲全局windows消息 <https://www.cnblogs.com/swarmbees/p/>
* Qt之股票組件-股票檢索--支持搜索結(jié)果預(yù)覽、鼠標(biāo)、鍵盤操作
<https://www.cnblogs.com/swarmbees/p/11154821.html>
除過方法2和方法4搭配起來使用外,方法1和方法2也可以一起搭配使用,言外之意就是方法2是按照事件過濾器的,方法1和方法4只是事件過濾器的回調(diào)處理接口而已。
為什么這么說呢,大家可以來驗(yàn)證一下,還是打開幫助文檔,我們輸入關(guān)鍵字installNativeEventFilter
,回車就會(huì)發(fā)現(xiàn),事件過濾器可以被安裝到兩個(gè)對(duì)象上,一個(gè)是我們熟知的QCoreApplication,另外一個(gè)看著好像也會(huì)牛逼的樣子,好像還是一個(gè)全局的抽象事件派發(fā)器。恭喜你,答對(duì)了,這兩個(gè)對(duì)象都很牛逼,都能優(yōu)先處理到Qt的全局事件。
本篇文章我們只是要實(shí)現(xiàn)一個(gè)模態(tài)窗體的抖動(dòng)而已,因此就不需要大材小用了,我們使用QWidget的nativeEvent函數(shù)即可,同樣能達(dá)到我們的目的。
大方向都定了,那么還等什么
打開vs,新建了一個(gè)demo。哐哐哐,就是一頓干。。。。
發(fā)現(xiàn)還真好使,竊喜中。。。
下面是實(shí)現(xiàn)的核心代碼,由于是demo,所以寫的比較粗糙,大家在寫到項(xiàng)目里時(shí)最好能規(guī)范下代碼。
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); }
重點(diǎn)強(qiáng)調(diào)
這里還需要說一點(diǎn),有些同學(xué)按照文檔操作了,調(diào)試時(shí)代碼也走到相關(guān)位置了,但是發(fā)現(xiàn)沒有效果,然后就開始懷疑人生了。
這里博主重點(diǎn)說幾個(gè)可能出現(xiàn)錯(cuò)誤的地方
* 我們的模態(tài)窗體一定要指定模態(tài)的父窗體是誰
* 窗體一定要設(shè)置上Qt::Dialog屬性
第二點(diǎn)是非常關(guān)鍵的,很多同學(xué)都是沒有設(shè)置這個(gè)屬性,導(dǎo)致失去了效果。
四、相關(guān)文章
* Qt自定義的無邊框Dialog 在點(diǎn)擊其他窗口時(shí)處理閃爍效果
<https://blog.csdn.net/r5014/article/details/70172375>
* Qt無邊框窗體-最大化時(shí)支持拖拽還原 <https://www.cnblogs.com/swarmbees/p/11415829.html>
* Qt之自定義QLineEdit右鍵菜單 <https://www.cnblogs.com/swarmbees/p/6044361.html>
* qt捕獲全局windows消息 <https://www.cnblogs.com/swarmbees/p/>
* Qt之股票組件-股票檢索--支持搜索結(jié)果預(yù)覽、鼠標(biāo)、鍵盤操作
<https://www.cnblogs.com/swarmbees/p/11154821.html>
值得一看的優(yōu)秀文章:
* 財(cái)聯(lián)社-產(chǎn)品展示 <https://www.cnblogs.com/swarmbees/p/6707798.html>
* 廣聯(lián)達(dá)-產(chǎn)品展示 <https://www.cnblogs.com/swarmbees/p/10836505.html>
* Qt定制控件列表 <https://blog.csdn.net/qq_30392343/article/details/95527107>
* 牛逼哄哄的Qt庫 <https://blog.csdn.net/qq_30392343/article/details/95526527>
如果您覺得文章不錯(cuò),不妨給個(gè)打賞,寫作不易,感謝各位的支持。您的支持是我最大的動(dòng)力,謝謝?。?!
很重要--轉(zhuǎn)載聲明
*
本站文章無特別說明,皆為原創(chuàng),版權(quán)所有,轉(zhuǎn)載時(shí)請(qǐng)用鏈接的方式,給出原文出處。同時(shí)寫上原作者:朝十晚八
<https://www.cnblogs.com/swarmbees/> or Twowords
<https://www.jianshu.com/u/7673f8cfb4e6>
*
如要轉(zhuǎn)載,請(qǐng)?jiān)霓D(zhuǎn)載,如在轉(zhuǎn)載時(shí)修改本文,請(qǐng)事先告知,謝絕在轉(zhuǎn)載時(shí)通過修改本文達(dá)到有利于轉(zhuǎn)載者的目的。
熱門工具 換一換