我只是用C ++学习Qt。我已经成功实现了信号和插槽来捕获标准事件,如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
甚至从QWidget
继承了mouseMoveEvent()。如果这是真的,是否有一个小部件,或者在某个地方继承它的对象列表?我从他们网站上的文档中可以看出,对象有多少继承的函数..
答案 0 :(得分:13)
根据您提供的文档链接,如果您的小部件具有Qt::WA_Hover
标记,则只会获得此QHoverEvent。
构建小部件调用后:
widget->setAttribute(Qt::WA_Hover);
看看它是否有效。
实现相同结果的另一种方法是覆盖小部件中的mouseMoveEvent()
请注意,除非您致电:
widget->setMouseTracking(true);
这基本上是QT如何在内部实现悬停事件。
答案 1 :(得分:8)
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在鼠标进入或离开时生成绘画事件 小部件。实现自定义时通常使用此功能 款式;有关详细信息,请参阅样式示例。
在绘制的每个小部件上调用一次
QStyle::polish()
重载 使用风格。我们重新实现它以设置Qt::WA_Hover
属性 在QPushButtons
和QComboBoxes
上。设置此属性后,Qt 鼠标指针进入或离开时生成绘画事件 小部件。这使得可以渲染按钮和组合框 当鼠标指针悬停在它们上方时会有所不同。
QWidget
设置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);
}
完成
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
希望有所帮助。
答案 2 :(得分:7)
为此目的使用信号和插槽不起作用。
mouseMoveEvent()
不是信号或元方法,也不能连接到插槽。
对窗口小部件类进行子类化并覆盖mouseMoveEvent()
将允许您获取鼠标移动事件,但这是实现此目的的一种非常重要的方法(并为您的源基础添加一个类)。
相反,请考虑在eventFilter()
课程上实施MyDialog
方法并将其安装在QLabel
上。使用此事件过滤器方法,您可以拦截给定QObject
实例的所有事件。
以下是有关事件过滤器的文档。
http://doc.qt.io/qt-4.8/eventsandfilters.html#event-filters
此外,通过查看代码示例,我建议您花点时间研究SIGNAL()
和SLOT()
宏的作用。您可以在$QTDIR/src/corelib/kernel/qobjectdefs.h
答案 3 :(得分:2)
我遇到了同样的问题,我进入了以下解决方案设计:
在我的主要小部件中,我想处理某些选定对象的悬停事件。出于这个原因,我在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);
剩下的是onHoverIn
中onHoverOut
和MainWindow
的实施。他们都有相同的想法,所以我只会展示onHoverIn
void MainWindow::onHoverIn(QObject *object)
{
QString objectName = object->objectName();
switch(objectName){
// do something depending on name of the widget
}
}
您可以轻松地扩展它,以便在新项目上处理悬停事件,您只需在其上设置一个事件监听器,并在onHoverIn
和onHoverOut
方法中处理您希望执行的操作。无需子类化任何小部件。
答案 4 :(得分:1)
QHoverEvent
仅适用于悬停小部件,您希望通过继承小部件来实现enterEvent
和leaveEvent
处理程序。
如果您想使用事件过滤器,则相应的事件类型为QEvent::Enter
和QEvent::Leave
。
如果您只是需要更改窗口小部件的外观,您可能需要查看Qt样式表,因为它们提供了:hover
选择器。
答案 5 :(得分:-3)
您需要子类化或过滤该特定小部件的focusInEvent和focusOutEvent。