即使已接受QTabletEvent,也会调用QWidget的mousePressEvent [英] mousePressEvent of QWidget gets called even though QTabletEvent was accepted

查看:91
本文介绍了即使已接受QTabletEvent,也会调用QWidget的mousePressEvent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在具有实现的tabletEvent(QTabletEvent * event)和mousePressEvent(QMouseEvent * event)的QWidget派生类对象中,每当TabletEvent用TabletEvent :: TabletPress类型调用时,都会调用mousePressEvent.根据 Qt文档,这不应发生:

In a QWidget derived class object with implemented tabletEvent(QTabletEvent *event) and mousePressEvent(QMouseEvent *event), the mousePressEvent gets called every time tabletEvent gets called with type TabletEvent::TabletPress. According to the Qt documentation, this should not happen:

事件处理程序QWidget :: tabletEvent()接收TabletPress,TabletRelease和TabletMove事件.Qt将首先发送一个平板电脑事件,然后如果任何小部件不接受它,它将发送一个鼠标事件.

mainwindow.cpp

mainwindow.cpp

#include "mainwindow.h"
#include "tabletwidget.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    TabletWidget* tw = new TabletWidget(this);
    setCentralWidget(tw);
}

tabletwidget.h

tabletwidget.h

#ifndef TABLETWIDGET_H
#define TABLETWIDGET_H

#include <QWidget>

class TabletWidget : public QWidget
{
    Q_OBJECT
public:
    explicit TabletWidget(QWidget *parent = 0);

protected:
    void tabletEvent(QTabletEvent *event) Q_DECL_OVERRIDE;
    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

signals:

public slots:
};

#endif // TABLETWIDGET_H

tabletwidget.cpp

tabletwidget.cpp

#include "tabletwidget.h"
#include <QDebug>
#include <QTabletEvent>

TabletWidget::TabletWidget(QWidget *parent) : QWidget(parent)
{

}

void TabletWidget::tabletEvent(QTabletEvent *event)
{
    event->accept();
    qDebug() << "tabletEvent: " << event->type();
}

void TabletWidget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "mousePressEvent";
}

如果我使用笔尖或按Wacom Intuos CTH-680S-DEIT的任何按钮,则生成的输出为:

The output generated if I use the tip of the pen or press any button of the Wacom Intuos CTH-680S-DEIT is:

tabletEvent:  92
mousePressEvent
tabletEvent:  87
tabletEvent:  87
tabletEvent:  87
tabletEvent:  87
tabletEvent:  93

因此,首先会调用tabletEvent,即使我接受该事件,无论如何也会调用mousePressEvent.接下来的每个tabletEvent的类型都是QTabletEvent :: TabletMove,最后一个是QTabletEvent :: TabletRelease.从 Qt文档:

So first the tabletEvent gets called, and even though I accept the event, mousePressEvent gets called anyway. Every following tabletEvent is of type QTabletEvent::TabletMove and the last one is QTabletEvent::TabletRelease. From the Qt documentation:

QEvent::TabletMove 87
QEvent::TabletPress 92
QEvent::TabletRelease 93

我已经在Mac OS 10.10.3和Windows 7上进行了测试,结果相同.这是错误还是我做错了?

I have tested this on Mac OS 10.10.3 and Windows 7 with the same result. Is this a bug or am I doing it wrong?

这已在Qt 5.4.2上进行了测试.

This is tested on Qt 5.4.2.

推荐答案

实际上,根据Qt文档,当使用数位板时,Qt不应发送鼠标事件.但这似乎还是可以做到的(我使用的是5.5版).

Indeed, according to Qt documentation, the Qt should not be sending mouse events when the tablet is in use. But it seems to do it anyway (I'm using version 5.5).

解决该问题的一种方法是重新实现 QApplication event()方法-在这里, TabletEnterProximity TabletLeaveProximity 已发送;这些函数不会发送到 QWidget event().

One way to get around it is to reimplement event() method of QApplication - that's where TabletEnterProximity and TabletLeaveProximity are sent; those functions are not sent to the QWidget's event().

因此,每当应用程序捕获到 TabletEnterProximity TabletLeaveProximity 事件时,您都可以向您的 TabletWidget 发送信号以更改私有布尔变量 _deviceActive .然后,在 TabletWidget 内部,为每个 MousePressEvent (和 MouseReleaseEvent )添加一个检查,以查看 _deviceActive 是否为正确与否;并仅在标志为false时实施事件.

So, whenever the application catches either TabletEnterProximity or TabletLeaveProximity events, you may send a signal to your TabletWidget to change a private bool variable _deviceActive. Then, inside the TabletWidget you add a check for each MousePressEvent (and MouseReleaseEvent) to see if the _deviceActive is true or not; and implement the event only if the flag is false.

为说明起见,继承的 TabletApplication 如下所示:

To illustrate, the inherited TabletApplication would look like this:

class TabletApplication : public QApplication {
    Q_OBJECT
public:
    TabletApplication(int& argv, char** argc): QApplication(argv,argc){}
    bool event(QEvent* event){
        if (event->type() == QEvent::TabletEnterProximity || event->type() == QEvent::TabletLeaveProximity) {
            bool active = event->type() == QEvent::TabletEnterProximity? 1:0;
            emit sendTabletDevice(active);
            return true; 
        }
        return QApplication::event(event);
}
signals:
    void sendTabletActive(bool active);
};

以及 tabletwidget.h 中的其他部分:

class TabletWidget : public QWidget {
// ...
public slots:
     void setTabletDeviceActive(bool active){
          _deviceActive = active;
     }
// ...
private:
     bool _deviceActive;
};

然后您在鼠标事件中检查设备是否处于活动状态:

Then you check inside the mouse events if the device is active:

void TabletWidget::mousePressEvent(QMouseEvent *event)
{
     if (!_deviceActive) 
         qDebug() << "mousePressEvent";
}

当然,不要忘记将相应的信号连接到插槽.希望对您有所帮助.

Of course, don't forget to connect the corresponding signal with the slot. Hope it helps.

参考:来自Qt平板电脑的TabletApplication例子

这篇关于即使已接受QTabletEvent,也会调用QWidget的mousePressEvent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