Tho*_*itz 5 c++ qt mouseevent qt5
在实现了 tabletEvent(QTabletEvent *event) 和 mousePressEvent(QMouseEvent *event) 的 QWidget 派生类对象中,每次使用 TabletEvent::TabletPress 类型调用 tabletEvent 时都会调用 mousePressEvent。根据Qt 文档,这不应该发生:
事件处理程序 QWidget::tabletEvent() 接收 TabletPress、TabletRelease 和 TabletMove 事件。Qt 将首先发送一个平板电脑事件,然后如果它不被任何小部件接受,它将发送一个鼠标事件。
主窗口.cpp
#include "mainwindow.h"
#include "tabletwidget.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
TabletWidget* tw = new TabletWidget(this);
setCentralWidget(tw);
}
Run Code Online (Sandbox Code Playgroud)
平板电脑.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
Run Code Online (Sandbox Code Playgroud)
平板电脑.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";
}
Run Code Online (Sandbox Code Playgroud)
如果我使用笔尖或按下 Wacom Intuos CTH-680S-DEIT 的任何按钮,生成的输出是:
tabletEvent: 92
mousePressEvent
tabletEvent: 87
tabletEvent: 87
tabletEvent: 87
tabletEvent: 87
tabletEvent: 93
Run Code Online (Sandbox Code Playgroud)
所以首先调用 tabletEvent ,即使我接受该事件, mousePressEvent 还是会被调用。接下来的每个 tabletEvent 都是 QTabletEvent::TabletMove 类型,最后一个是 QTabletEvent::TabletRelease。从Qt 文档:
QEvent::TabletMove 87
QEvent::TabletPress 92
QEvent::TabletRelease 93
Run Code Online (Sandbox Code Playgroud)
我已经在 Mac OS 10.10.3 和 Windows 7 上进行了测试,结果相同。这是一个错误还是我做错了?
这是在 Qt 5.4.2 上测试的。
事实上,根据 Qt 文档,当平板电脑在使用时,Qt 不应该发送鼠标事件。但无论如何它似乎都会这样做(我使用的是 5.5 版本)。
解决这个问题的一种方法是重新实现- 这就是发送和的event()方法;这些函数不会发送到's 。QApplicationTabletEnterProximityTabletLeaveProximityQWidgetevent()
因此,每当应用程序捕获TabletEnterProximity或TabletLeaveProximity事件时,您都可以向您发送一个信号TabletWidget以更改私有 bool 变量_deviceActive。然后,在 内部添加对每个( 和)TabletWidget的检查,以查看是否为真;仅当标志为 false 时才执行该事件。 MousePressEventMouseReleaseEvent_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);
};
Run Code Online (Sandbox Code Playgroud)
以及里面的附加部件tabletwidget.h:
class TabletWidget : public QWidget {
// ...
public slots:
void setTabletDeviceActive(bool active){
_deviceActive = active;
}
// ...
private:
bool _deviceActive;
};
Run Code Online (Sandbox Code Playgroud)
然后检查鼠标事件内部设备是否处于活动状态:
void TabletWidget::mousePressEvent(QMouseEvent *event)
{
if (!_deviceActive)
qDebug() << "mousePressEvent";
}
Run Code Online (Sandbox Code Playgroud)
当然,不要忘记将相应的信号与插槽连接起来。希望能帮助到你。
参考:Qt 平板电脑示例中的 TabletApplication