子 QMenu 中的 QPushButton,悬停时更改背景

Posted

技术标签:

【中文标题】子 QMenu 中的 QPushButton,悬停时更改背景【英文标题】:QPushButton in a sub-QMenu, change background on hover 【发布时间】:2017-04-09 05:58:27 【问题描述】:

编辑: 注意,这只发生在按钮位于子菜单中时。 (菜单中的菜单。)此代码仅适用于父菜单!

在 Windows 7 上运行 Qt 5.0.2。我有一个 QMenu 和一个 QWidgetAction。在QWidgetAction 里面是一个QPushButton。当鼠标悬停在按钮上时,我想更改按钮的背景颜色。

这是我的代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMenu>
#include <QWidgetAction>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);



MainWindow::~MainWindow()

    delete ui;


void MainWindow::on_pushButton_clicked()

    QMenu menu;
    QMenu *subMenu = new QMenu("SubMenu text");

    QWidgetAction *widgetAction = new QWidgetAction(subMenu);
    QPushButton *btn = new QPushButton("test");
    btn->setStyleSheet("QPushButton:hoverbackground-color: #ff0000;");
    widgetAction->setDefaultWidget(btn);
    subMenu->addAction(widgetAction);

    menu.addMenu(subMenu);
    menu.exec();

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui 
class MainWindow;


class MainWindow : public QMainWindow

    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
;

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    MainWindow w;

    w.show();

    return a.exec();

但是,当光标悬停在QPushButton 上时,背景颜色不会改变。不管我是否以融合风格运行它。

这里发生了什么?感谢您的宝贵时间。

【问题讨论】:

对我来说,变色有效,setCursor 不行。使用 Qt 5.8、Ubuntu 16.04 测试。 我使用的是 Qt 5.1 Windows。就像我说的,我什至对它进行了子类化,它没有得到任何鼠标事件。可能是特定于平台的吗? 不重要,但我想指出,将鼠标悬停在动作本身上确实遵循我的样式表设置。与包含在那里的 QListView 小部件类似。我还注意到,当我第一次在菜单中的微调框上调用 set enabled(true) 时,光标会变为编辑文本图标并卡在该图标上,直到我单击微调框。显然,QMenu 出现了一些问题。 Windows 是否起作用? 据我所知,悬停检测对于某些平台上的小部件操作实际上并不适用。您是否看到没有样式的悬停效果? @felix 当我有一个常规的 qmenu 时,菜单中的项目会在悬停时改变样式。我什至用 QMenu::item:hover 定制了那些没有问题。但我的问题是 QMenu 中的一些小部件(甚至是小部件内的小部件内的小部件)没有应用悬停效果。除了 QListView。这些项目接受悬停状态。 【参考方案1】:

这听起来像mouseTracking 没有在小部件上启用(和/或可能在父小部件上)。您可以通过调用来启用它

QWidget::setMouseTracking(bool enable);

【讨论】:

只需将按钮和所有父小部件的 mouseTracking 设置为 true。没有变化。 也许您必须子类化小部件才能做到这一点。 @CodeLurker 检查我的编辑,这个问题只发生在子菜单中。常规菜单完全按预期工作。【参考方案2】:
    如果不更改按钮的边框样式,则可能无法自定义背景。

如何解决:使用一些非默认样式,例如:

const auto fusion = QStyleFactory::create( "Fusion" );
QApplication::setStyle( fusion );
    QPushButton 不是为完美处理悬停事件而设计的。例如,悬停事件不会通过样式表更改字体。

如何解决:改用QToolButton

附:不知道,为什么它不适合你。对我来说一切都很好......

更新

只需复制粘贴并运行:

#include <QApplication>
#include <QWidgetAction>
#include <QMenu>
#include <QPushButton>
#include <QToolButton>
#include <QStyleFactory>


void showMenu()

    const auto parent = qApp->activeWindow();
    auto menu = new QMenu( parent );
    
    auto root = new QMenu( "Root", menu );
    menu->addMenu( root );

    auto wa = new QWidgetAction( parent );
    auto tb = new QToolButton;
    tb->setText( "ToolBtn" );
    wa->setDefaultWidget( tb );

    root->addAction( wa );

    menu->exec( QCursor::pos() );
    menu->deleteLater();



int main(int argc, char *argv[])

    QApplication a( argc, argv );

    const auto fusion = QStyleFactory::create( "Fusion" );
    const auto qss =
        "QToolButton:!hoverbackground-color: #00ff00;"
        "QToolButton:hoverbackground-color: #ff0000;"
        ;

    QApplication::setStyle( fusion );
    qApp->setStyleSheet( qss );

    QWidget w;
    w.resize( 800, 600 );
    auto btn = new QPushButton "Test", &w ;

    QObject::connect( btn, &QPushButton::clicked, &showMenu );
    w.show();

    return a.exec();

【讨论】:

当工具按钮在子菜单中时,您的代码不起作用。这仅适用于执行的主菜单。 刚刚尝试了您的确切更新代码,悬停不再有效。 @mrg95 我不知道你为什么没有结果。你做错了什么。也许别人会检查。顺便说一句,你为什么使用这么旧且有缺陷的 Qt 版本? @mrg95 再次:你为什么使用这么旧版本的 Qt。可能,如果您更新,您的问题将得到解决。我建议您至少使用 Qt 5.6.2。 @mrg95 我还是不明白,你为什么用老版本的Qt???使用 5.6.2 - 官方支持。用msvc2010搭建起来非常简单。

以上是关于子 QMenu 中的 QPushButton,悬停时更改背景的主要内容,如果未能解决你的问题,请参考以下文章

QPushButton.setMenu (self, QMenu menu) 使用从 Qt Designer 生成的代码

为啥 QToolTips 不会出现在 QMenu 中的 QActions 上

如何格式化 Qmenu 或 Toolboxes 中的特定项目?是不是可以定义伪状态或子控件?

如何向 QPushButton 添加悬停过渡?

在悬停并按下时更改 QPushButton 图标

如何在 QMenu 中隐藏子菜单