2012-02-13 24 views
5

Recientemente, quería que QPushButton pueda emitir una señal, cuando ingresa el puntero del mouse. ¿Cómo puedo hacerlo?¿Cómo se emite una señal desde QPushButton cuando el mouse se cierne sobre ella?

Sé que QPushButton tiene alguna señal ya definida, como clicked(), pressed(), destory() y así sucesivamente. Pero no hay señal como hover(), enter(), ...

Miré algo de información al respecto: Alguien dijo que se puede hacer por css. No entiendo. Me puedes dar algún consejo ? ¡Gracias!

+0

Si se puede explicar lo que le gustaría hacer cuando esté el ratón, puede no ser necesario para interceptar tal evento. Si, por ejemplo, desea cambiar el aspecto del botón, puede hacerlo con una hoja de estilos. –

+0

Gracias .. Quiero hacer eso: si hay dos componentes, una vez que el puntero del mouse se coloca sobre uno, el otro es invisible ... –

+1

Ok, dado que desea afectar un botón basado en la interacción del mouse con otro botón, de hecho deberá interceptar este evento. –

Respuesta

7

Puede usar QWidget::enterEvent (QEvent * event) para esto.

Anula este evento y envía una señal personalizada cuando se produce este evento.

Primero tiene que habilitar el seguimiento del mouse para este widget (setMouseTracking(true) en el constructor, por ejemplo).

Archivo de cabecera: archivo

class my_button 
{ 
    // ... 

protected: 
    virtual void enterEvent(QEvent* e); 

public Q_SIGNALS: 
    void hovered(); 

    // ... 
}; 

Fuente:

void my_button::enterEvent(QEvent* e) 
{ 
    Q_EMIT hovered(); 

    // don't forget to forward the event 
    QWidget::enterEvent(e); 
} 

Cuando se utiliza el botón:

connect(one_of_my_button, SIGNAL(hovered()), this, SLOT(do_something_when_button_hovered())); 
+0

en primer lugar, gracias. Creo que es un poco complicado, porque solo uso uno de esos botones, ¿Hay alguna otra manera? –

1

Si no recuerdo mal, debe habilitar el seguimiento del mouse para el botón (Qt documentation) y anular QWidget::onEnter() y QWidget::onLeave().

Tendrá que crear una clase de botón personalizada heredando de QPushButton. Puede definir señales para mouseEnter y mouseLeave en su clase personalizada y emitirlas desde los métodos onEnter() y onLeave() que debe sobrescribir.

+0

¿Debe anularse? Gracias por ayudarme ... –

+1

Sí, debe implementar las funciones onEnter() y onLeave() en su clase de botón personalizado. Ver la respuesta de @ Exa para el ejemplo del código. PD. Por favor vote si encuentra una respuesta útil – dirk

3

Asegúrese de añadir ':' después de la palabra clave pública

public: Q_SIGNALS: 
    void hovered(); 
6

Aunque @Exa ha respondido esta pregunta, quiero mostrar otra solución que no necesita subclasificar QPushButton y es flexible en su uso. (Eso es lo que necesito en mi proyecto)

Paso 1/2: reemplazando 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); 
    } 
} 

Paso 2/2: Instalación EventFilter de los widgets de destino.

LoginWindow::LoginWindow() 
{ 
    ... 
    targetPushButton->installEventFilter(this); 
    ... 
} 
+0

Esta es una muy buena respuesta. Pero por alguna extraña razón, cuando aplico esta lógica en un 'QToolButton' (para mostrar una ventana emergente de texto personalizado al pasar el cursor sobre ella), el botón se vuelve invisible, aunque al pasar el mouse por encima de donde se supone que se muestra, aparece la ventana emergente, y incluso el cursor se convierte en puntero como se esperaba, dado que lo configuré así para el botón. – SexyBeast

+0

¡Perfecto! ¡No quería crear una nueva clase para cada widget para el que quería detectar eventos de desplazamiento! – BuvinJ

+2

@Cupidvogel Creo que encontré la causa. En lugar de 'return true' en la función' eventFilter', use 'return QWidget :: eventFilter (obj, event);' y uno tampoco necesita la condición else. Hice esto y desapareció la condición del botón que desaparecía. – Volomike

Cuestiones relacionadas