To my knowledge there is no default Qml-item for handling zooming. PinchArea is the currently best for providing zoom by pinch, but it doesn't work on desktop, and the default zoom behaviour isn't really to my liking.
Luckily Qml provides different transformations, and you can create your own zoomable area with a little extra effort. The following is my take on a draggable and zoomable Qml-item. This works on Android and on desktop (zoom with wheel). You can test this code by creating a Qt Quick application with the wizard in Qt Creator 3.1.1, and copy pasting this code into the default file called "main.qml"
import QtQuick 2.2 import QtQuick.Window 2.1 Window { id: container visible: true width: 1280 height: 768 Rectangle { id: rect gradient: Gradient { GradientStop { position: 0.0; color: "red" } GradientStop { position: 0.33; color: "yellow" } GradientStop { position: 1.0; color: "green" } } border.width: 2 width: 600 height: 600 transform: Scale { id: scaler origin.x: pinchArea.m_x2 origin.y: pinchArea.m_y2 xScale: pinchArea.m_zoom2 yScale: pinchArea.m_zoom2 } PinchArea { id: pinchArea anchors.fill: parent property real m_x1: 0 property real m_y1: 0 property real m_y2: 0 property real m_x2: 0 property real m_zoom1: 0.5 property real m_zoom2: 0.5 property real m_max: 2 property real m_min: 0.5 onPinchStarted: { console.log("Pinch Started") m_x1 = scaler.origin.x m_y1 = scaler.origin.y m_x2 = pinch.startCenter.x m_y2 = pinch.startCenter.y rect.x = rect.x + (pinchArea.m_x1-pinchArea.m_x2)*(1-pinchArea.m_zoom1) rect.y = rect.y + (pinchArea.m_y1-pinchArea.m_y2)*(1-pinchArea.m_zoom1) } onPinchUpdated: { console.log("Pinch Updated") m_zoom1 = scaler.xScale var dz = pinch.scale-pinch.previousScale var newZoom = m_zoom1+dz if (newZoom <= m_max && newZoom >= m_min) { m_zoom2 = newZoom } } MouseArea { id: dragArea hoverEnabled: true anchors.fill: parent drag.target: rect drag.filterChildren: true onWheel: { console.log("Wheel Scrolled") pinchArea.m_x1 = scaler.origin.x pinchArea.m_y1 = scaler.origin.y pinchArea.m_zoom1 = scaler.xScale pinchArea.m_x2 = mouseX pinchArea.m_y2 = mouseY var newZoom if (wheel.angleDelta.y > 0) { newZoom = pinchArea.m_zoom1+0.1 if (newZoom <= pinchArea.m_max) { pinchArea.m_zoom2 = newZoom } else { pinchArea.m_zoom2 = pinchArea.m_max } } else { newZoom = pinchArea.m_zoom1-0.1 if (newZoom >= pinchArea.m_min) { pinchArea.m_zoom2 = newZoom } else { pinchArea.m_zoom2 = pinchArea.m_min } } rect.x = rect.x + (pinchArea.m_x1-pinchArea.m_x2)*(1-pinchArea.m_zoom1) rect.y = rect.y + (pinchArea.m_y1-pinchArea.m_y2)*(1-pinchArea.m_zoom1) } MouseArea { anchors.fill: parent onClicked: console.log("Click in child") } } } } }
By default the descendant MouseAreas of the "dragArea" will "steal" the dragging event, and drag will not work. In this case you can enable the drag by providing setting "drag.filterChildren" to true in "dragArea".
Thanks for sharing this code. But i have one query regarding this.Currently zoomable item can be dragged anywhere without setting drag.minimumX, drag.minimumY and drag.maximumX, drag.maximumY. But how can i set these drag values so that it can be dragged within container bounds.?
VastaaPoistaThanks for sharing this code. But i have one query regarding this.Currently zoomable item can be dragged anywhere without setting drag.minimumX, drag.minimumY and drag.maximumX, drag.maximumY. But how can i set these drag values so that it can be dragged within container bounds.?
VastaaPoistaHi! Unfortunately you have to do this "manually" by checking the bounds on every mouse move event. And even more effort must be put into checking that the bounds are respected on zoom events. I don't have ready example for this...
PoistaHopefully qml will soon provide a standard item that supports these operations so that everyone doesn't have to code their own version.
Hi! Unfortunately you have to do this "manually" by checking the bounds on every mouse move event. And even more effort must be put into checking that the bounds are respected on zoom events. I don't have ready example for this...
PoistaHopefully qml will soon provide a standard item that supports these operations so that everyone doesn't have to code their own version.