首页 > 学院 > 开发设计 > 正文

QML-例程photosurface

2019-11-08 01:59:17
字体:
来源:转载
供稿:网友

import QtQuick 2.5 import QtQuick.Dialogs 1.0 import QtQuick.Window 2.1 import Qt.labs.folderlistmodel 1.0

Window { id: root visible: true width: 1024; height: 600 color: “blue” PRoperty int highestZ: 0 property real defaultSize: 200 property var currentFrame: undefined property real surfaceViewportRatio: 1.5

FileDialog { id: fileDialog title: "Choose a folder with some images" selectFolder: true //选中文件通知 onAccepted: folderModel.folder = fileUrl + "/"}Flickable { id: flick anchors.fill: parent //布局->anchors.fill设置内部矩形的锚点为填充(fill),填充的目的对象是parent // 由于一个实现的细节,放置在Flickable里面的项不能用id来anchor,而用parent代替 contentWidth: width * surfaceViewportRatio contentHeight: height * surfaceViewportRatio // 指明了内容的大小 Repeater { //模型 model: FolderListModel { //访问本地系统中一个文件夹的内容的组件 id: folderModel objectName: "folderModel" showDirs: false //目录能使用showDirs属性设置包含和排除。 如果为真,目录包含在model中,否则model只包含文件 nameFilters: ["*.png", "*.jpg", "*.gif"] } Rectangle { //声明了一个矩形 id: photoFrame //设置唯一标识 width: image.width * (1 + 0.10 * image.height / image.width) height: image.height * 1.10 scale: defaultSize / Math.max(image.sourceSize.width, image.sourceSize.height) //缩放属性 //Behavior 让属性变化具有一定的动画效果 Behavior on scale { NumberAnimation { duration: 200 } } Behavior on x { NumberAnimation { duration: 200 } } Behavior on y { NumberAnimation { duration: 200 } } border.color: "black" //边框设置 border.width: 2 smooth: true //渐变 antialiasing: true //抗锯齿,默认就是开启的 Component.onCompleted: { x = Math.random() * root.width - width / 2 y = Math.random() * root.height - height / 2 rotation = Math.random() * 13 - 6 } //QtQuick所有的Object都有的一个附带信号处理函数。 Image { //在场景中使用位图 id: image //定义唯一的ID anchors.centerIn: parent //anchors 描点布局 fillMode: Image.PreserveaspectFit //图片按比例缩放,但不裁减。 source: folderModel.folder + fileName //图片 antialiasing: true //抗锯齿 } //触摸变化 PinchArea { anchors.fill: parent //描点布局 pinch.target: photoFrame //target来指定想要旋转和缩放的对象 pinch.minimumRotation: -360 //制了可见对象的范围.旋转属性,单不是手势事件的旋转属性 pinch.maximumRotation: 360 pinch.minimumScale: 0.1 //限制了可见对象的范围,但是并不是手势事件的缩放属性. pinch.maximumScale: 10 pinch.dragAxis: Pinch.XAndYAxis //dragAxis指定了是否拖拽是被允许的.可以是Pinch.XAxis,Pinch.YAxis,Pinch.XAndYAxis. onPinchStarted: setFrameColor(); property real zRestore: 0 //具体实现算法 onSmartZoom: { if (pinch.scale > 0) { photoFrame.rotation = 0; photoFrame.scale = Math.min(root.width, root.height) / Math.max(image.sourceSize.width, image.sourceSize.height) * 0.85 photoFrame.x = flick.contentX + (flick.width - photoFrame.width) / 2 photoFrame.y = flick.contentY + (flick.height - photoFrame.height) / 2 zRestore = photoFrame.z photoFrame.z = ++root.highestZ; } else { photoFrame.rotation = pinch.previousAngle photoFrame.scale = pinch.previousScale photoFrame.x = pinch.previousCenter.x - photoFrame.width / 2 photoFrame.y = pinch.previousCenter.y - photoFrame.height / 2 photoFrame.z = zRestore --root.highestZ } } //鼠标句柄交互 MouseArea { id: dragArea //唯一ID hoverEnabled: true //默认false,只有按下鼠标键时才处理鼠标事件,为true时即使没有按下鼠标键也会作相应的处理 anchors.fill: parent //布局、描点布局 drag.target: photoFrame //实现移动效果 scrollGestureEnabled: false // 2-finger-flick gesture should pass through to the Flickable //MouseEvent类型的参数提供有关按下时的鼠标信息,包括鼠标的位置以及按下时对应的鼠标按键。 onPressed: { photoFrame.z = ++root.highestZ; parent.setFrameColor(); } onEntered: parent.setFrameColor(); onWheel: { if (wheel.modifiers & Qt.ControlModifier) { photoFrame.rotation += wheel.angleDelta.y / 120 * 5; if (Math.abs(photoFrame.rotation) < 4) photoFrame.rotation = 0; } else { photoFrame.rotation += wheel.angleDelta.x / 120; if (Math.abs(photoFrame.rotation) < 0.6) photoFrame.rotation = 0; var scaleBefore = photoFrame.scale; photoFrame.scale += photoFrame.scale * wheel.angleDelta.y / 120 / 10; } } } function setFrameColor() { if (currentFrame) currentFrame.border.color = "black"; currentFrame = photoFrame; currentFrame.border.color = "red"; } } } }}Rectangle { id: verticalScrollDecorator anchors.right: parent.right anchors.margins: 2 color: "cyan" border.color: "black" border.width: 1 width: 5 radius: 2 antialiasing: true height: flick.height * (flick.height / flick.contentHeight) - (width - anchors.margins) * 2 y: flick.contentY * (flick.height / flick.contentHeight) NumberAnimation on opacity { id: vfade; to: 0; duration: 500 } onYChanged: { opacity = 1.0; fadeTimer.restart() }}Rectangle { id: horizontalScrollDecorator anchors.bottom: parent.bottom anchors.margins: 2 color: "cyan" border.color: "black" border.width: 1 height: 5 radius: 2 antialiasing: true width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2 x: flick.contentX * (flick.width / flick.contentWidth) NumberAnimation on opacity { id: hfade; to: 0; duration: 500 } onXChanged: { opacity = 1.0; fadeTimer.restart() }}Timer { id: fadeTimer; interval: 1000; onTriggered: { hfade.start(); vfade.start() } }Image { anchors.top: parent.top anchors.left: parent.left anchors.margins: 10 source: "resources/folder.png" MouseArea { anchors.fill: parent anchors.margins: -10 onClicked: fileDialog.open() }}Text { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right anchors.margins: 10 color: "darkgrey" wrapMode: Text.WordWrap font.pointSize: 8 text: "On a touchscreen: use two fingers to zoom and rotate, one finger to drag/n" + "With a mouse: drag normally, use the vertical wheel to zoom, horizontal wheel to rotate, or hold Ctrl while using the vertical wheel to rotate"}Component.onCompleted: fileDialog.open()

}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表