2012-12-08 85 views
0

我從以下複製問題描述從其他問,但沒有回答的問題,因爲這是我想問的同一個問題。Qt菜單沒有褪色?

我有一個帶半透明背景和圓角邊緣(邊框半徑)的QMenu。不幸的是,Windows 7爲這個菜單繪製了一個陰影,這不適合圓角邊緣。它的陰影將爲正常的矩形菜單畫出。

是否有 - 一種方法可以完全禁用QMenu的繪製陰影或者 - 使陰影適合圓角邊緣的方法?

這裏是它發生簡約的例子:

QPushButton b("press me"); 
QMenu m; 
m.addAction("hello"); m.addAction("world"); 
m.setWindowFlags(m.windowFlags() | Qt::FramelessWindowHint); 
m.setAttribute(Qt::WA_TranslucentBackground); 
m.setStyleSheet("background:rgba(255,0,0,50%); border-radius:5px;"); 
b.setMenu(&m); 
b.show(); 

現在我不得不關閉Windows控制面板中的菜單陰影手動擺脫陰影。 其實我想要存檔,是像qt的餡餅菜單菜單,或像這樣的菜單: http://upload.wikimedia.org/wikipedia/commons/8/85/Blender_2.36_Screenshot.jpg 我試過彈出窗口小部件,但它獲得上面描述的陰影工件。 任何人都可以幫助解決這個問題嗎?

+0

我認爲這種情況下,你想選擇一個非本地外觀和感覺,在本機外觀和感覺,默認情況下使用Qt。 Qt試圖類似於操作系統的小部件。爲了顯示一個菜單,Qt使用了一個專用窗口(它不會簡單地在底層窗口部件上繪製菜單)。 Windows操作系統決定爲這個窗口添加一個陰影,而Qt沒有任何控制權。我唯一的想法是爲QMenu嘗試不同的窗口標誌。否則,請不要使用本機QMenu並繪製自己的。但是這變得複雜... – leemes

+0

感謝您的回覆!說如果我想畫我自己的,你能給我更多的提示嗎?非常感謝! – miguel

+0

創建一個顯示菜單條目的自定義菜單部件。實現鼠標懸停效果以突出顯示當前菜單項。要管理和顯示這些項目,您可以創建一個自定義的MenuItem小部件或僅爲項目使用QStringList,這取決於您想要的靈活性級別以及您想要投入多少努力。但是,根據您的技能水平,不要期望在少於幾個小時或幾天內就能獲得合理的結果......但是,一旦擁有此功能,您可以根據需要擴展菜單。圓角,圓角投影,動畫,... – leemes

回答

1

在Windows Vista和更高版本中,我想要一個具有普通窗口陰影的菜單。因此,我不得不做兩件事情:

  1. 從菜單HWNDWNDCLASS使用Qt被添加在覈心深處,刪除CS_DROPSHADOW
  2. 使用DWM API添加陰影。

關鍵是要抓住QEvent::WinIdChange得到HWND句柄菜單窗口,然後使用GetClassLong/SetClassLong刪除CS_DROPSHADOW標誌。我只做了一次(使用static bool),因爲WNDCLASS對於所有菜單總是相同的。如果你的應用程序的一部分想要顯示菜單陰影而其他則不顯示,則這可能會導致問題。

我有子類的QMenu和創建菜單

Menu * my_menu = new Menu(tr("&File")); 
mainMenu->addMenu(my_menu); 

這裏是整個代碼時,我總是用我的被覆蓋的類,可享受:

menu.h

#ifndef MENU_H 
#define MENU_H 

#include <QMenu> 

class Menu : public QMenu 
{ 
    Q_OBJECT 
public: 
    explicit Menu(QWidget *parent = 0); 
    explicit Menu(const QString & title); 

protected: 
    virtual bool event(QEvent *event); 

signals: 

public slots: 

}; 

#endif // MENU_H 

菜單.cpp

#include "menu.h" 

#pragma comment(lib, "dwmapi.lib") 
#include "dwmapi.h" 

Menu::Menu(QWidget *parent) : 
    QMenu(parent) 
{ 

} 

Menu::Menu(const QString &title) : 
    QMenu(title) 
{ 

} 



bool Menu::event(QEvent *event) 
{ 
    static bool class_amended = false; 
    if (event->type() == QEvent::WinIdChange) 
    { 
     HWND hwnd = reinterpret_cast<HWND>(winId()); 
     if (class_amended == false) 
     { 
      class_amended = true; 
      DWORD class_style = ::GetClassLong(hwnd, GCL_STYLE); 
      class_style &= ~CS_DROPSHADOW; 
      ::SetClassLong(hwnd, GCL_STYLE, class_style); 
     } 
     DWMNCRENDERINGPOLICY val = DWMNCRP_ENABLED; 
     ::DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &val, sizeof(DWMNCRENDERINGPOLICY)); 

     // This will turn OFF the shadow 
     // MARGINS m = {0}; 
     // This will turn ON the shadow 
     MARGINS m = {-1}; 
     HRESULT hr = ::DwmExtendFrameIntoClientArea(hwnd, &m); 
     if(SUCCEEDED(hr)) 
     { 
      //do more things 
     } 
    } 
    return QWidget::event(event); 
} 
0

我只是刪除Qt :: popup標誌來擺脫陰影。 而且我必須添加關閉代碼到任何其他的後臺用戶界面。這些都是額外的工作,但我得到了我想要的:)