以下内容引用自
http://www.cnblogs.com/lingdhox/p/3474404.html
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事件循環嵌套