2

Qtでマウスオーバー効果を実装しようとしていますが、イベントハンドラーの使用方法がわかりません。プッシュボタンを使用して単純なQtウィジェットアプリケーションを作成しました。次のように、イベントハンドラーをメインウィンドウにバインドできます。

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

これは機能し、graphicsEffectがpushButtonに適用されます。しかし、イベントハンドラーを単一のQObjectにバインドする方法がわかりません。私の知る限り、シグナルはクリックイベントのみをサポートし、マウスオーバーイベントはサポートしていないため、シグナルを使用することはできません。

私はQtにかなり慣れていないので、理解できる情報を見つけることができませんでした。

イベントハンドラーを単一のQObjectにバインドする方法を誰かに説明してもらえますか?

前もって感謝します。

4

3 に答える 3

6

別の方法で、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 を右クリックし、[プロモート先...] を選択して、MyPushButton を [プロモートされたクラス名] として追加しました。

それは魔法のように機能し、あらゆるイベントで機能するため、拡張やカスタマイズが非常に簡単です.

于 2012-05-17T08:39:56.763 に答える
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 に答える
1

QPushButton を使用している場合は、ここでよく説明されています。

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

Enter イベントと Leave イベントについては、こちらを参照してください: 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 に答える