mouseMoveEvent未调用

问题描述 投票:4回答:2

我需要在小部件内移动鼠标:

一个eventFilter是不可能的,因为它将安装在QApplication上。该窗口小部件在类型层次结构中位置很远。将此小部件传递到创建QApplication对象的主要功能上会弄乱代码。

因此我实施了

void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent *event);

在小部件中。

没有任何事件被调用。即使在中央窗口小部件和我实际需要该事件的窗口小部件上将mousetracking设置为true之后,也不会调用这些函数:

centralWidget->setMouseTracking(true);

您如何在Qt中为QWidget的自定义子类获取鼠标事件?

更新:这是.h文件:

class Plot : public QWidget
{
    Q_OBJECT
//...

protected:
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent *event);

更新

我尝试了eventFilter方法。

在.h文件中:

protected:
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent *event);

    bool eventFilter(QObject* object, QEvent* event);

。cpp中:

void Plot::mousePressEvent(QMouseEvent *event){
//...
}
void Plot::mouseMoveEvent(QMouseEvent *event){

}
void Plot::mouseReleaseEvent(QMouseEvent *event){

}

bool Plot::eventFilter(QObject* object, QEvent* event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* mev=static_cast<QMouseEvent*>(event);

        qDebug()<<mev->x();
    }
   return false;
}

然后在我的qWidget的构造函数中:

this->installEventFilter(this);

代码可以编译并正常运行。事件过滤器中if语句的断点将停止程序,将调用eventFilter方法。但是if语句永远不会评估为true。即使简单的buttonPress事件也不会注册。

仍然不调用事件的覆盖方法。

c++ qt qt5
2个回答
2
投票
bool someClass::eventFilter(QObject* object, QEvent* event)
{
    if(event->type() == QEvent::MouseMove)
    {
         mouseMoveFunction(static_cast<QMouseEvent*>(event))
    }
    // Repeat for other mouse events 

   // returning true blocks event returning false doesnt so if you want to block all mouse events except what your handling then return true inside each of your ifs
   return false;
}

然后将事件过滤器安装在您希望对其应用过滤器的任何对象上,为此,请假设您在ui类中(在构造函数中这样做)

this->installEventFilter(this)

编辑:OP使用的是QCustomPlot,根据以前的经验,我知道这会消耗所有事件,并且不会将它们传递回去,因此您必须连接到鼠标单击(或您想要的任何事件),该信号随点或事件发出在里面


1
投票

我也需要在较深的层次结构中过滤鼠标事件,并且上面的答案对我而言还不是很有效。我不得不花一点时间来使工作正常。

您需要向QCoreApplication注册子类化的小部件,但这可以轻松完成而无需遍历层次结构。在子类的构造函数中,添加以下行:

QCoreApplication::instance()->installEventFilter(this);

您的子类现在将接收所有事件,仅需过滤所需内容即可。

下面的完整示例

Header File:
MouseMoveReaderBox : QScrollArea
{
    Q_OBJECT
public:
    explicit MouseMoveReaderBox(QWidget *parent = 0);
    ~MouseMoveReaderBox();

protected:
    bool eventFilter(QObject *obj, QEvent *event);
}

Source File:
#include "MouseMoveReaderBox"

MouseMoveReaderBox::MouseMoveReaderBox(QWidget *parent = 0):
    QScrollArea(parent)
{
     QCoreApplicaiton::instance()->installEventFilter(this);
}

bool MouseMoveReaderBox::eventFilter(QObject *obj, QEvent *event)
{
    if(event.type() == QEvent::MouseMove)
    {
        // logic here...
        return true;// if you want to intercept
    }
    // Other event type checks here...
    return false;//the signal will be delivered other filters
}

希望这会有所帮助,因为我知道我正在拔头发!

© www.soinside.com 2019 - 2024. All rights reserved.