简体   繁体   English

QML PinchArea无法与QML Flickable一起使用

[英]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 . 由于某些奇怪的原因,我的代码中的FlickablePinchArea窃取了触摸事件,因此,捏触摸事件被忽略并传递到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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM