我想在我的小部件中加入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;
}
问题是我在QTapAndHoldGesture
的末尾得到了不想要的QTapGesture
。
它看起来是这样的:
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
发布于 2018-05-25 21:52:53
因为QTapAndHoldGesture
手势也需要“点击”,所以预计它会同时收到这两个:
首先,当用户保持一定时间时(然后,当用户释放
时,结束触摸
因为它们总是按该顺序接收,所以您可以使用这一事实来过滤或取消将在验证接收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事件类型,但我相信在您的情况下它不会被触发。
https://stackoverflow.com/questions/50457215
复制相似问题