Domanda

Sto solo imparando Qt con C ++. Ho implementato con successo segnali e slot per intercettare eventi standard come ButtonPushed () , ecc. Tuttavia, voglio avere una funzione chiamata quando passo il mouse e mi sposto da un QLabel . Sembra che QHoverEvent farà ciò di cui ho bisogno, ma non riesco a sembrare per trovare tutorial o esempi su come implementarlo. È fatto allo stesso modo di segnali e slot ?. Ho provato:

connect(ui.lbl_test, SIGNAL(QHoverEvent), this, SLOT(TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos)));

.. ma la funzione non è stata chiamata quando ho passato il mouse sopra l'etichetta.

Ecco la funzione, elencata nel file di intestazione come uno slot pubblico:

void MyDialog::TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos) {
     QMessageBox::information(this, tr("Hey"), tr("Listen!"));
}

Qualcuno può aiutarmi a capirlo o indicarmi un buon esempio?

EDIT:

Dopo aver letto un post di seguito, non ho trovato alcun membro setFlag () da chiamare per il mio widget etichetta, ma ho provato:

    ui.lbl_test->setMouseTracking(true);
    connect(ui.lbl_test, SIGNAL(ui.lbl_test->mouseMoveEvent()), this, SLOT(TestFunc(QMouseEvent *event)));

E aggiornato TestFunc () di conseguenza. Ma non succede nulla quando passo il mouse sopra.

Dopo aver guardato non sono sicuro che QLabel erediti anche mouseMoveEvent () anche da QWidget . Se questo è vero, esiste un widget o un elenco di oggetti che lo ereditano da qualche parte ?. Tutto ciò che posso dire dalla documentazione sul loro sito è quante funzioni ereditate ha un oggetto ..

È stato utile?

Soluzione

L'uso di segnali e slot a questo scopo non funzionerà.

mouseMoveEvent () non è un segnale o un meta-metodo e non può essere collegato a uno slot.

La sottoclasse della classe del widget e l'override di mouseMoveEvent () ti consentiranno di ottenere eventi di spostamento del mouse, ma questo è un modo molto pesante per raggiungere questo obiettivo (e aggiunge un'altra classe alla tua base di origine ).

Invece, considera di implementare un metodo eventFilter () sulla tua classe MyDialog e installalo su QLabel . Con questo metodo di filtro eventi, puoi intercettare tutti gli eventi per una determinata istanza QObject .

Ecco la documentazione sui filtri degli eventi.

http://doc.qt.io/qt-4.8 /eventsandfilters.html#event-filters

Inoltre, guardando l'esempio di codice, ti consiglio di dedicare un momento a indagare su cosa fanno le macro SIGNAL () e SLOT () . Puoi vedere come sono definiti in $QTDIR/src/corelib/kernel/qobjectdefs.h

Altri suggerimenti

In base al link del documento fornito, otterrai questo QHoverEvent solo se il tuo widget ha il flag Qt :: WA_Hover .

Dopo aver creato la chiamata al widget:

widget->setAttribute(Qt::WA_Hover);

e vedi se funziona.

Un altro modo per ottenere lo stesso risultato è sostituire mouseMoveEvent () nel tuo widget
si noti che anche questa funzione non verrà normalmente chiamata a meno che non si chiami:

widget->setMouseTracking(true);

Questo è fondamentalmente il modo in cui QT implementa internamente l'evento hover.

http://qt-project.org/doc/qt -5 / qwidget.html # enterEvent

http://qt-project.org/doc/qt -5 / qwidget.html # leaveEvent

http://qt-project.org/doc /qt-5/qt.html#widget-attributes

Qt :: WA_Hover

  

Forza Qt a generare eventi di disegno quando il mouse entra o esce da   widget di. Questa funzione viene in genere utilizzata durante l'implementazione personalizzata   stili; vedere l'esempio degli stili per i dettagli.

http: / /qt-project.org/doc/qt-5/qtwidgets-widgets-styles-example.html#norwegianwoodstyle-class-implementation

  

Questo sovraccarico QStyle :: polish () viene chiamato una volta su ogni widget disegnato   usando lo stile. Lo reimplementiamo per impostare l'attributo Qt :: WA_Hover   su QPushButtons e QComboBoxes . Quando questo attributo è impostato, Qt   genera eventi di disegno quando il puntatore del mouse entra o esce da   widget di. Ciò rende possibile il rendering di pulsanti e combobox   diversamente quando il puntatore del mouse è su di essi.

Come ricevere Enter and Leave Events su un QWidget

  1. Imposta l'attributo del widget per WA_Hover

    // in your widget's constructor (probably)
    this->setAttribute(Qt::WA_HOVER, true);
    
  2. Implementa QWidget :: enterEvent () e QWidget :: leaveEvent () .

    void Widget::enterEvent(QEvent * event)
    {
        qDebug() << Q_FUNC_INFO << this->objectName();
        QWidget::enterEvent(event);
    }
    
    void Widget::leaveEvent(QEvent * event)
    {
        qDebug() << Q_FUNC_INFO << this->objectName();
        QWidget::leaveEvent(event);
    }
    
  3. Fatto

