1. 程式人生 > >Qt中QMenu的菜單關閉處理方法

Qt中QMenu的菜單關閉處理方法

焦點 n) 奇葩 exe ase 最終 con pre code

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展開消息循環後, 直接截獲所有事件, 這樣用戶在桌面上的任意點擊都能捕獲到, 還有按鍵消息也一樣.

Qt中QMenu的菜單關閉處理方法