0

EDIT: NOTE this only occurs when the button is in a SUBMENU. (Menu in a menu.) This code works fine only on the parent menu!

Running Qt 5.0.2, on Windows 7. I have a QMenu with a QWidgetAction in it. Inside the QWidgetAction is a QPushButton. I would like to change the background color of the button when the mouse hovers over it.

Here is my code:

#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:hover{background-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();
}

However when the cursor hovers over the QPushButton the background color doesn't change. Doesn't matter if I run it in fusion style or not.

What is going on here? Thanks for your time.

mrg95
  • 2,371
  • 11
  • 46
  • 89
  • For me, color changing works, setCursor not. Tested with Qt 5.8, Ubuntu 16.04. – m7913d Apr 09 '17 at 09:46
  • I'm on Qt 5.1 Windows. Like I said, I even subclassed it and it wasn't getting any mouse events. Could be platform specific? – mrg95 Apr 09 '17 at 11:53
  • Not if it matters, but I would like to point out that hovering over the actions themselves does follow my stylesheet settings. Likewise with QListView widgets that are contained there. I also noticed that when I call set enabled(true) on a spinbox in a menu, on the first time, the cursor changes to the edit text icon and gets stuck with that icon until I click on the spinbox. Clearly something is glitching out bad with QMenu. Does Windows play a role? – mrg95 Apr 09 '17 at 12:07
  • As far as I know, hover detection does not really work for widgets actions on some platforms. Do you see hover effects without a style? – Felix Apr 09 '17 at 18:30
  • @felix when I have a regular qmenu, the items in the menu change styles upon hover. I've even customized those with QMenu::item:hover with no problems. But my issue is that some widgets that are in the QMenu (even widgets within widgets within widgets) no hover effect is applied. Except for QListView. Those items accept hover states. – mrg95 Apr 10 '17 at 03:21
  • A Widget action is *not* a normal action. They are handled differently. – Felix Apr 10 '17 at 21:07
  • @Felix In what way are they different may I ask? How does it explain hover working for QListView items but not other widgets? – mrg95 Apr 10 '17 at 21:09
  • It depends on the platform. Unlike normal windows, where Qt controls the whole window, and can draw however it wants, menus are to some extend native. They are drawing by the OS and provide less integration for custom drawing. Thus, hover effects, as an example, may not work properly. If you start your app with the Fusion style, they should work (run app with `-style fusion`). – Felix Apr 10 '17 at 21:11
  • I don't know if thats the case on windows, but on some platforms it's the case. This sounds like it's for windows true as well – Felix Apr 10 '17 at 21:12
  • @Felix So what do you think could be a possible workaround? Because right now I have glitchy cursors and absolutely no events... A large core of my software relies on widgets in context menus. Like... a lot. – mrg95 Apr 10 '17 at 21:56
  • Does it work with the Fusion Style? That would be a workaround. (If it works with `-style fusion`, I can post an answer explaining how to do it from code) – Felix Apr 11 '17 at 10:15
  • When I ran it with style fusion, the logic of my code changed for some reason. My whole program is running differently, to the point where the option to open the qmenu isn't available (since it's dependent on many dynamic factors). Why is the logic different from changing the style to fusion? – mrg95 Apr 11 '17 at 11:58
  • I just tried it in a standalone application with fusion style, and the button still doesnt change on hover – mrg95 Apr 11 '17 at 12:03
  • I have tested the code and have not had any problems. You could show more code. – eyllanesc Apr 12 '17 at 22:38
  • @eyllanesc That is literally all the code and the problem persists. Edited my question to show the entire project. I'm on Windows 7 – mrg95 Apr 13 '17 at 02:48
  • The change is almost imperceptible because the default color of the button and to which you have changed it are very similar. – eyllanesc Apr 13 '17 at 03:00
  • @eyllanesc changed it to red. still nothing – mrg95 Apr 13 '17 at 03:09
  • I recommend that you use windows in your question since in linux there is no such problem. – eyllanesc Apr 13 '17 at 03:16
  • @eyllanesc Added that to my question. Thanks. And yeah Felix already confirmed it works on Linux – mrg95 Apr 13 '17 at 03:19
  • You sample works fine on Windows 7 with Qt versions 4.8, 5.6, 5.7. So looks like it's bug of you current Qt version. – ramzes2 Apr 13 '17 at 11:45
  • You have tried upgrading your version of Qt to the current 5.8, since you can be a bug in your version. – eyllanesc Apr 17 '17 at 15:41
  • @eyllanesc I did not try yet. I'll try it tonight and let you know – mrg95 Apr 17 '17 at 17:21
  • Please see my edit. I found out the issue only occurs on submenus – mrg95 Apr 17 '17 at 17:48
  • @eyllanesc Got around to updating. Went to Qt 5.5.1 and the problem persists. Also, submenus are even more broken https://stackoverflow.com/questions/44106990/disable-sloppysubmenu – mrg95 May 23 '17 at 17:00

