Qt中的事件处理程序

时间:2012-05-16 21:50:03

标签: c++ qt

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

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

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

我是Qt的新手,我无法找到任何我能理解的信息。

有人可以向我解释如何将事件处理程序绑定到单个QObject吗?

提前致谢。

3 个答案:

答案 0 :(得分:4)

我用另一种方式通过使用QtCreator中的'Promote to ...'选项来解决这个问题。 正如此处所述:http://sector.ynet.sk/qt4-tutorial/customing-widgets.html

我添加了一个“MyPushButton”类:

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

mypushbutton.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并选择了'Promote to ...'并且我将MyPushButton添加为'Promoted class name'。

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

答案 1 :(得分: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);
处理程序例程中的

答案 2 :(得分:1)

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

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

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));