Question

Je suis en train d'apprendre Qt avec C ++. J'ai implémenté avec succès des signaux et des emplacements pour capturer des événements standard tels que ButtonPushed () , etc. Cependant, je souhaite qu'une fonction soit appelée lorsque je passe la souris sur un QLabel . Il semble que QHoverEvent fasse ce que j'ai besoin, mais je ne peux pas sembler pour trouver des tutoriels ou des exemples sur la façon de mettre en œuvre cela. Est-ce fait de la même manière que les signaux et les slots?. J'ai essayé:

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

.. mais la fonction n'a pas été appelée lorsque j'ai survolé l'étiquette.

Voici la fonction répertoriée dans le fichier d'en-tête en tant qu'emplacement public:

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

Quelqu'un peut-il m'aider à comprendre cela ou à me montrer un bon exemple?

EDIT:

Après avoir lu un article ci-dessous, je n’ai trouvé aucun membre setFlag () à appeler pour mon widget étiquette, mais j’ai essayé:

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

Et mis à jour TestFunc () en conséquence. Mais rien ne se passe quand je passe la souris.

Après avoir regardé, je ne suis pas sûr que QLabel hérite même de mouseMoveEvent () même de QWidget . Si cela est vrai, existe-t-il un widget ou une liste d'objets qui en héritent quelque part?. Tout ce que je peux dire de la documentation sur leur site est le nombre de fonctions héritées d’un objet.

Était-ce utile?

La solution

L'utilisation de signaux et d'emplacements à cet effet ne fonctionnera pas.

mouseMoveEvent () n'est pas un signal ni une méta-méthode et ne peut pas être connecté à un emplacement.

Sous-classer la classe de widgets et redéfinir mouseMoveEvent () vous permettra d’obtenir des événements de déplacement de la souris, mais c’est un moyen très lourd de le faire (et ajoute une classe supplémentaire à votre base source ).

Au lieu de cela, pensez à implémenter une méthode eventFilter () sur votre classe MyDialog et à l'installer sur le QLabel . Avec cette méthode de filtrage des événements, vous pouvez intercepter tous les événements pour une instance QObject donnée.

Voici la documentation sur les filtres d'événement.

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

De plus, en consultant l'exemple de code, je vous recommanderais de prendre un moment pour découvrir ce que font les macros SIGNAL () et SLOT () . Vous pouvez voir comment ils sont définis dans $ QTDIR / src / corelib / kernel / qobjectdefs.h

Autres conseils

Selon le lien de document que vous indiquez, vous n'obtiendrez cet événement QHoverEvent que si votre widget est associé à l'indicateur Qt :: WA_Hover .

Après avoir construit l'appel du widget:

widget->setAttribute(Qt::WA_Hover);

et voyez si cela fonctionne.

Un autre moyen d'obtenir le même résultat consiste à remplacer mouseMoveEvent () dans votre widget
remarquez que cette fonction ne sera pas appelée normalement sauf si vous appelez:

widget->setMouseTracking(true);

C’est essentiellement ainsi que QT implémente l’événement de survol en interne.

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

  

Force Qt à générer des événements de peinture lorsque la souris entre ou quitte le   widget. Cette fonctionnalité est généralement utilisée lors de la mise en œuvre de   modes; voir l'exemple de styles pour plus de détails.

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

  

Cette surcharge QStyle :: polish () est appelée une fois sur chaque widget dessiné.   en utilisant le style. Nous le réimplémentons pour définir l'attribut Qt :: WA_Hover   sur QPushButtons et QComboBoxes . Lorsque cet attribut est défini, Qt   génère des événements de peinture lorsque le pointeur de la souris entre ou quitte la   widget. Cela permet de rendre les boutons poussoirs et les comboboxes   différemment lorsque le pointeur de la souris les survole.

Comment recevoir des événements d'entrée et de sortie sur un QWidget

  1. Définir l'attribut de widget pour WA_Hover

    // in your widget's constructor (probably)
    this->setAttribute(Qt::WA_HOVER, true);
    
  2. Implémentez QWidget :: enterEvent () et 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. Terminé

QHoverEvent dans QWidget

http://qt-project.org/doc/qt -5 / qhoverevent.html # détails

http://qt-project.org/doc/qt -5 / qobject.html # événement

http://qt-project.org/doc/qt -5 / qwidget.html # événement

// 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:

Exemple simple

Passez la souris sur le bouton pour voir le changement de compte. Consultez la sortie de l'application pour plus d'informations.

L’espoir que cela aide.

J'avais le même problème, je suis arrivé à la conception de solution suivante:

Dans mon widget principal, j'aimerais traiter les événements de survol de certains objets sélectionnés. Pour cette raison, j'ai créé 2 emplacements sur mon MainWindow :

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

Ensuite, j'ai créé une classe de filtrage d'événements comme celle-ci:

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;
}

Vous pouvez voir que cette classe déclenchera HoverIn ou HoverOut en fonction de ce qui s’est passé. Cette approche ne nécessite pas de paramètres de Qt :: WA_Hover

Maintenant, à la dernière étape, nous devons indiquer quels éléments doivent être filtrés et connecter les signaux et les slots. Je vais créer un pointeur privé sur le filtre d'événements dans mainwindow.h

class MainWindow : public QWidget
{
    Q_OBJECT

...

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

private:

    HoverEventFilter* hoverEventFilter;

...

};

Et dans le constructeur, j'ajoute ceci:

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*)));

Désormais, chaque fois que je souhaite recevoir des événements survolés sur un objet, je définis simplement un filtre d'événements, comme ceci:

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

Il ne reste que l'implémentation de onHoverIn et de onHoverOut dans MainWindow . Ils partagent tous les deux la même idée, donc je vais montrer seulement onHoverIn

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

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

Vous pouvez étendre cela si facilement, pour traiter des événements survolés sur un nouvel élément, il vous suffit de définir un écouteur d'événements sur celui-ci et de prendre en charge ce que vous souhaitez effectuer dans onHoverIn et onHoverOut méthodes. Pas besoin de sous-classer les widgets.

QHoverEvent concerne uniquement les widgets de survol, vous souhaitez implémenter les gestionnaires enterEvent et leaveEvent en sous-classant le widget. Si vous souhaitez utiliser un filtre d'événements à la place, les types d'événements correspondants sont QEvent :: Enter et QEvent :: Leave .

Si vous devez simplement modifier l'apparence du widget, vous pouvez également consulter les feuilles de style Qt, car elles fournissent un sélecteur : hover .

Vous devez sous-classer ou filtrer focusInEvent et focusOutEvent de ce widget particulier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top