QtでQHoverEventを実装するにはどうすればよいですか?
質問
QtをC ++で学習しています。 ButtonPushed()
などの標準イベントをトラップする信号とスロットを実装しました。ただし、 QLabel
。 QHoverEvent が必要なことを行うように見えますが、私には見えませんこれを実装する方法に関するチュートリアルや例を見つけます。信号やスロットと同じ方法で行われますか?試しました:
connect(ui.lbl_test, SIGNAL(QHoverEvent), this, SLOT(TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos)));
..しかし、ラベルの上にマウスを置いたときに関数が呼び出されませんでした。
関数は、ヘッダーファイルにパブリックスロットとしてリストされています。
void MyDialog::TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos) {
QMessageBox::information(this, tr("Hey"), tr("Listen!"));
}
誰でも私がこれを理解するのを手伝ってくれるか、良い例を教えてくれますか?
編集:
以下の投稿を読んだ後、ラベルウィジェットを呼び出す setFlag()
メンバーが見つかりませんでしたが、試しました:
ui.lbl_test->setMouseTracking(true);
connect(ui.lbl_test, SIGNAL(ui.lbl_test->mouseMoveEvent()), this, SLOT(TestFunc(QMouseEvent *event)));
そして、それに応じて TestFunc()
を更新しました。しかし、マウスオーバーしても何も起こりません。
見てから、 QLabel
がmouseMoveEvent()を QWidget
からも継承するかどうかわかりません。これが当てはまる場合、それを行うウィジェット、またはそれをどこかから継承するオブジェクトのリストはありますか?彼らのサイトのドキュメントから私が知ることができるのは、オブジェクトにいくつの継承された関数があるかです。
解決
この目的で信号とスロットを使用しても機能しません。
mouseMoveEvent()
はシグナルまたはメタメソッドではないため、スロットに接続できません。
ウィジェットクラスをサブクラス化し、 mouseMoveEvent()
をオーバーライドすると、マウス移動イベントを取得できますが、これはこれを達成するための非常に重い方法です(そして、もう1つのクラスをソースベースに追加します) )。
代わりに、 MyDialog
クラスに eventFilter()
メソッドを実装し、 QLabel
にインストールすることを検討してください。このイベントフィルターメソッドを使用すると、特定の QObject
インスタンスのすべてのイベントをインターセプトできます。
イベントフィルタのドキュメントはこちらです。
http://doc.qt.io/qt-4.8 /eventsandfilters.html#event-filters
さらに、コードサンプルを見て、 SIGNAL()
および SLOT()
マクロが何をするかを調査することをお勧めします。これらの定義は、 $ QTDIR / src / corelib / kernel / qobjectdefs.h
他のヒント
指定したドキュメントリンクによると、ウィジェットに Qt :: WA_Hover
フラグがある場合にのみ、このQHoverEventを取得します。
ウィジェット呼び出しの構築後:
widget->setAttribute(Qt::WA_Hover);
それが機能するかどうかを確認します。
同じ結果を得る別の方法は、ウィジェットで mouseMoveEvent()
をオーバーライドすることです
この関数も、以下を呼び出さない限り通常は呼び出されないことに注意してください。
widget->setMouseTracking(true);
これは基本的に、QTが内部的にホバーイベントを実装する方法です。
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
マウスがマウスを出入りするときにQtに強制的にペイントイベントを生成させます ウィジェット。この機能は通常、カスタムを実装するときに使用されます スタイル;詳細については、スタイルの例を参照してください。
この
QStyle :: polish()
オーバーロードは、描画されるすべてのウィジェットで1回呼び出されます スタイルを使用します。Qt :: WA_Hover
属性を設定するために再実装しますQPushButtons
およびQComboBoxes
で。この属性が設定されると、Qt マウスポインターが出入りするときにペイントイベントを生成します ウィジェット。これにより、プッシュボタンとコンボボックスをレンダリングできます マウスポインターがそれらの上にあるときとは異なります。
QWidget
でEnterイベントとLeaveイベントを受信する方法
-
WA_Hoverのウィジェット属性の設定
// in your widget's constructor (probably) this->setAttribute(Qt::WA_HOVER, true);
-
QWidget :: enterEvent()
および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); }
-
完了
QWidgetのQHoverEvent
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);
}
更新:
簡単な例
ボタンにカーソルを合わせて、カウントの変化を確認します。詳細については、アプリケーションの出力をご覧ください。
https://gist.github.com/peteristhegreat/d6564cd0992351f98aa94f869be36f77
役立つこと。
同じ問題を抱えていましたが、次のソリューション設計に行き着きました:
メインウィジェットで、選択したオブジェクトのホバーイベントを処理したいと思います。このため、 MainWindow
に2つのスロットを作成しました:
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
次に、次のようなイベントフィルタークラスを作成しました:
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;
}
このクラスは、発生した内容に応じてHoverInまたはHoverOutのいずれかを起動することがわかります。 この方法では、 Qt :: WA_Hover
最後のステップとして、どの要素をフィルタリングし、信号とスロットを接続するかを指示する必要があります。 mainwindow.hでイベントフィルターへのプライベートポインターを作成します
class MainWindow : public QWidget
{
Q_OBJECT
...
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
private:
HoverEventFilter* hoverEventFilter;
...
};
そしてコンストラクターに、これを追加します:
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*)));
オブジェクトのホバーイベントを受け取りたいときはいつでも、次のようにイベントフィルターを設定するだけです:
this->ui->someLabelOrWhatever->installEventFilter(this->hoverEventFilter);
残っているのは、 MainWindow
の onHoverIn
および onHoverOut
の実装です。どちらも同じアイデアを共有しているので、 onHoverIn
void MainWindow::onHoverIn(QObject *object)
{
QString objectName = object->objectName();
switch(objectName){
// do something depending on name of the widget
}
}
これを非常に簡単に拡張できます。新しいアイテムのホバーイベントを処理するには、イベントリスナーを設定し、 onHoverIn
と onHoverOutで何をしたいかを処理します。
メソッド。ウィジェットをサブクラス化する必要はありません。
QHoverEvent
はホバーウィジェット専用です。代わりにウィジェットをサブクラス化して、 enterEvent
および leaveEvent
ハンドラーを実装します。
代わりにイベントフィルターを使用する場合、対応するイベントタイプは QEvent :: Enter
および QEvent :: Leave
です。
ウィジェットの外観を単に変更する必要がある場合は、:hover
セレクターが用意されているため、Qtスタイルシートを調べてください。
focusInEvent および focusOutEvent 。