在一个带有实现的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上测试的。
答案 0 :(得分:3)
实际上,根据Qt文档,Qt不应该在平板电脑使用时发送鼠标事件。但无论如何它似乎都是这样做的(我使用的是5.5版)。
解决这个问题的一种方法是重新实施event()
QApplication
方法 - 即发送TabletEnterProximity
和TabletLeaveProximity
的方法;这些功能不会发送到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;
};
当然,不要忘记将相应的信号连接到插槽。希望它有所帮助。