QML 动画 - 移动应用程序 window

QML animation - moving the application window

我想创建一个动画来移动(或调整大小)我使用 QML 构建的应用程序 Window。

我有以下代码(其中大部分是在我们创建 QT quick Controls 应用程序时默认创建的:

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

MainForm.ui.qml

import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Layouts 1.3

Item {
    width: 640
    height: 480

    property alias button1: button1
    property alias button2: button2

    RowLayout {
        anchors.centerIn: parent

        Button {
            id: button1
            text: qsTr("Press Me 1")
        }

        Button {
            id: button2
            text: qsTr("Press Me 2")
        }
    }
}

main.qml

import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Dialogs 1.2

ApplicationWindow {
    id: mainWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    MainForm {
        anchors.fill: parent
        button1.onClicked: Qt.quit();
        button2.onClicked: state = "other";
    }

    transitions: [
        Transition {
            from: "*"
            to: "other"
            NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad; duration: 2000 }

        }
    ]

    states: [
        State {
           name: "other"
           PropertyChanges {
               target: mainWindow
               x: x + 200
           }
       }
    ]

    MessageDialog {
        id: messageDialog

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
}

使用此代码,我只是想将我的 window 200 像素向右移动。当我尝试 运行 它时,我得到 qrc:/main.qml:42 Cannot assign to non-existent property "states"。我认为这很奇怪,因为当我开始输入 "states" 并选择自动完成时,它为我构建了整个结构,所以我认为它应该存在...

我是 QML 的新手,我并不完全熟悉现有的几个动画选项。这是我根据 QT Creator 附带的示例尝试过的(animation.pro - 来自转换的代码)。

相信应该很简单吧?你能帮我解决这个问题吗?

Qt Creator 具有一项功能,您可以使用特定关键字插入代码片段。您可以前往 Tools > Options > Text Editor > Snippets.

查看可用的片段

片段将在自动完成弹出窗口中显示为红色,而常规属性(或类型,如下所示)将显示为绿色:

因此,ApplicationWindow 没有状态 属性。如果您有任何疑问,请转到您感兴趣的类型的文档(例如 http://doc.qt.io/qt-5/qml-qtquick-controls-applicationwindow.html) and click on the link that says "List of all members, including inherited members”)。这将向您显示属于的所有属性、函数等 到那种类型。


如果您想为 window 的位置设置动画,您可以使用 NumberAnimation 而无需使用状态:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.5

ApplicationWindow {
    id: window
    width: 400
    height: 400
    visible: true

    NumberAnimation {
        id: xyAnimation
        target: window
        properties: "x,y"
        easing.type: Easing.InOutQuad
        duration: 2000
        to: 500
    }

    Button {
        text: "Start"
        onClicked: xyAnimation.start()
    }
}

state is a property in Item, however ApplicationWindow is not an Item. To add state/transition to an non-Item type, use StateGroup:

ApplicationWindow {
    id: mainWindow
    //your code...

    MainForm {
        button2.onClicked: { myWindowStates.state = "other";}
    }

    StateGroup {
        id: myWindowStates

        transitions: [
            Transition {
                from: "*"; to: "other"
                NumberAnimation { 
                    properties: "x,y"; easing.type: Easing.Linear; 
                    duration: 2000 
                }
            }
        ]

        states: [
            State {
               name: "other"
               PropertyChanges {
                   target: mainWindow
                   x: mainWindow.x + 200
                   explicit: true //Remember to set this
               }
           }
        ]
    }
}

记得将PropertyChange.explict设置为true,否则状态行为是错误的,你的window将在转换完成后消失。