即使接受了QTabletEvent,也会调用QWidget的mousePressEvent

时间:2015-07-01 22:08:32

标签: c++ qt mouseevent qt5

在一个带有实现的tabletEvent(QTabletEvent * event)和mousePressEvent(QMouseEvent * event)的QWidget派生类对象中,每次使用TabletEvent :: TabletPress类型调用tabletEvent时都会调用mousePressEvent。根据{{​​3}},这不应该发生:

  

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

mainwindow.cpp

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

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

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

#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的任何按钮,则会产生输出:

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

首先调用tabletEvent,即使我接受了这个事件,仍然会调用mousePressEvent。以下每个tabletEvent的类型为QTabletEvent :: TabletMove,最后一个是QTabletEvent :: TabletRelease。来自Qt documentation

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

我在Mac OS 10.10.3和Windows 7上测试过这个结果相同。这是一个错误还是我做错了?

这是在Qt 5.4.2上测试的。

1 个答案:

答案 0 :(得分:3)

实际上,根据Qt文档,Qt不应该在平板电脑使用时发送鼠标事件。但无论如何它似乎都是这样做的(我使用的是5.5版)。

解决这个问题的一种方法是重新实施event() QApplication方法 - 即发送TabletEnterProximityTabletLeaveProximity的方法;这些功能不会发送到QWidget的{​​{1}}。

因此,只要应用程序捕获event()TabletEnterProximity个事件,您就可以向TabletLeaveProximity发送信号以更改私有bool变量TabletWidget。然后,在_deviceActive内,您为每个TabletWidget(和MousePressEvent)添加一个检查,以查看MouseReleaseEvent是否为真;并且仅当标志为false时才实现该事件。

为了说明,继承的_deviceActive将如下所示:

TabletApplication

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;
};

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

参考:TabletApplication from Qt tablet example