Wie implementiere ich QHoverEvent in Qt?
Frage
Ich lerne gerade Qt mit C ++. Ich habe erfolgreich Signale und Slots zu stoppen Standardereignisse wie ButtonPushed()
implementiert usw. Aber ich möchte eine Funktion haben, aufgerufen, wenn ich die Maus über und Maus aus einem QLabel
. Es sieht aus wie QHoverEvent wird tun, was ich brauche, aber ich kann nicht scheinen, zu finden alle Tutorials oder Beispiele, wie diese umzusetzen. Ist es die gleiche Art und Weise wie Signale und Slots gemacht ?. Ich habe versucht:
connect(ui.lbl_test, SIGNAL(QHoverEvent), this, SLOT(TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos)));
.. aber die Funktion nicht aufgerufen werden, wenn ich über das Etikett schwebte.
Hier ist die Funktion, in der Header-Datei als öffentliche Slot aufgelistet:
void MyDialog::TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos) {
QMessageBox::information(this, tr("Hey"), tr("Listen!"));
}
Kann mir jemand helfen, dies herauszufinden, oder zeigen Sie uns ein gutes Beispiel?
EDIT:
Nach einem Beitrag unten zu lesen, ich habe kein setFlag()
Mitglied gefunden für mein Label-Widget zu nennen, aber ich habe versucht:
ui.lbl_test->setMouseTracking(true);
connect(ui.lbl_test, SIGNAL(ui.lbl_test->mouseMoveEvent()), this, SLOT(TestFunc(QMouseEvent *event)));
Und aktualisiert TestFunc()
entsprechend. Aber immer noch nichts passiert, wenn ich die Maus über.
Nach einem Blick Ich bin nicht sicher QLabel
auch die erbt mousemove () sogar von QWidget
. Wenn dies wahr ist, ist es ein Widget, das der Fall ist, oder eine Liste von Objekten, die es irgendwo erben ?. Alles, was ich aus der Dokumentation auf ihrer Website sagen kann, ist, wie viele ein Objekt geerbt Funktionen hat ..
Lösung
Signale und Slots für diesen Zweck verwendet, wird nicht funktionieren.
mouseMoveEvent()
kein Signal oder meta-Verfahren und kann nicht in einen Schlitz verbunden werden.
Erweitern die Widget-Klasse und überwiegendes mouseMoveEvent()
ermöglicht es Ihnen, Maus-move-Ereignisse zu bekommen, aber das ist ein sehr Schwergewicht Weg dies zu tun (und fügt eine weitere Klasse zu Ihrer Source-Basis).
Stattdessen betrachten eine eventFilter()
Methode auf Ihrer MyDialog
Klasse implementieren, und es auf dem QLabel
installieren. Mit dieser Ereignisfilter-Methode können Sie alle Ereignisse abfangen für eine gegebene QObject
Instanz.
Hier ist die Dokumentation auf Ereignisfilter.
http://doc.qt.io/qt-4.8 /eventsandfilters.html#event-filters
Zusätzlich wird durch den Code Probe suchen, würde ich empfehlen Sie einen Moment Zeit nehmen, zu untersuchen, was die SIGNAL()
und SLOT()
Makros tun. Sie können sehen, wie sie in $QTDIR/src/corelib/kernel/qobjectdefs.h
definiert sind
Andere Tipps
Nach dem Dokument Link Sie geben werden nur diese QHoverEvent erhalten, wenn IhrFormal Widget das Qt::WA_Hover
Flag hat.
Nach dem Widget Aufruf Konstruktion:
widget->setAttribute(Qt::WA_Hover);
und sehen, ob es funktioniert.
Eine andere Möglichkeit, um das gleiche Ergebnis zu erzielen, ist mouseMoveEvent()
in Ihrem Widget
außer Kraft zu setzen
feststellen, dass dies auch Funktion, wenn Sie normalerweise nicht nennen aufgerufen werden:
widget->setMouseTracking(true);
Dies ist im Grunde, wie QT das Hover-Ereignis implementiert intern.
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
Forces Qt Farbe Ereignisse zu erzeugen, wenn die Maus betritt oder verlässt die Widget. Diese Funktion wird normalerweise verwendet, wenn kundenspezifische Implementierung Stile; finden Sie im Stil Beispiel für Details.
Diese
QStyle::polish()
Überlastung wird einmal aufgerufen, jedes Widget gezogen mit dem Stil. Wir reimplementieren es dasQt::WA_Hover
Attribut festlegen aufQPushButtons
undQComboBoxes
. Wenn dieses Attribut gesetzt ist, Qt erzeugt Ereignisse Farbe, wenn der Mauszeiger ein oder aus Widget. Dies ermöglicht es, Druckknöpfe und Comboboxen zu machen anders, wenn sich der Mauszeiger über sie.
Wie betreten und verlassen Events auf einem QWidget
erhalten
-
Stellen Sie das Widget Attribut für WA_Hover
// in your widget's constructor (probably) this->setAttribute(Qt::WA_HOVER, true);
-
Implementieren
QWidget::enterEvent()
undQWidget::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); }
-
Fertig
QHoverEvent in QWidget
http://qt-project.org/doc/qt -5 / qhoverevent.html # Details
http://qt-project.org/doc/qt -5 / qobject.html # event
http://qt-project.org/doc/qt -5 / qwidget.html # event
// 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:
Einfaches Beispiel
auf die Schaltfläche Bewegen und die Zählung Änderung sehen. Schauen Sie sich die Anwendungsausgabe für weitere Informationen.
https://gist.github.com/peteristhegreat/d6564cd0992351f98aa94f869be36f77
Ich hoffe, das hilft.
Ich habe das gleiche Problem hat, kam ich zu folgenden Lösung Entwurf:
In meinem Haupt-Widget, würde Ich mag Hover Ereignisse einiger ausgewählter Objekte verarbeiten. Aus diesem Grund habe ich 2 Slots auf meinem MainWindow
:
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
Dann habe ich ein Ereignisfilter Klasse wie folgt:
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;
}
Sie können diese Klasse sehen feuert entweder HoverIn oder HoverOut je nachdem, was passiert ist. Dieser Ansatz keine Einstellungen von Qt::WA_Hover
benötigen
Jetzt als letzten Schritt müssen wir die Elemente anweisen sind gefiltert werden und Signale und Slots verbinden. Ich werde einen eigenen Zeiger auf Ereignisfilter in mainwindow.h erstellen
class MainWindow : public QWidget
{
Q_OBJECT
...
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
private:
HoverEventFilter* hoverEventFilter;
...
};
Und in Konstruktor, füge ich diese:
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*)));
Nun, wenn ich auf ein Objekt schweben Ereignisse erhalten möchten, habe ich nur Ereignisfilter auf es wie folgt aus:
this->ui->someLabelOrWhatever->installEventFilter(this->hoverEventFilter);
Was bleibt, ist die Umsetzung von onHoverIn
und onHoverOut
in MainWindow
. Beide teilen sich die gleiche Idee, damit ich nur onHoverIn
zeigen
void MainWindow::onHoverIn(QObject *object)
{
QString objectName = object->objectName();
switch(objectName){
// do something depending on name of the widget
}
}
Sie können diese erweitern so leicht, schweben Ereignisse auf neues Element zu verarbeiten, müssen Sie nur ein Ereignis-Listener auf sie gesetzt und kümmern uns um, was Sie wollen in den onHoverIn
und onHoverOut
Methoden zu tun. Keine Notwendigkeit, alle Widgets Unterklasse.
QHoverEvent
ist nur für Hover-Widgets, die Sie wollen stattdessen den enterEvent
und leaveEvent
Handler implementieren, indem Subklassen das Widget.
Wenn Sie wollen stattdessen einen Ereignisfilter verwenden, sind die entsprechenden Ereignistypen QEvent::Enter
und QEvent::Leave
.
Wenn Sie einfach nur das Aussehen des Widgets ändern müssen, möchten Sie vielleicht in Qt Sheets sehen, wie sie einen :hover
Wähler liefern.
Sie müssen Unterklasse oder filtern focusInEvent und focusOutEvent dieses speziellen Widget.