How to emit a signal from a QPushButton when the mouse hovers over it?

后端 未结 5 1097
野性不改
野性不改 2021-01-05 12:52

Recently, I wanted that QPushButton can emit a signal, when the mouse pointer enters. How can I make it?

I know that QPushButton has some already defin

相关标签:
5条回答
  • 2021-01-05 12:56

    Make sure to add ':' after the public keyword

    public: Q_SIGNALS:
        void hovered();
    
    0 讨论(0)
  • 2021-01-05 13:13

    So QT deal with mouse hovering using the "event" enterEvent (https://doc.qt.io/qt-5/qevent.html look for "QEvent::Enter"). This isn't about the Signal/Slot functionality (https://doc.qt.io/qt-5/signalsandslots.html), this is about Events (https://doc.qt.io/qt-5/eventsandfilters.html) We find enterEvent as a protected method at QWidget class (https://doc.qt.io/qt-5/qwidget.html) which is a base class for QPushButton class (https://doc.qt.io/qt-5/qpushbutton.html).

    So what you have to do: to create a new class derived from QPushButton and override the protected method "enterEvent" that QPushButton inherited from QWidget.

    Creating the new class:
    QT Creator - File - New File or Project...
    File and Classes - C++
    C++ Class
    Choose...
    Base class - Custom - QPushButton
    Next
    define a name for your new class like MyPushButton

    In mypushbutton.h:

    #ifndef MYPUSHBUTTON_H
    #define MYPUSHBUTTON_H
    
    #include <QPushButton>
    
    class MyPushButton: public QPushButton
    {
        Q_OBJECT
    public:
        using QPushButton::QPushButton;  //inherits the QPushButton constructors
    
    signals:
        void myPushButtonMouseHover();
    
    protected:
        void enterEvent(QEvent *event);
    };
    
    #endif // MYPUSHBUTTON_H
    

    In mypushbutton.cpp:

    #include "mypushbutton.h"
    #include <QMessageBox>
    
    void MyPushButton::enterEvent(QEvent *event)
    {
        QMessageBox::warning(this, "Mouse hover", "Mouse hovered MyPushButton"); //popping a message box
    
        emit myPushButtonMouseHover();  //emitting signal 
    
        QPushButton::QWidget::enterEvent(event);  //calling the "natural" enterEvent
    
    }
    
    0 讨论(0)
  • 2021-01-05 13:14

    You can use QWidget::enterEvent ( QEvent * event ) for this.

    You override this event and send a custom defined signal when ever this event occurs.

    First you have to enable mouse tracking for this widget (setMouseTracking(true) in the constructor for example).

    Header file:

    class my_button
    {
        // ...
    
    protected:
        virtual void enterEvent( QEvent* e );
    
    public Q_SIGNALS:
        void hovered();
    
        // ...
    };
    

    Source file:

    void my_button::enterEvent( QEvent* e )
    {
        Q_EMIT hovered();
    
        // don't forget to forward the event
        QWidget::enterEvent( e );
    }
    

    Where you use your button:

    connect( one_of_my_button, SIGNAL(hovered()), this, SLOT(do_something_when_button_hovered()) );
    
    0 讨论(0)
  • 2021-01-05 13:15

    Although @Exa has answered this question, I want to show another solution which does not need to subclass QPushButton and is flexible in use! ( That's what I need in my project)

    Step 1/2 : Overriding eventFilter.

    LoginWindow.h:

    // LoginWindow is where you placed your QPushButton 
    //(= most probably your application windows)
    
    class LoginWindow: public QWidget
    {
    public:
          bool eventFilter(QObject *obj, QEvent *event);
    ..
    };
    

    LoginWindow.cpp:

    bool LoginWindow::eventFilter(QObject *obj, QEvent *event)
    {
        // This function repeatedly call for those QObjects
        // which have installed eventFilter (Step 2)
    
        if (obj == (QObject*)targetPushButton) {
            if (event->type() == QEvent::Enter)
            {
            // Whatever you want to do when mouse goes over targetPushButton
            }
            return true;
        }else {
            // pass the event on to the parent class
            return QWidget::eventFilter(obj, event);
        }
    }
    

    Step 2/2 : Installing eventFilter on target widgets.

    LoginWindow::LoginWindow()
    {
        ...
        targetPushButton->installEventFilter(this);
        ...
    }
    
    0 讨论(0)
  • 2021-01-05 13:17

    If I remember correctly, you need to enable mouse tracking for the button (Qt documentation) and override QWidget::onEnter() and QWidget::onLeave().

    You will need to create a custom button class inheriting from QPushButton. You can define signals for mouseEnter and mouseLeave in your custom class and emit them from the onEnter() and onLeave() methods that you need to override.

    0 讨论(0)
提交回复
热议问题