Qt Quick demo -Photo Surface

Click to download the latest trial version of Qt6

A QML application for touch devices that uses a Repeater with FolderListModel to access the contents of folders and a PinchArea with MouseArea to handle kneading gestures on retrieving content.

Photo Surface

Demonstrated how to use Repeater with FolderListModel and FileDialog to access images in user-selected folders, and how to use PinchArea with MouseArea to handle drag, rotate, and zoom within the same project.

All application code is contained in a QML file, photosurface.qml. Inline JavaScript code is used to place, rotate, and scale images on the photo surface.

Run the example

To run the sample from Qt Creator, open Welcome mode, and then select the sample from Examples.

Create the main window

To create the main Window for the Photo Surface application, we use the Window QML type as the root project. It automatically sets the window to use with the Qt Quick graphics type:

Window {
    id: root
    visible: true
    width: 1024; height: 600
    color: "black"
    property int highestZ: 0
    property real defaultSize: 200
    property var currentFrame: undefined
Copy the code

To use the Window type, we must import:

The import QtQuick. Windows 2.1Copy the code

Accessing folder contents

We use the Repeater QML type with FolderListModel to display GIF, JPG, and PNG images located in folders:

        Repeater {
            model: FolderListModel {
                id: folderModel
                objectName: "folderModel"
                showDirs: false
                nameFilters: imageNameFilters
            }
Copy the code

To use the FolderListModel type, we must import:

The import Qt. LABS. Folderlistmodel 1.0Copy the code

We use FileDialog to enable the user to select the folder containing the image:

    FileDialog {
        id: fileDialog
        title: "Choose a folder with some images"
        selectFolder: true
        folder: picturesLocation
        onAccepted: folderModel.folder = fileUrl + "/"
    }
Copy the code

To use the FileDialog type, we must import the Qt quick dialog:

The import QtQuick. Dialogs 1.0Copy the code

Filedialog.open () when the application starts, we use this function to open the fileDialog box:

Component.onCompleted: fileDialog.open()
Copy the code

The user can also click the file dialog icon to open the file dialog box. We use the Image QML type to display ICONS. Inside the Image type, we call the filedialog.open () function using MouseAreaonClicked with a signal handler:

Displays an image on a photo surface

We use Rectangle as a delegate to Repeater to frame each image FolderListModel finds in the selected folder. We use the JavaScriptMath() method to place frames randomly on the photo surface, rotate them at any Angle, and scale the image:

  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()
            hoverEnabled: true
            onPositionChanged: {
                tooltip.visible = false
                hoverTimer.start()
            }
            onExited: {
                tooltip.visible = false
                hoverTimer.stop()
            }
Copy the code

Handle kneading gestures

We use a PinchArea with a MouseArea inside the frame to handle dragging, rotating, and pinching of the frame.

Rectangle {id: photoFrame width: image.width * (1 + 0.10 * image.height/image.width) height: 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 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}Copy the code

We use the PinchGroup attribute to control the frame’s response to kneading gestures. The pinch. Target group photoFrame project to operate on. The rotate property specifies that frames can be rotated at all angles, while the scale property specifies that they can be scaled between 0.1 and 10.

In MouseArea’s onPressed signal handler, we boost the selected frame to the top by increasing the value of its Z property. The root entry stores the z value of the uppermost frame. Controls the frame border color in the onEntered signal handler to highlight the selected image:

PinchArea { anchors.fill: parent pinch.target: photoFrame pinch.minimumRotation: -360 pinch.maximumRotation: 360 pinch. MinimumScale: 0.1 pinch. MaximumScale: 10 pinch. DragAxis: pinchStarted: setFrameColor();Copy the code

To enable you to test the example on the desktop, we use MouseArea’s onWheel signal handler to simulate pinching gestures by using the mouse:

          MouseArea {
                        id: dragArea
                        hoverEnabled: true
                        anchors.fill: parent
                        drag.target: photoFrame
                        scrollGestureEnabled: false  // 2-finger-flick gesture should pass through to the Flickable
                        onPressed: {
                            photoFrame.z = ++root.highestZ;
                            parent.setFrameColor();
                        }
                        onEntered: parent.setFrameColor();
Copy the code

The onWheel signal handler is called in response to the mouse wheel gesture. Use the vertical scroll wheel to zoom and Ctrl keys and the vertical scroll wheel to rotate the frame. If the mouse has a horizontal scroll wheel, use it to rotate the frame.

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; }}Copy the code

Qt related components:

  • QtitanRibbon:**** Is the Ribbon UI component of the Microsoft Ribbon UI Paradigm for Qt technology, dedicated to providing fully functional Ribbon components for Windows, Linux and Mac OS X.
  • **QtitanChart :** is a C ++ library that represents a set of controls that enable you to quickly produce beautiful and rich charts for your applications. All major desktop operating systems are supported.
  • **QtitanDataGrid :** this Qt data grid component is created in pure C++ and is extremely fast and works well with large data and very large data sets. QtitanDataGrid is fully integrated with QtDesigner, making it easy to adapt to other similar development environments, ensuring 100% Qt GUI compatibility.