2

我正在尝试在 Qt 中实现鼠标悬停效果,但我不知道如何使用事件处理程序。我用一个按钮创建了一个简单的 Qt 小部件应用程序。我可以像这样将事件处理程序绑定到 MainWindow:

MainWindow::enterEvent(QEvent *event)
{
    ui->pushButton_3->setGraphicsEffect(effect);
}

这行得通,graphicsEffect 应用于 pushButton。但我不明白如何将事件处理程序绑定到单个 QObject。据我所知,不可能使用信号,因为它们只支持点击事件而没有鼠标悬停事件。

我对 Qt 很陌生,我找不到任何我能理解的信息。

谁能向我解释如何将事件处理程序绑定到单个 QObject?

提前致谢。

4

3 回答 3

6

我以另一种方式通过使用 QtCreator 中的“提升到...”选项来解决这个问题。还解释了这里:http ://sector.ynet.sk/qt4-tutorial/customing-widgets.html

我添加了一个类“MyPushButton”:

我的按钮.h

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>
#include <QGraphicsDropShadowEffect>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    MyPushButton(QWidget *parent = 0);

private:
    void enterEvent(QEvent *e);
    void leaveEvent(QEvent *e);

    QGraphicsDropShadowEffect *effect;
};

#endif // MYPUSHBUTTON_H

我的按钮.cpp

#include "mypushbutton.h"

MyPushButton::MyPushButton(QWidget *parent)
    :QPushButton(parent)
{
    effect = new QGraphicsDropShadowEffect();
    effect->setBlurRadius(5);
    effect->setEnabled(false);
    this->setGraphicsEffect(effect);
}

void MyPushButton::enterEvent(QEvent *event)
{
    if (this->isEnabled())
        effect->setEnabled(true);
}

void MyPushButton::leaveEvent(QEvent *event)
{
    if (this->isEnabled())
        effect->setEnabled(false);
}

然后我在编辑器中右键单击我的 QPushButton 并选择了“提升为 ...”,并将 MyPushButton 添加为“提升的类名”。

它就像一个魅力,很容易扩展或定制,因为它适用于任何事件。

于 2012-05-17T08:39:56.763 回答
1

如果您使用的是 QPushButton,这里的描述非常好:

http://www.developer.nokia.com/Community/Wiki/How_to_use_QPushButton_in_Qt

对于进入和离开事件,请看这里:Finding current mouse position in QT

例如,如果你做了一些继承自 QGraphicsRectItem 的东西,你可以像这样覆盖鼠标事件:

class BTNodeGraphicsItem : public QGraphicsRectItem
{
protected:
    virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
    // other class stuff
};

然后

void BTNodeGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
    // do stuff here
}

如果你想让事件更进一步,那么你添加

QGraphicsRectItem::mousePressEvent(event);

在处理程序例程中。

于 2012-05-16T21:53:26.323 回答
1

如果您想为 QWidgets 指定依赖于事件的行为,而不是对每个事件进行子类化,则可以使用事件过滤器。如Qt 的文档所述,创建一个事件过滤器,并将其应用于相关的小部件。

我在下面写了一个简单的示例,但请注意,当您开始有多种交互行为时,以这种方式使用过滤器会变得越来越复杂。我发现它们对于需要跨多种不同类型的小部件应用的简单行为最有效。

class WidgetHoverEffectEnabler : public QObject
{
Q_OBJECT
public:
   WidgetHoverEffectEnabler(QObject* parent);

   virtual bool eventFilter(QObject* obj, QEvent* e);
};

WidgetHoverEffectEnabler::WidgetHoverEffectEnabler(QObject* parent)
: QObject(parent)
{
}

bool WidgetHoverEffectEnabler::eventFilter(QObject* obj, QEvent* e)
{
   if(QWidget* widget = qobject_cast<QWidget*>(obj))
   {
      QGraphicsEffect* effect = widget->graphicsEffect();
      if(effect)
      {
         if(e->type() == QEvent::Enter)
         {
            effect->setEnabled(true);
         }
         else if(e->type() == QEvent::Leave)
         {
            effect->setEnabled(false);
         }
      }
   }
   return QObject::eventFilter(obj, e);
}

然后您可以在初始化期间在您的小部件上安装该过滤器:

// works on your button
QPushButton* button = new QPushButton;
QGraphicsDropShadowEffect* dropShadowEffect = new QGraphicsDropShadowEffect;
dropShadowEffect->setEnabled(false);
button->setGraphicsEffect(dropShadowEffect);
button->installEventFilter(new WidgetHoverEffectEnabler(button));

// works on any widget
QLabel* label = new QLabel("Read me!");
QGraphicsBlurEffect* blurEffect = new QGraphicsBlurEffect;
blurEffect->setEnabled(false);
label->setGraphicsEffect(blurEffect);
label->installEventFilter(new WidgetHoverEffectEnabler(label));
于 2012-05-17T01:17:00.060 回答