我发现有同样的问题,于是设计了以下解决方案:
在我的主窗口小部件中,我希望处理一些选定对象的悬停事件。因此,我在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.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
方法中处理您希望执行的操作即可。无需子类化任何小部件。
QWidget::enterEvent()
和QWidget::leaveEvent()
不是虚函数。 - juzzlin