2 Answers2

0

This sound like mouseTracking is not enabled on the widget (and/or probably on the parent widget(s)). You can enable it by calling

QWidget::setMouseTracking(bool enable);
Bowdzone
  • 3,827
  • 11
  • 39
  • 52
0
  1. Background may not be customized, if you don't change a border style of a button.

How to solve: use some non-default style, for example:

const auto fusion = QStyleFactory::create( "Fusion" );
QApplication::setStyle( fusion );
  1. QPushButton is not designed for perfect handling hover events. For example, hover event will not change a font via stylesheet.

How to solve: use QToolButton instead.

P.S. Don't know, why it's not worked for you. Everything is OK for me...

UPDATE

Just copy-paste it and run:

#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:!hover{background-color: #00ff00;}"
        "QToolButton:hover{background-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();
}

Screenshot

Community
  • 1
  • 1
Dmitry Sazonov
  • 8,801
  • 1
  • 35
  • 61
  • Your code doesn't work when the toolbutton is in a SUBmenu. This only works only the main menu that was executed. – mrg95 Apr 17 '17 at 17:42
  • Just tried your exact updated code, hovering no longer works. – mrg95 Apr 18 '17 at 16:28
  • @mrg95 I don't know why you have no results. You are doing something wrong. Mayby someone else will check. Btw, why you use so old and buggy version of Qt? – Dmitry Sazonov Apr 19 '17 at 07:05
  • Lol I used your exact code buddy. Straight copy and paste. – mrg95 Apr 19 '17 at 12:37
  • 1
    @mrg95 once again: why are you using so old version of Qt. Possible, your problem will be fixed if you will update. I propose you to use at least Qt 5.6.2. – Dmitry Sazonov Apr 19 '17 at 14:37
  • Finally updated to Qt 5.5.1 (Latest version that supports MSVC2010 which is what I need) and no change was made. In fact, now it's worse because the submenu closes automatically when hovering on the toolbutton due to https://stackoverflow.com/questions/44106990/disable-sloppysubmenu – mrg95 May 23 '17 at 16:59
  • 1
    @mrg95 I still don't understand, why you are using old version of Qt??? Use 5.6.2 - it's officially supported. It is very simple to build it with msvc2010. – Dmitry Sazonov May 24 '17 at 06:28
  • @dmirty because I would have to build it myself which I don't know how to do. 5.5.1 is supported as well. – mrg95 May 25 '17 at 06:55
  • Boom. 5.6.2 works now. Swag. Thx for ur help :) If u edit ur answer to mention the version issues, I'll accept it since I didn't know Qt 5.6.2 supported C++98 until u said it worked for msvc2010. Thanks a ton! – mrg95 May 26 '17 at 08:12
  • @mrg95 I don't know what to edit. From my point of view, my answer is complete: it has working code and screenshots. – Dmitry Sazonov May 26 '17 at 08:14
  • Well simply put, I didn't need to use a toolbutton or Fusion style or anything. Works default as expected. I just had to update to 5.6.2 – mrg95 May 26 '17 at 08:15