没有阴影的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 我尝试了弹出小部件,但它得到了上面描述的阴影工件。 谁能帮忙?

在Windows Vista及更高版本上,我想要一个带有普通窗口阴影的菜单。所以我必须做两件事:

  1. 从菜单中删除CS_DROPSHADOWHWNDQt在核心深处添加的WNDCLASS
  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);

这是整个代码,享受:

菜单.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);
}

我只是删除Qt::p opup标志来摆脱阴影。 我必须将关闭代码添加到任何其他后台 UI。 这些是更多的额外工作,但我得到了我想要的:)

最新更新