我希望在我的小部件中获得QTapAndHoldGesture
和QTapGesture
,并对这些手势做出不同的反应。所以我重写QWidget::event
方法并添加这样的代码:
bool event(QEvent *event) override {
if (event->type() == QEvent::Gesture) {
auto g_event = static_cast<QGestureEvent *>(event);
qDebug() << "GestureEvent BEGIN: gestures " << g_event->gestures().size() << ", active: " << g_event->activeGestures();
if (auto g = qobject_cast<QTapGesture *>(g_event->gesture(Qt::TapGesture))) {
g_event->accept(g);
return true;
}
if (auto g = qobject_cast<QTapAndHoldGesture *>(g_event->gesture(Qt::TapAndHoldGesture))) {
if (g->state() == Qt::GestureFinished) {
qDebug("FINISHED!!!");
g->setGestureCancelPolicy(QGesture::CancelAllInContext);
}
g_event->accept(g);
return true;
}
问题是我在QTapGesture
结束时不想要QTapAndHoldGesture
。
它看起来像这样:
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureStarted,hotSpot=773.396,492.884,position=773.396,492.884))
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureUpdated,hotSpot=773.396,492.884,position=773.396,492.884))
mouse event x 773 , y 493
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureUpdated,hotSpot=773.396,492.884,position=773.396,492.884))
...
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureUpdated,hotSpot=773.396,492.884,position=773.396,492.884))
GestureEvent BEGIN: gestures 1 , active: (QTapAndHoldGesture(state=GestureStarted,hotSpot=773,493,position=773,493,timeout=700))
GestureEvent BEGIN: gestures 1 , active: (QTapAndHoldGesture(state=GestureFinished,hotSpot=773,493,position=773,493,timeout=700))
FINISHED!!!
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureUpdated,hotSpot=773.396,492.884,position=773.396,492.884))
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureUpdated,hotSpot=773.396,492.884,position=773.396,492.884))
GestureEvent BEGIN: gestures 1 , active: (QTapGesture(state=GestureFinished,hotSpot=773.396,492.884,position=773.396,492.884))
正如你在开始时看到的那样,QTapGesture
处于启动状态,然后QTapGesture
处于更新状态,之后QTapAndHoldGesture
和之后的QTabGesture
完成。
我需要一些方法来忽略它。但是我没有看到如果没有重新实现手势框架:收集事件的位置和时间并根据这些信息过滤事件。因为我一个接一个地接受手势,不能连接QTapGesture
和QTapAndHoldGesture
。
那么有可能在QTapGesture
之后忽略QTapAndHoldGesture
而没有收集关于QGestureEvent
的位置和时间的信息吗?
因为QTapAndHoldGesture
手势也需要“Tap”,所以预计会同时收到:
因为它们将始终以该顺序接收,所以当您收到QTapAndHoldGesture验证(即已完成)时,您可以使用该事实来过滤或取消将启动但未完成的QTapGesture。
如果您管理单个接触点,则无需时间或位置信息(免责声明:以下内容未经测试)。
bool MyClass::event(QEvent *event) override
{
// QPointer in case we receive partial events. Should remove "isNull()" keys at some point.
static QMap<QPointer<QTapGesture*>, bool> tapGestures;
if (event->type() != QEvent::Gesture)
return QQuickItem::event(event);
auto g_event = static_cast<QGestureEvent *>(event);
if (auto g = qobject_cast<QTapGesture *>(g_event->gesture(Qt::TapGesture))) {
// A TapAndHold was triggered during that tap... let's ignore it
if (tapGestures.value(g))
g_event->ignore(g); // Or handle as you like
if (g->state() == Qt::GestureFinished || g->state() == Qt::GestureCancelled)
tapGestures.remove(g);
else if (!tapGestures.contains(g))
tapGestures.insert(g, false);
g_event->accept(g);
return true;
}
if (auto g = qobject_cast<QTapAndHoldGesture *>(g_event->gesture(Qt::TapAndHoldGesture))) {
// Probably not needed if the gesture handle doesn't conflict with another component
//if (g->state() == Qt::GestureFinished)
// g->setGestureCancelPolicy(QGesture::CancelAllInContext);
// Mark all QTapGesture in progress to be ignored
for (auto it = tapGestures.begin(); it != tapGestures.end(); ++it)
it.value() = true;
g_event->accept(g);
return true;
}
}
所有手势都在QGestureManager class中提供,因此可能有办法访问它。
还有GestureOverride事件类型,但我相信在你的情况下它不会被触发。