Hover event on QPushButton



  • Hi.

    I want to change the icons of my buttons when mouse goes over it.
    They are created like this:

        btn1 = new QPushButton("", this);
        btn1->setGeometry(0, 150, 100, 100);
        btn1->setIcon(QIcon("btnLogs/1.jpg"));
        btn1->setIconSize(QSize(100, 100));
        QObject::connect(btn1, SIGNAL(clicked()), this, SLOT(slotBtn1()));
    

    Found the QEvent::HoverEnter and QEvent::HoverLeave events in the Qt documentation, but I fear that I will not get them to work without some help.

    I tried something like this for example:

        btn1->QEvent::HoverEnter;
        {
        btn1->setIcon(QIcon("btnLogs/1_hover.jpg"));
        }
        btn1->QEvent::HoverLeave;
        {
        btn1->setIcon(QIcon("btnLogs/1.jpg"));
        }
    

    It tells me that 'QEvent' is not a base of 'QPushButton' btn1->QEvent::HoverEnter;

    I didn't find an easy example for this on google.

    Thanks for your help.


  • Lifetime Qt Champion

    Hi,

    HoverEnter and HoverLeave are two enumeration value.

    In your case, you should implement an event filter that you'll set on your QPushButton



  • I tried but I did not really understant everything.

    In the .h file I declared a function called filterBtn1();

    #ifndef TEST_H
    #define TEST_H
    
    #include <QApplication>
    #include <QWidget>
    #include <QPixmap>
    #include <QPushButton>
    #include <QObject>
    #include <QHoverEvent>
    
    class myMainWindow : public QWidget
    {
        public:
        myMainWindow();
    
        public slots:
        void filterBtn1();
    
        private:
        QPushButton *btn1;
    };
    

    The main.cpp

    #include "Test.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        myMainWindow mainWindow;
        mainWindow.setFixedSize(1024, 768);
        mainWindow.show();
    
        return app.exec();
    }
    

    Then I added an event filter: "btn1->installEventFilter(filterBtn1);"
    And I understood that I have to create a class in the .cpp file and set boolean conditions:
    From this point, the example of the Qt documentation is a bit to complicate for me.

    #include "Test.h"
    
    myMainWindow::myMainWindow() : QWidget()
    {
        btn1 = new QPushButton("", this);
        btn1->setGeometry(0, 150, 104, 103);
        btn1->setIcon(QIcon("btnLogs/1.jpg"));
        btn1->setIconSize(QSize(104, 103));
        btn1->installEventFilter(filterBtn1);
    }
    
    class filterBtn1 : public QObject
    {
        Q_OBJECT
    protected:
        bool eventFilter(QObject ???*, QEvent *???);
    };
    
    bool filterBtn1::eventFilter(QObject *???, QEvent *???)
    {
        if (event->type() == QEvent::HoverEnter) {
    btn1->setIcon(QIcon("btnLogs/1_hover.jpg"));
        } else {
    ???
        }
    }
    


  • If someone could help me with that it would be great.



  • @Shodan said in Hover event on QPushButton:

    QPushButton

    As far as I see it, its quite similar as in Qml. You can use:
    void QWidget::enterEvent(QEvent *event)
    void QWidget::leaveEvent(QEvent *event)
    from here:
    http://doc.qt.io/qt-5/qpushbutton-members.html
    An event is sent to the widget when the mouse cursor enters the widget.
    A leave event is sent to the widget when the mouse cursor leaves the widget.



  • @c64zottel

    I tried with those members like this:
    .h file

    #ifndef TEST2_H
    #define TEST2_H
    
    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>
    
    
    class myMainWindow : public QWidget
    {
        Q_OBJECT
    
        public:
        myMainWindow();
        QPushButton *btn1;
    
        public slots:
        void enterEvent(QPushButton *btn1);
        void leaveEvent(QPushButton *btn1);
    
        private:
    };
    
    #endif // TEST2_H
    

    .cpp file

    #include "test2.h"
    
    myMainWindow::myMainWindow() : QWidget()
    {
        btn1 = new QPushButton("", this);
        btn1->setGeometry(0, 150, 104, 103);
        btn1->setIcon(QIcon("btnLogs/1.jpg"));
        btn1->setIconSize(QSize(104, 103));
    }
    
    void myMainWindow::enterEvent(QPushButton *btn1)
    {
        btn1->setIcon(QIcon("btnLogs/1_hover.jpg"));
    }
    
    void myMainWindow::leaveEvent(QPushButton *btn1)
    {
        btn1->setIcon(QIcon("btnLogs/1.jpg"));
    }
    

    No errors come up when I run the programm. Nothing happens when mouse goes over the button.
    I belive there is a connection to do with the button but I can't figure out how.
    At least I hope this is the right way to use void QWidget::enterEvent(QEvent *event).

    Thanks for your answers


  • Lifetime Qt Champion

    With all due respect, it seems you have a lack of C++ knowledge regarding virtual method re-implementation.

    The methods you re-implement must have matching signatures.

    Did you read the documentation chapter about handling events I linked to ?



  • Yes I know.
    I began with Qt only a few days ago :-)

    Of course I read id and tried to follow the examples.
    Since I am not english, many things are hard to understand.


  • Lifetime Qt Champion

    Well, in this case, it has nothing to do with Qt but basic C++. See polymorphism.



  • Ok, to test myself I did this in about 10 min. Since I can't upload a tar file, here is a link:
    [https://www.file-upload.net/download-12680886/TestEnterLeaveEvent.tar.gz.html](link url)

    For the sake of discussion and future references, here is the main code:

    class CustomButton : public QPushButton
    {
        // QWidget interface
    protected:
        virtual void enterEvent(QEvent *) {
            qDebug() << "entering";
            QPalette pal = palette();
            pal.setColor(QPalette::Button, QColor(Qt::blue));
            setAutoFillBackground(true);
            setPalette(pal);
            update();
        }
    
        virtual void leaveEvent(QEvent *) {
            qDebug() << "leaving";
            QPalette pal = palette();
            pal.setColor(QPalette::Button, QColor(Qt::red));
            setAutoFillBackground(true);
            setPalette(pal);
            update();
        }
    };
    

    The MainWindow has a pointer to a CustomButton, which is initialized in the ctor:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        cb = new CustomButton;
    
        cb->setText( "My funny button");
        this->setCentralWidget( cb );
    }
    

  • Lifetime Qt Champion

    @c64zottel There's no need to call setAutoFileBackground in every function. That's typically something you do once in the constructor.



  • @c64zottel If it's just the background color you want to change, I would recomment the use of a StyleSheet:

    QPushButton *btn = new QPushButton();
    btn->setObjectName("btnName_1");
    btn->show();
    btn->setSteyleSheet(
    "   QPushButton#btnName_1 {"
    "     background-color: yellow;"
    " }"
    " QPushButton#btnName_1:pressed {"
    "     background-color: rgb(224, 0, 0);     "
    " }"
    " QPushButton#btnName_1:hover {"
    "     background-color: rgb(224, 255, 0);"
    " }"
    
    "QPushButton#btnName_1:hover:pressed"
    "{"
    "    background-color:red;"
    "}"
    );
    


  • I tried to change the button icon with a styleSheet like this:

    #include "test2.h"
    
    myMainWindow::myMainWindow() : QWidget()
    {
        btn1 = new QPushButton("", this);
        btn1->setGeometry(0, 150, 104, 103);
        btn1->setObjectName("btn1_Name");
        btn1->show();
        btn1->setStyleSheet(
        "   QPushButton#btn1_Name {"
        "     background-image: url('btnLogs/1.jpg');"
        " }"
        " QPushButton#btn1_Name:pressed {"
        "     background-image: url('btnLogs/1_pressed.jpg');"
        " }"
        " QPushButton#btn1_Name:hover {"
        "     background-image: url('btnLogs/1_hover.jpg');"
        " }"
        "QPushButton#btn1_Name:hover:pressed"
        "{"
        "     background-image: url('btnLogs/1_pressed.jpg');"
        "}"
        );
    }
    

    It seems to work, even better than expected since there are the "pressed" status within.
    For what I want to do it's just great!

    I'll try to do this using a event filter in my next programm, with a bit more experience in Qt.

    Thanks all the people for your help with this.

    Best regards :-}


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.