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()}
新聞熱點
疑難解答