C++ 如何在 Qt 中实现 QHoverEvent?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/411823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I implement QHoverEvent in Qt?
提问by Alpants
I'm just learning Qt with C++. I have successfully implemented signals and slots to trap standard events like ButtonPushed()
, etc. However, I want to have a function called when I mouse over and mouse out of a QLabel
. It looks like QHoverEventwill do what I need, but I can't seem to find any tutorials or examples on how to implement this. Is it done the same way as signals and slots?. I tried:
我只是在用 C++ 学习 Qt。我已经成功地实现了信号和槽来捕获标准事件,例如ButtonPushed()
,等等。但是,我想在我将鼠标悬停在QLabel
. 看起来QHoverEvent会做我需要的,但我似乎找不到任何关于如何实现它的教程或示例。它的完成方式与信号和插槽相同吗?我试过:
connect(ui.lbl_test, SIGNAL(QHoverEvent), this, SLOT(TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos)));
.. but the function didn't get called when I hovered over the label.
.. 但是当我将鼠标悬停在标签上时没有调用该函数。
Here is the function, listed in the header file as a public slot:
这是在头文件中作为公共槽列出的函数:
void MyDialog::TestFunc(QEvent::Type type, const QPoint & pos, const QPoint & oldPos) {
QMessageBox::information(this, tr("Hey"), tr("Listen!"));
}
Can anyone help me figure this out or point me to a good example?
谁能帮我解决这个问题或给我指出一个很好的例子?
EDIT:
编辑:
After reading a post below, I found no setFlag()
member to call for my label widget, but I did try:
阅读下面的帖子后,我发现没有setFlag()
成员调用我的标签小部件,但我确实尝试过:
ui.lbl_test->setMouseTracking(true);
connect(ui.lbl_test, SIGNAL(ui.lbl_test->mouseMoveEvent()), this, SLOT(TestFunc(QMouseEvent *event)));
And updated TestFunc()
accordingly. But still nothing happens when I mouse over.
并相应更新TestFunc()
。但是当我鼠标悬停时仍然没有任何反应。
After looking I am not sure QLabel
even inherits the mouseMoveEvent() even from QWidget
. If this is true, is there a widget that does, or a list of objects that inherit it somewhere?. All I can tell from the documentation on their site is how many inherited functions an object has..
看了之后,我QLabel
什至不确定是否从QWidget
. 如果这是真的,是否有一个小部件,或者在某处继承它的对象列表?我可以从他们网站上的文档中得知一个对象有多少继承的函数。
回答by shoosh
According to the document link you give you're only going to get this QHoverEvent if your widget has the Qt::WA_Hover
flag.
根据您提供的文档链接,如果您的小部件具有Qt::WA_Hover
标志,您只会获得此 QHoverEvent 。
After constructing the widget call:
构建小部件调用后:
widget->setAttribute(Qt::WA_Hover);
and see if it works.
看看它是否有效。
Another way of achieving the same result is to override mouseMoveEvent()
in your widget
notice that this function too will not be normally called unless you call:
实现相同结果的另一种方法是mouseMoveEvent()
在您的小部件中覆盖
注意,除非您调用,否则通常不会调用此函数:
widget->setMouseTracking(true);
This is basically how QT implements the hover event internally.
这基本上就是 QT 在内部实现悬停事件的方式。
回答by phyatt
http://qt-project.org/doc/qt-5/qwidget.html#enterEvent
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/qwidget.html#leaveEvent
http://qt-project.org/doc/qt-5/qt.html#widget-attributes
http://qt-project.org/doc/qt-5/qt.html#widget-attributes
Qt::WA_Hover
Qt::WA_Hover
Forces Qt to generate paint events when the mouse enters or leaves the widget. This feature is typically used when implementing custom styles; see the Styles example for details.
当鼠标进入或离开小部件时,强制 Qt 生成绘制事件。此功能通常在实现自定义样式时使用;有关详细信息,请参阅样式示例。
This
QStyle::polish()
overload is called once on every widget drawn using the style. We reimplement it to set theQt::WA_Hover
attribute onQPushButtons
andQComboBoxes
. When this attribute is set, Qt generates paint events when the mouse pointer enters or leaves the widget. This makes it possible to render push buttons and comboboxes differently when the mouse pointer is over them.
此
QStyle::polish()
重载在使用该样式绘制的每个小部件上调用一次。我们重新实现它以将Qt::WA_Hover
属性设置为QPushButtons
和QComboBoxes
。设置此属性后,Qt 会在鼠标指针进入或离开小部件时生成绘制事件。这使得可以在鼠标指针悬停在按钮和组合框上时以不同的方式呈现它们。
How to receive Enter and Leave Events on a QWidget
如何接收进入和离开事件 QWidget
Set the Widget Attribute for WA_Hover
// in your widget's constructor (probably) this->setAttribute(Qt::WA_HOVER, true);
Implement
QWidget::enterEvent()
andQWidget::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); }
Done
为 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); }
完毕
QHoverEvent in QWidget
QWidget 中的 QHoverEvent
http://qt-project.org/doc/qt-5/qhoverevent.html#details
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/qobject.html#event
http://qt-project.org/doc/qt-5/qwidget.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:
更新:
Simple Example
简单示例
Hover the button and see the count change. Look at the application output for more information.
将鼠标悬停在按钮上并查看计数变化。查看应用程序输出以获取更多信息。
https://gist.github.com/peteristhegreat/d6564cd0992351f98aa94f869be36f77
https://gist.github.com/peteristhegreat/d6564cd0992351f98aa94f869be36f77
Hope that helps.
希望有帮助。
回答by Michael Bishop
Using signals and slots for this purpose isn't going to work.
为此目的使用信号和插槽是行不通的。
mouseMoveEvent()
is not a signal or meta-method and cannot be connected to a slot.
mouseMoveEvent()
不是信号或元方法,不能连接到插槽。
Subclassing the widget class and overriding mouseMoveEvent()
will allow you to get mouse-move-events, but that is a very heavyweight way to accomplish this (and adds one more class to your source base).
子类化小部件类并覆盖mouseMoveEvent()
将允许您获得鼠标移动事件,但这是实现此目的的一种非常重量级的方法(并向您的源代码库添加一个更多类)。
Instead, consider implementing an eventFilter()
method on your MyDialog
class and installing it on the QLabel
. With this event filter method, you can intercept all the events for a given QObject
instance.
相反,请考虑eventFilter()
在您的MyDialog
类上实现一个方法并将其安装在QLabel
. 使用此事件过滤器方法,您可以拦截给定QObject
实例的所有事件。
Here is the documentation on Event Filters.
这是有关事件过滤器的文档。
http://doc.qt.io/qt-4.8/eventsandfilters.html#event-filters
http://doc.qt.io/qt-4.8/eventsandfilters.html#event-filters
Additionally, through looking at the code sample, I'd recommend you take a moment to investigate what the SIGNAL()
and SLOT()
macros do. You can see how they are defined in $QTDIR/src/corelib/kernel/qobjectdefs.h
此外,通过查看代码示例,我建议您花点时间研究SIGNAL()
和SLOT()
宏的作用。你可以看到它们是如何定义的$QTDIR/src/corelib/kernel/qobjectdefs.h
回答by michnovka
I was having the same issue, I came to the following solution design:
我遇到了同样的问题,我来到了以下解决方案设计:
In my main widget, I'd like to process hover events of some selected objects. For this reason, I created 2 slots on my MainWindow
:
在我的主要小部件中,我想处理一些选定对象的悬停事件。出于这个原因,我在我的上创建了 2 个插槽MainWindow
:
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
Then I created an Event Filter class like this:
然后我创建了一个这样的事件过滤器类:
hovereventfilter.h
悬停事件过滤器.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
悬停事件过滤器.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;
}
You can see this class will fire either HoverIn or HoverOut depending on what happened. This approach does not need settings of Qt::WA_Hover
您可以看到这个类将根据发生的情况触发 HoverIn 或 HoverOut。这种方法不需要设置Qt::WA_Hover
Now as last step, we need to instruct which elements are to be filtered and connect signals and slots. I will create a private pointer to event filter in mainwindow.h
现在作为最后一步,我们需要指示要过滤哪些元素并连接信号和插槽。我将在 mainwindow.h 中创建一个指向事件过滤器的私有指针
class MainWindow : public QWidget
{
Q_OBJECT
...
public slots:
void onHoverIn(QObject* object);
void onHoverOut(QObject* object);
private:
HoverEventFilter* hoverEventFilter;
...
};
And in constructor, I add this:
在构造函数中,我添加了以下内容:
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*)));
Now whenever I wish to receive hover events on some object, I just set event filter on it, like this:
现在,每当我希望在某个对象上接收悬停事件时,我只需在其上设置事件过滤器,如下所示:
this->ui->someLabelOrWhatever->installEventFilter(this->hoverEventFilter);
What is left is implementation of onHoverIn
and onHoverOut
in MainWindow
. They both share the same idea so I will show just onHoverIn
剩下的是onHoverIn
和onHoverOut
in 的实现MainWindow
。他们都有相同的想法,所以我只会展示onHoverIn
void MainWindow::onHoverIn(QObject *object)
{
QString objectName = object->objectName();
switch(objectName){
// do something depending on name of the widget
}
}
You can extend this so easily, to process hover events on new item, you just set an event listener on it and take care of what you wish to do in the onHoverIn
and onHoverOut
methods. No need to subclass any widgets.
你可以很容易地扩展它,处理新项目上的悬停事件,你只需在它上面设置一个事件侦听器,并在onHoverIn
和onHoverOut
方法中处理你想要做的事情。无需对任何小部件进行子类化。
回答by Sebastian Wahl
QHoverEvent
is only for hover widgets, you want to implement the enterEvent
and leaveEvent
handlers by subclassing the widget instead.
If you want to use an event filter instead, the corresponding event types are QEvent::Enter
and QEvent::Leave
.
QHoverEvent
仅适用于悬停小部件,您希望通过对小部件进行子类化来实现enterEvent
和leaveEvent
处理程序。如果要改用事件过滤器,则相应的事件类型为QEvent::Enter
和QEvent::Leave
。
If you simply need to change the appearance of the widget, you might want to look into Qt stylesheets, as they provide a :hover
selector.
如果您只需要更改小部件的外观,您可能需要查看 Qt 样式表,因为它们提供了一个:hover
选择器。
回答by Ariya Hidayat
You need to subclass or filter focusInEventand focusOutEventof that particular widget.
您需要子类化或过滤该特定小部件的focusInEvent和focusOutEvent。