[英]QML PinchArea not working as expected with QML Flickable
So I was implementing a simple image viewer and wanted to implement pinch to zoom inside a Flickable
. 因此,我实现了一个简单的图像查看器,并希望实现捏以在
Flickable
缩放。 After looking at several example, I came across this and thought I could do something similar. 看了几个例子之后,我遇到了这个问题,并认为我可以做类似的事情。 However, when I tested the code (Qt 5.13 on Android) it doesn't work as expected.
但是,当我测试代码(Android上的Qt 5.13)时,它无法按预期工作。 The problem is that when the image is zoomed, the
PinchArea
stops working and the user is unable to zoom out while the Flickable
still allows to "flick" the image (at that zoom level). 问题在于,当缩放图像时,
PinchArea
停止工作,并且用户无法缩小,而Flickable
仍允许“轻拂”图像(处于该缩放级别)。 Here is the code, which I couldn't find any mistake with: 这是代码,我找不到任何错误:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Flickable Image Zoom Example")
Page {
id: imagePage
property string imgUrl: "qrc:/messi.jpg"
property string strHpTitle: ""
property string strThumbnailUrl: ""
anchors.fill: parent
Flickable {
id: imageFlickable
anchors.fill: parent
contentWidth: imageContainer.width; contentHeight: imageContainer.height
clip: true
onHeightChanged: if (imagePreview.status === Image.Ready) imagePreview.fitToScreen();
Item {
id: imageContainer
width: Math.max(imagePreview.width * imagePreview.scale, imageFlickable.width)
height: Math.max(imagePreview.height * imagePreview.scale, imageFlickable.height)
Image {
id: imagePreview
property real prevScale
function fitToScreen() {
scale = Math.min(imageFlickable.width / width, imageFlickable.height / height, 1)
pinchArea.minScale = scale
prevScale = scale
}
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
cache: false
asynchronous: true
source: imagePage.imgUrl
sourceSize.height: 1000;
smooth: !imageFlickable.moving
onStatusChanged: {
if (status == Image.Ready) {
fitToScreen()
}
}
onScaleChanged: {
if ((width * scale) > imageFlickable.width) {
var xoff = (imageFlickable.width / 2 + imageFlickable.contentX) * scale / prevScale;
imageFlickable.contentX = xoff - imageFlickable.width / 2
}
if ((height * scale) > imageFlickable.height) {
var yoff = (imageFlickable.height / 2 + imageFlickable.contentY) * scale / prevScale;
imageFlickable.contentY = yoff - imageFlickable.height / 2
}
prevScale = scale
}
}
}
PinchArea {
id: pinchArea
property real minScale: 1.0
property real maxScale: 3.0
anchors.fill: parent
pinch.target: imagePreview
pinch.minimumScale: minScale
pinch.maximumScale: maxScale
pinch.dragAxis: Pinch.XandYAxis
onPinchFinished: {
imageFlickable.returnToBounds()
}
}
}
}
}
Ok so I found the solution to this problem. 好的,所以我找到了解决此问题的方法。 The issue (I think) is due to a bug.
该问题(我认为)是由于错误所致。 For some strange reason, the
Flickable
in my code steals touch events from the PinchArea
so the pinching touch events are ignored and passed onto the Flickable
. 由于某些奇怪的原因,我的代码中的
Flickable
从PinchArea
窃取了触摸事件,因此,捏触摸事件被忽略并传递到Flickable
。 In order to solve the problem, I found a workaround which consists in creating a MouseArea
inside the PinchArea
, this allows the PinchArea
to receive the touch events so that the Flickable
doesn't steal them. 为了解决该问题,我找到了一种解决方法,其中包括在
PinchArea
内创建一个MouseArea
,这使PinchArea
可以接收触摸事件,以便Flickable
不会窃取它们。 So with the workaround my code has the following structure: 因此,通过变通办法,我的代码具有以下结构:
Flickable{
PinchArea{
MouseArea{ anchors.fill: parent} // this is the workaround
}
Item{}
}
I have reported the bug here and uploaded a small video showing the cause. 我已在此处报告了该错误,并上传了一个显示原因的小视频。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.