Qt5.5 如何在应用程序级别覆盖 MousePress 事件坐标

Posted

技术标签:

【中文标题】Qt5.5 如何在应用程序级别覆盖 MousePress 事件坐标【英文标题】:Qt5.5 How to override MousePress event coordinates at Application level 【发布时间】:2015-10-04 18:13:07 【问题描述】:

我正在使用 Qt5.5 在小型嵌入式 Linux 设备上开发应用程序。我需要能够在我的应用程序中修改从 Linux ( tslib ) 接收的鼠标按下坐标。我尝试在我的主视图中实现一个事件过滤器,它修改接收到的鼠标坐标,创建一个新的鼠标事件并将新事件提交给小部件。但是,在小部件的 mousePressEvent 函数中,我只看到一次调试消息,它是接收到的原始坐标,而不是我截取和修改的坐标。

目前,当我触摸屏幕时,我会收到调试消息,它们看起来像这样:

Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Original:  QPoint(192,148)
Mouse New:  QPoint(128,148)
Mouse Press 192 148

如何在顶层拦截鼠标事件、修改它们的坐标并将它们发布到我的小部件,同时还能使用原始鼠标事件?谢谢!

main.cpp:

MyWidget w;
app.installEventFilter(&w);
w.show();

我的小部件:

bool MyWidget::eventFilter(QObject *object, QEvent *event)


    if ( event->type() == QEvent::MouseButtonPress ) 
        QMouseEvent *orig = static_cast<QMouseEvent*>( event );
        QPoint origLocation = orig->pos();
        qDebug() << "Mouse Original: "<< origLocation;
        int newx = abs(origLocation.x()-320);
        QPoint newPoint(newx,origLocation.y());
        QMouseEvent *newPosEvent = new QMouseEvent(QEvent::MouseButtonPress, newPoint, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        qDebug() << "Mouse New: " << newPosEvent->pos();
        //qApp->postEvent(this, newPos);
        return QObject::eventFilter(object, newPosEvent);
    

    return QObject::eventFilter(object, event);


void MyWidget::mousePressEvent ( QMouseEvent * event )

    qDebug() << "Mouse Press" << event->x() << event->y();

【问题讨论】:

【参考方案1】:

您可以通过从 eventFilter() 方法返回 true 来“使用”该事件并停止其进一步传播。如果您不使用事件过滤器,则可以使用其accept() 方法停止该事件。

您可以使用静态方法QCoreApplication::postEvent(obj, evnt);重新发布您创建的事件

另外,您可能想要更深入地拦截,例如在QWindow 级别。我的意思是,如果您在小部件级别拦截它,并将其再次发布到您的小部件,它将再次被事件过滤器拦截。您没有发布新活动,而是收到了原始活动,因为您没有阻止它传播。

另外,如果你想产生点击,你必须连续发布两个事件,一个按下和释放事件:

    QMouseEvent * e1 = new QMouseEvent(QEvent::MouseButtonPress, QPointF(x, y), Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
    QCoreApplication::postEvent(obj, e1);
    QMouseEvent * e2 = new QMouseEvent(QEvent::MouseButtonRelease, QPointF(x, y), Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
    QCoreApplication::postEvent(obj, e2);

【讨论】:

obj 在子类中是什么?在我试图实现这一点的类中,我有ScribbleArea::ScribbleArea(QWidget *parent) : QWidget(parent) 用于.cpp 文件的构造函数部分。我想在 drawLine() 函数中捕获两个鼠标事件。 @developer01 检查文档postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)

以上是关于Qt5.5 如何在应用程序级别覆盖 MousePress 事件坐标的主要内容,如果未能解决你的问题,请参考以下文章

ui_* 文件不是 QT5.5 生成的

如何在 Qt5.5 中使用 gstreamer1.0 而不是 0.10?

如何在VS2015中集成QT5.5

Qt5.5 脚本

Qt5.5 为啥不显示错误信息?

git系列1/4git 配置的级别,如何新增删除git配置,配置的覆盖关系配置对应在什么目录