QHoverEvent in QWidget

http://qt-project.org/doc/qt -5 / qhoverevent.html # details

http://qt-project.org/doc/qt -5 / qobject.html # evento

http://qt-project.org/doc/qt -5 / qwidget.html # evento

// in your widget's constructor (probably)
this->setAttribute(Qt::WA_HOVER, true);
// ...

void Widget::hoverEnter(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}
void Widget::hoverLeave(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}
void Widget::hoverMove(QHoverEvent * event) {qDebug() << Q_FUNC_INFO << this->objectName();}

bool Widget::event(QEvent * e)
{
    switch(e->type())
    {
    case QEvent::HoverEnter:
        hoverEnter(static_cast<QHoverEvent*>(e));
        return true;
        break;
    case QEvent::HoverLeave:
        hoverLeave(static_cast<QHoverEvent*>(e));
        return true;
        break;
    case QEvent::HoverMove:
        hoverMove(static_cast<QHoverEvent*>(e));
        return true;
        break;
    default:
        break;
    }
    return QWidget::event(e);
}

UPDATE:

Esempio semplice

Passa con il mouse sul pulsante e guarda il conteggio cambiare. Guarda l'output dell'applicazione per ulteriori informazioni.

https://gist.github.com/peteristhegreat/d6564cd099235f8a77f

Spero che sia d'aiuto.

Avevo lo stesso problema, sono arrivato al seguente progetto di soluzione:

Nel mio widget principale, vorrei elaborare gli eventi al passaggio del mouse di alcuni oggetti selezionati. Per questo motivo, ho creato 2 slot sul mio MainWindow :

public slots:
    void onHoverIn(QObject* object);
    void onHoverOut(QObject* object);

Quindi ho creato una classe Filtro eventi come questa:

hovereventfilter.h

#ifndef HOVEREVENTFILTER_H
#define HOVEREVENTFILTER_H

#include <QObject>
#include <QEvent>

class HoverEventFilter : public QObject
{
    Q_OBJECT
public:
    explicit HoverEventFilter(QObject *parent = 0);

signals:
    void HoverIn(QObject *);
    void HoverOut(QObject *);

public slots:

protected:
    bool eventFilter(QObject *watched, QEvent *event);
};

#endif // HOVEREVENTFILTER_H

hovereventfilter.cpp

#include "hovereventfilter.h"

HoverEventFilter::HoverEventFilter(QObject *parent) : QObject(parent)
{

}

bool HoverEventFilter::eventFilter(QObject *watched, QEvent *event)
{

    QEvent::Type t = event->type();

    switch(t){
    case QEvent::Enter:
        emit HoverIn(watched);
        break;

    case QEvent::Leave:
        emit HoverOut(watched);
        break;
    default:
        return false;
    }

    return true;
}

Puoi vedere che questa classe genererà HoverIn o HoverOut a seconda di ciò che è successo. Questo approccio non richiede impostazioni di Qt::WA_Hover

Ora, come ultimo passo, dobbiamo indicare quali elementi devono essere filtrati e collegare segnali e slot. Creerò un puntatore privato al filtro eventi in mainwindow.h

class MainWindow : public QWidget
{
    Q_OBJECT

...

public slots:
    void onHoverIn(QObject* object);
    void onHoverOut(QObject* object);

private:

    HoverEventFilter* hoverEventFilter;

...

};

E nel costruttore, aggiungo questo:

this->hoverEventFilter = new HoverEventFilter(this);

connect(this->hoverEventFilter, SIGNAL(HoverIn(QObject*)), this, SLOT(onHoverIn(QObject*)));
connect(this->hoverEventFilter, SIGNAL(HoverOut(QObject*)), this, SLOT(onHoverOut(QObject*)));

Ora ogni volta che desidero ricevere eventi hover su un oggetto, ho appena impostato il filtro eventi su di esso, in questo modo:

this->ui->someLabelOrWhatever->installEventFilter(this->hoverEventFilter);

Ciò che rimane è l'implementazione di onHoverIn e onHoverOut in MainWindow . Entrambi condividono la stessa idea, quindi mostrerò solo onHoverIn

void MainWindow::onHoverIn(QObject *object)
{
    QString objectName = object->objectName();

    switch(objectName){
        // do something depending on name of the widget
    }
}

Puoi estenderlo così facilmente, per elaborare gli eventi al passaggio del mouse su un nuovo elemento, devi solo impostare un listener di eventi su di esso e prenderti cura di ciò che desideri fare in onHoverIn e onHoverOut . Non è necessario sottoclassare alcun widget.

QHoverEvent è solo per i widget hover, si desidera implementare i gestori enterEvent e leaveEvent subclassando invece il widget. Se invece si desidera utilizzare un filtro eventi, i tipi di evento corrispondenti sono QEvent :: Enter e QEvent :: Leave .

Se hai semplicemente bisogno di cambiare l'aspetto del widget, potresti voler esaminare i fogli di stile Qt, in quanto forniscono un selettore : hover .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top