我有一个包含多个页面的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
}
}
}
}
我做了一些检查,并同意 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;
}
}
}