即使已接受QTabletEvent,也会调用QWidget的mousePressEvent [英] mousePressEvent of QWidget gets called even though QTabletEvent was accepted
问题描述
在具有实现的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屋!