首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在QTapAndHoldGesture之后如何忽略QTapGesture

在QTapAndHoldGesture之后如何忽略QTapGesture
EN

Stack Overflow用户
提问于 2018-05-22 06:10:35
回答 1查看 427关注 0票数 9

我想在我的小部件中加入QTapAndHoldGestureQTapGesture,并对这些手势做不同的反应。所以我覆盖了QWidget::event方法并添加了这样的代码:

代码语言:javascript
复制
 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

它看起来是这样的:

代码语言:javascript
复制
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完成之后。

我需要一些方法来忽略它。但是我不明白如果不重新实现手势框架:收集事件的位置和时间,并根据这些信息过滤事件。因为我一个接一个的接收手势,不能连接QTapGestureQTapAndHoldGesture

那么,在不收集有关QTapGesture的位置和时间的信息的情况下,是否可以在QTapAndHoldGesture之后忽略QGestureEvent

EN

回答 1

Stack Overflow用户

发布于 2018-05-25 21:52:53

因为QTapAndHoldGesture手势也需要“点击”,所以预计它会同时收到这两个:

首先,当用户保持一定时间时(然后,当用户释放

  • QTapAndHoldGesture

时,结束触摸

因为它们总是按该顺序接收,所以您可以使用这一事实来过滤或取消将在验证接收QTapAndHoldGesture (即完成)时启动但不会完成的QTapGesture。

如果您正在管理单个触摸点,则不需要时间或位置信息(免责声明:以下内容未经测试)。

代码语言:javascript
复制
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事件类型,但我相信在您的情况下它不会被触发。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50457215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档