我需要在小部件内移动鼠标:
一个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事件也不会注册。
仍然不调用事件的覆盖方法。
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,根据以前的经验,我知道这会消耗所有事件,并且不会将它们传递回去,因此您必须连接到鼠标单击(或您想要的任何事件),该信号随点或事件发出在里面
我也需要在较深的层次结构中过滤鼠标事件,并且上面的答案对我而言还不是很有效。我不得不花一点时间来使工作正常。
您需要向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
}
希望这会有所帮助,因为我知道我正在拔头发!