Qt中qmenu的實現三四千行...
當初有個特殊的需求, 要求菜單的周邊帶幾個像素的陰影, 琢磨了半天, 用QMenu做不來, 就干脆自己用窗口寫一個
然而怎么讓菜單消失卻非常麻煩
1. 點擊菜單項
2. 點擊其他地方
3. 被其他窗口遮擋
4. 按鍵啊
然后用判斷焦點的方法吭哧吭哧寫了, 做法類似彈出一個自動關閉的窗口.
但是菜單是可以多級的, 這就造成非常惡心的焦點傳遞. 雖然最終處理好了(代碼好惡心- -!, 自己看得都想吐)
可惜天不遂人願, 但其他窗口一起搶焦點的時候, 我的菜單就變成奇葩了. 想來想去也想不出解決方案來
終於還是看Qt的源碼把.
看完之后, 豁然開朗, 想想自己以前怎么那么2呢. 簡直是2到家了.
關鍵就是幾行代碼:
QAction *QMenu::exec(const QPoint &p, QAction *action) { ............ QEventLoop eventLoop; d->eventLoop = &eventLoop; ................ (void) eventLoop.exec(); ................... }
QMenu 繼承自QWiget, 並設置Qt::Popup類型
然后在下面幾個事件中處理關閉即可.
mousePressEvent
mouseReleaseEvent
keyPressEvent
原因在於QEventLoop::exec展開消息循環后, 直接截獲所有事件, 這樣用戶在桌面上的任意點擊都能捕獲到, 還有按鍵消息也一樣.
關於eventloop嵌套, 可以看這篇文章, 亂談Qt事件循環嵌套