在 Qt QML SwipeView 中,如何确保 Dials 始终处理触摸输入而不是底层 SwipeView?

问题描述 投票:0回答:1

背景

我有一个包含多个页面的SwipeView。它专为直径为 2.1 英寸的小圆形屏幕而设计,其想法是在页面之间向左或向右滑动,每个页面都有一个或几个 UI 元素可以与之交互。其中许多页面包含一个Dial和小/没有别的。也许底部中心有一个按钮。

问题

通过触摸(预期的输入设备),Dial 内的水平拖动通常被解释为在下方的 SwipeView 中导航。它很少意识到我想调整表盘。

使用鼠标,Dial 似乎非常可靠地抓住了拖动手势,因此即使是水平拖动(例如从表盘的顶部或底部)也不会无意中在 SwipeView 的页面之间导航。

有关触摸行为与鼠标行为的比较,请参阅此视频(我无法直接在 StackOverflow 编辑器中上传它,所以我希望 imgur 的链接可以接受)

问题

有没有办法让 Dial 优先于解释触摸/滑动手势,这样用户就不会意外地在页面之间滑动? (更像鼠标行为)

我可以通过垂直开始手势然后移动到所需位置来解决这个问题,但我不想告诉我的用户,这似乎是他们在这个应用程序中最常见的挂断。

刻度盘是窗口本身大小的 70%,因此刻度盘外部有足够的空间供用户滑动 SwipeView。

到目前为止我已经尝试/考虑过的

我试过设置 SwipeView

interactive: !(dial1.pressed || dial2.pressed)
等,但这不起作用。似乎转盘的
.pressed
属性在转盘被明确选择用于处理输入之前不会生效。在这个特定的例子中,我更希望它的行为更像它对鼠标的行为。

在考虑纯

interactive: false
的 SwipeView 时——这样 Dial 可以保证接收手势——我必须在每个屏幕上添加按钮以在页面之间导航,这将带走我的房间对于其他 UI 元素。拨号页面是唯一给我带来麻烦的页面。其他页面在手势冲突风险很小的地方已经有 1-3 个按钮。如果我必须在页面的任一侧添加一个按钮,它就会开始将内容压缩到难以在预期的屏幕尺寸上点击的程度。

我目前唯一能想到的其他选择是编辑/完成按钮(如模态对话框?),但这会增加一些我宁愿避免的摩擦。

代码

此代码是视频中所见的最小可重现示例。我上次在 Ubuntu 20.04 上使用 USB/HDMI 触摸屏尝试 Qt 6.3.0。

import QtQuick
import QtQuick.Controls.Basic

Window {
    width: 480
    height: 480
    visible: true
    title: "SwipeView Dial Test"

    SwipeView {
        anchors.fill: parent
        Item {
            Dial {
                id: dial1
                anchors.centerIn: parent
                width: parent.width * 0.7
                height: parent.height * 0.7
            }
        }
        Item {
            Dial {
                id: dial2
                anchors.centerIn: parent
                width: parent.width * 0.7
                height: parent.height * 0.7
            }
        }
    }
}
qt qml touch
1个回答
0
投票

我做了一些检查,并同意 Dial 对于您的用例来说有些损坏。您建议的解决方法都是合乎逻辑的,我不会忽略它们,但会进一步研究它们。编辑/完成模式可以通过“单击”编辑和“单击外部”完成来工作到拨号区域本身。

   SwipeView {
        id: swipeView
        anchors.fill: parent
        MouseArea {
            Dial {
                id: dial1
                anchors.centerIn: parent
                width: parent.width * 0.7
                height: parent.height * 0.7
                enabled: focus
                focus: true
            }
            MouseArea {
                anchors.fill: dial1
                enabled: !dial1.enabled
                onClicked: {
                    dial1.forceActiveFocus();
                    swipeView.interactive = false;
                }
            }
            onClicked: {
                forceActiveFocus();
                swipeView.interactive = true;
            }
        }
        MouseArea {
            Dial {
                id: dial2
                anchors.centerIn: parent
                width: parent.width * 0.7
                height: parent.height * 0.7
                enabled: focus
                focus: true
            }
            MouseArea {
                anchors.fill: dial2
                enabled: !dial2.enabled
                onClicked: {
                    dial2.forceActiveFocus();
                    swipeView.interactive = false;
                }
            }
            onClicked: {
                forceActiveFocus();
                swipeView.interactive = true;
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.