Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
没有shaodw的Qt菜单?_Qt_Menu - Fatal编程技术网

没有shaodw的Qt菜单?

没有shaodw的Qt菜单?,qt,menu,Qt,Menu,我从其他被问但未回答的问题中复制了下面的问题描述,因为这与我想问的问题完全相同 我有一个半透明背景和圆形边缘(边界半径)的QMenu。不幸的是,Windows 7为此菜单绘制了一个阴影,该阴影不适合圆角。它是为普通矩形菜单绘制的阴影 是否有一种方法可以完全禁用QMenu的绘图放置阴影,或者有一种方法可以使阴影适合圆角边缘 下面是一个出现这种情况的极简示例: QPushButton b("press me"); QMenu m; m.addAction("hello"); m.addAction(

我从其他被问但未回答的问题中复制了下面的问题描述,因为这与我想问的问题完全相同

我有一个半透明背景和圆形边缘(边界半径)的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的饼状菜单的菜单,或者是这样的菜单: 我尝试了弹出窗口小部件,但它得到了上面描述的阴影工件。
谁能帮上忙

我只是删除了Qt::popup标志以去除阴影。
我必须给任何其他后台用户界面添加关闭代码。这些都是额外的工作,但我得到了我想要的:)

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

  • 从Qt在内核深处添加的菜单
    HWND
    WNDCLASS
    中删除
    CS\u DROPSHADOW
  • 使用DWMAPI添加阴影
  • 技巧是捕获
    QEvent::WinIdChange
    以获取菜单窗口的
    HWND
    句柄,然后使用
    GetClassLong
    /
    SetClassLong
    删除
    CS\u DROPSHADOW
    标志。我只做了一次(通过使用
    静态bool
    ),因为
    WNDCLASS
    对于所有菜单都是相同的。如果应用程序的一部分想要显示菜单阴影,而另一部分不想显示,这可能会导致问题

    我已经对
    QMenu
    进行了子类化,并且在创建菜单时总是使用覆盖的类

    Menu * my_menu = new Menu(tr("&File"));
    mainMenu->addMenu(my_menu);
    
    以下是全部代码,请欣赏:

    菜单

    #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
    
    \ifndef菜单
    #定义菜单
    #包括
    类菜单:公共QMenu
    {
    Q_对象
    公众:
    显式菜单(QWidget*parent=0);
    显式菜单(常量字符串和标题);
    受保护的:
    虚拟布尔事件(QEvent*事件);
    信号:
    公众时段:
    };
    #endif//菜单
    
    menu.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);
    }
    
    #包括“menu.h”
    #pragma注释(lib,“dwmapi.lib”)
    #包括“dwmapi.h”
    菜单::菜单(QWidget*父项):
    QMenu(父项)
    {
    }
    菜单::菜单(常量字符串和标题):
    QMenu(标题)
    {
    }
    bool菜单::事件(QEvent*事件)
    {
    静态布尔类_修正=假;
    如果(事件->类型()==QEvent::WinIdChange)
    {
    HWND HWND=reinterpret_cast(winId());
    如果(类_修正==假)
    {
    第u类修正=真;
    DWORD class_风格=::GetClassLong(hwnd,GCL_风格);
    class_style&=~CS_DROPSHADOW;
    ::SetClassLong(hwnd,GCL_样式,class_样式);
    }
    DWMNCRENDERINGPOLICY val=DWMNCRP_已启用;
    ::DwmSetWindowAttribute(hwnd、DWMWA_NCRENDERING_POLICY和val、sizeof(DWMNCRENDERINGPOLICY));
    //这将关闭阴影
    //边距m={0};
    //这将打开阴影
    边距m={-1};
    HRESULT hr=::dwmextendframeintoclienterea(hwnd,&m);
    如果(成功(hr))
    {
    //多做事
    }
    }
    返回QWidget::事件(event);
    }
    
    我认为,在这种情况下,您需要选择非本机外观,而不是按默认值使用Qt的本机外观。Qt试图模仿操作系统的小部件。为了显示菜单,Qt使用一个专用窗口(它不只是在底层小部件上绘制菜单)。Windows操作系统决定向Qt无法控制的窗口添加阴影。我唯一的想法是为QMenu尝试不同的窗口标志。否则,不要使用本机QMenu并绘制自己的QMenu。但是事情变得复杂了…谢谢你的回复!说如果我想画我自己的,你能给我更多的提示吗??非常感谢!创建一个显示菜单项的自定义菜单小部件。实现鼠标悬停效果以突出显示当前菜单项。要管理和显示项目,您可以创建一个自定义的MenuItem小部件,或者只对项目使用QStringList,这取决于您希望的灵活性级别以及您希望在这方面投入多少精力。然而,根据你的技能水平,不要期望在几小时或几天内得到合理的结果。。。但是一旦你有了这个,你可以根据你的需要扩展你的菜单。圆角,圆角阴影,动画等等,我强烈建议你重新思考,如果你真的想这样做只是为了实现圆角。我告诉过你你能做些什么来实现这一点,但在我看来,这不值得付出努力。也许其他人知道如何调整
    QMenu
    以禁用本机阴影效果。也许你忽略了一个窗口标志。我刚刚尝试了其他窗口标志,是的,我消除了阴影,但我失去了弹出窗口标志提供的功能:单击菜单区域以外的屏幕区域将关闭菜单。这是一种模仿这些的方法吗?我是否必须向所有其他bg小部件添加关闭代码??至于我自己画菜单,主要问题是我要在哪里画画?如果我在应该拥有这些菜单的小部件上绘制,菜单将不会超出该小部件的框架。所以我必须打开一个全屏透明的小部件,把我的菜单画成它的内容?