我正在学习 Qt 和 C++。我已经成功地实现了信号和槽来捕获标准事件,例如 ButtonPushed(), , ETC。但是,我希望当我将鼠标悬停在鼠标上并移出鼠标时调用一个函数 QLabel. 。看起来像 QHover事件 会做我需要的事情,但我似乎找不到任何关于如何实现这一点的教程或示例。它的处理方式与信号和槽相同吗?我试过:

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()将允许您获取鼠标移动事件,但这是实现此目的的一种非常重要的方法(并为您的源代码库增加一个类) )。

相反,请考虑在 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_悬停

强制 Qt 在鼠标进入或离开 控件。此功能通常在实现自定义时使用 风格;有关详细信息,请参阅样式示例。

http://qt-project.org/doc/qt-5/qtwidgets-widgets-styles-example.html#norwegianwoodstyle-class-implementation

QStyle::polish() 重载在每个绘制的小部件上调用一次 使用样式。我们重新实现它来设置 Qt::WA_Hover 属性 上 QPushButtonsQComboBoxes. 。设置此属性时,Qt 当鼠标指针进入或离开 控件。这样就可以渲染按钮和组合框 当鼠标指针位于它们上方时,情况有所不同。

如何接收进入和离开事件 QWidget

  1. 设置 WA_Hover 的小部件属性

    // in your widget's constructor (probably)
    this->setAttribute(Qt::WA_HOVER, true);
    
  2. 实施 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);
    }
    
  3. 完毕

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

如果您只是需要更改窗口小部件的外观,您可能需要查看Qt样式表,因为它们提供了:hover 选择器。

您需要子类化或过滤 focusInEvent focusOutEvent

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top