QML旋转窗口篇

本文介绍了一种使用QML实现的简洁旋转窗口设计,详细展示了界面代码和动画效果,适用于前端开发人员学习和参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经过几天的QML学习中,自己写了一个简洁的旋转窗口特此记录。

实现效果如下:
在这里插入图片描述
界面代码如下:

import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick 2.12
import QtGraphicalEffects 1.12
Window{
    //焦点进入AccountLineEdit状态
    function inputAccountDynamicIcon()
    {
        userIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/DynamicAccountIcon.png"
        passwordIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/PasswordIcon.png"
        showPasswordRectangle.visible = false
        passwordLine.color = "#a1a3a6"
        accountLine.color = "#33a3dc"
    }

    //焦点进入PasswordLineEdit的状态
    function inputPasswordDynamicIcon()
    {
        userIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/AccountIcon.png"
        passwordIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/DynamicPasswordIcon.png"
        if(passwordLineEdit.text != "")
        {
           showPasswordRectangle.visible = true
        }
        accountLine.color = "#a1a3a6"
        passwordLine.color = "#33a3dc"
    }

    //初始化两个LineEdit的状态
    function  inputNoDynamicIcon()
    {
        userIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/AccountIcon.png"
        passwordIcon.source =  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/PasswordIcon.png"
        showPasswordRectangle.visible = false
        accountLine.color = "#a1a3a6"
        passwordLine.color = "#a1a3a6"
    }

    //初始化两个LineEdit等候文本的状态
    function  initHorldTextInfo()
    {
         if(!accountLineEdit.focus && accountLineEdit.text === "")
         {
             accountLineEditPlaceHorldText.text = "请输入文件云账号/QQ账号/手机号"
         }
         else
         {
             accountLineEditPlaceHorldText.text = ""
         }


         if(!passwordLineEdit.focus &&  passwordLineEdit.text === "")
         {
             passwordLineEditPlaceHorldText.text = "请输入密码"
         }
         else
         {
            passwordLineEditPlaceHorldText.text = ""
         }
    }

    function setRgb(r,g,b){
        var result = (r << 16 | g << 8 | b )
        return "#" + result.toString(16)
    }

    id: loginDialog
    flags:  Qt.FramelessWindowHint
    width: 640
    height: 510
    visible: true
    color: "transparent"

    //最低层的Rectangle用于旋转
    Rectangle{
       property int rotateValue: 180
       property int rotateTempValue: 180

       id: baseBackground
       anchors.centerIn: parent
       width: 535
       height: 405
       layer.enabled: true


    //登入背景的gif
    Rectangle{
        id: loginDialogBackgroundRectangle
        width: baseBackground.width
        height: 155
        color: "transparent"
        AnimatedImage{
           id: loginDialogAnimatedImage
           anchors.fill: parent
           source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/LoginDialogBackground.gif"
      }
    }

    //用户的图标(这地方可以考虑做用户切换)
    Rectangle{
        id: userRectangle
        anchors.top: loginDialogBackgroundRectangle.bottom
        anchors.horizontalCenter: loginDialogBackgroundRectangle.horizontalCenter
        anchors.topMargin: -50
        width: 100
        height: 100
        color: "transparent"

        Image{
            id: userImage
            anchors.fill: parent
            source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/UserIcon.png"
        }
    }

    //账号输入框
    TextInput{
        id: accountLineEdit
        anchors.top: loginDialogBackgroundRectangle.bottom
        anchors.horizontalCenter: loginDialogBackgroundRectangle.horizontalCenter
        anchors.topMargin: 60
        width: 300
        font.bold: true
        font.pointSize: 12
        font.family: "微软雅黑"
        color: "black"
        maximumLength: 15
        leftPadding: 40

        MouseArea{
            id: accountLineEditMouseArea
            anchors.fill: parent
            enabled: true
            hoverEnabled: true

            onEntered:{
                if(!accountLineEdit.focus)accountLine.color = loginDialog.setRgb(199,199,199)
            }
            onExited:{
                if(!accountLineEdit.focus)accountLine.color = loginDialog.setRgb(229,229,229)
            }
            onClicked:{
                accountLineEdit.focus = true
                initHorldTextInfo()
                inputAccountDynamicIcon()
            }
        }

        Rectangle{
            id: accountLine
            anchors.bottom: accountLineEdit.bottom
            anchors.horizontalCenter:  accountLineEdit.horizontalCenter
            anchors.bottomMargin: -8
            width: 300
            height: 3
            radius: 1
            color: loginDialog.setRgb(229,229,229)
        }

        Image{
            id:userIcon
            width: 30
            height: 30
            anchors.left: parent.left
            anchors.bottom: parent.top
            anchors.bottomMargin: -25
            source:"file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/AccountIcon.png"
        }

        Text{
            id:accountLineEditPlaceHorldText
            anchors.left: parent.left
            anchors.bottom: parent.top
            anchors.leftMargin: 40
            anchors.bottomMargin: -25
            text: "请输入文件云帐号/QQ帐号/手机号"
            color: "grey"
            font.bold: true
            font.italic: true
            font.pointSize: 10
            font.family: "微软雅黑"
        }
    }

    //密码输入框
    TextInput{
        id: passwordLineEdit
        anchors.top: accountLineEdit.bottom
        anchors.horizontalCenter:  accountLineEdit.horizontalCenter
        anchors.topMargin: 30
        width: 300
        font.bold: true
        font.pointSize: 12
        font.family: "微软雅黑"
        color: "black"
        //clip:  true
        leftPadding: 40
        rightPadding:  40
        maximumLength: 15
        echoMode:  TextInput.Password

        MouseArea{
            id: passwordLineEditMouseArea
            anchors.fill: parent
            enabled: true
            hoverEnabled: true


            onEntered:{
                if(!passwordLineEdit.focus)passwordLine.color = loginDialog.setRgb(199,199,199)
            }
            onExited:{
                if(!passwordLineEdit.focus)passwordLine.color = loginDialog.setRgb(229,229,229)
            }
            onClicked:{
                passwordLineEdit.focus = true
                initHorldTextInfo()
                inputPasswordDynamicIcon()
            }
        }

        Rectangle{
            id: passwordLine
            anchors.bottom: passwordLineEdit.bottom
            anchors.left: passwordLineEdit.left
            anchors.bottomMargin: -8
            width: 300
            height: 3
            radius: 1
            color: loginDialog.setRgb(229,229,229)
        }

        Image{
            id:passwordIcon
            width: 30
            height: 30
            anchors.left: passwordLineEdit.left
            anchors.bottom: passwordLineEdit.top
            anchors.bottomMargin: -25
            source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/PasswordIcon.png"
        }

        Text{
            id:passwordLineEditPlaceHorldText
            anchors.left: parent.left
            anchors.bottom: parent.top
            anchors.leftMargin: 40
            anchors.bottomMargin: -25
            text: "请输入密码"
            color: "grey"
            font.bold: true
            font.italic: true
            font.pointSize: 10
            font.family: "微软雅黑"
        }

        Rectangle
        {
            id: showPasswordRectangle
            anchors.left:  passwordLineEdit.right
            anchors.bottom:  passwordLineEdit.bottom
            anchors.leftMargin: -30
            anchors.bottomMargin: 5
            width: 30
            height: 20
            visible: false
            color: "transparent"

            MouseArea{
                id: showPasswordMouseArea
                anchors.fill: parent
                enabled: true


                onPressed:{
                    passwordLineEdit.echoMode = TextInput.Normal
                    showPasswordIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/DynamicShowPasswordIcon.png"
                }
                onReleased:{
                    passwordLineEdit.echoMode = TextInput.Password
                    showPasswordIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/ShowPasswordIcon"
                }
            }


            Image{
                id: showPasswordIcon
                anchors.fill: parent
                source:  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/ShowPasswordIcon.png"
            }


        }


        onTextEdited:{
            if(passwordLineEdit.text != ""){
                showPasswordRectangle.visible = true
            }
            else{
                showPasswordRectangle.visible = false
            }
        }
    }


    //保存密码的图标
    RadioButton{
        id: savePasswordRadioButton
        anchors.left:  passwordLineEdit.left
        anchors.top: passwordLineEdit.bottom
        anchors.topMargin: 15


        style: RadioButtonStyle{
            indicator: Rectangle{
                implicitWidth: 16
                implicitHeight: 16
                radius: 2
                border.color: control.hovered ? loginDialog.setRgb(199,199,199) : loginDialog.setRgb(229,229,229)


                Rectangle{
                    anchors.fill: parent
                    radius: 5
                    color: "white"
                    visible: control.checked


                    Image{
                        anchors.fill: parent
                        source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/SavePasswordRadioButtonImage.png"
                    }
                }
            }
            label: Text{
                text: "记住密码"
                font.pointSize: 9
                color: loginDialog.setRgb(129,129,129)
            }
         }
      }
    //找回密码的一个文本 可以做成一个链接或者弹出一个对话框
    Text{
       id: amendPasswordText
       anchors.left: savePasswordRadioButton.right
       anchors.top: savePasswordRadioButton.top
       anchors.leftMargin: 40
       text: "找回密码"
       font.pointSize: 9
       color: loginDialog.setRgb(129,129,129)


       MouseArea{
           id: amendPasswordTextMouseArea
           anchors.fill: parent
           hoverEnabled: true


           onEntered: {
               amendPasswordText.color = "black"
           }
           onExited: {
               amendPasswordText.color = loginDialog.setRgb(129,129,129)
           }
           onClicked: {
               console.log("down amend password text")
           }
       }
    }
    //登录按钮
    Rectangle {
          id: loginRectangle
          anchors.top: savePasswordRadioButton.bottom
          anchors.horizontalCenter: passwordLineEdit.horizontalCenter
          anchors.topMargin: 15
          width: 300
          height: 45
          color: "#7bbfea"
          radius: 10
          layer.enabled: true


          MouseArea{
              id: loginRectangleMouseArea
              anchors.fill: parent
              enabled: true
              hoverEnabled: true


              onEntered:{
                baseBackground.color =  loginDialog.setRgb(127,183,223)
                loginRectangle.color = "#009ad6"
              }
              onExited:{
                baseBackground.color = "white"
                loginRectangle.color = "#7bbfea"
              }


              onPressed: {
                  loginRectangle.color = "#145b7d"
              }


              onReleased:{
                 loginRectangle.color = "#009ad6"
              }
              onClicked:{
                  accountLineEdit.focus = false
                  passwordLineEdit.focus = false
                  loginDialog.initHorldTextInfo()
                  loginDialog.inputNoDynamicIcon()


                  //暂停GIF播放同时另一个开启
                  loginDialogAnimatedImage.paused = true
                  loginDialogAnimatedImage1.paused = false


                  baseBackground.scale = 0.9
                  //启动旋转动画
                  rotateTimer.rotateFlag = true
                  rotateTimer.start()
              }
          }


          Text{
             anchors.centerIn: parent
             text: "登录"
             color: "white"
             font.bold: true
             font.pointSize: 13
             font.family: "Cooper Black"
          }


          layer.effect: DropShadow{
              color: "black"
              radius: 5
          }
      }


    //关闭按钮
    Rectangle{
        id: closeRectangle
        anchors.right: parent.right
        anchors.top: parent.top
        width: 30
        height: 30
        color: "transparent"


        MouseArea{
            id: closeRectangleMouseArea
            anchors.fill: parent
            enabled: true
            hoverEnabled: true


            onEntered:{
                closeRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/HoverExitIcon.png"
            }
            onExited:{
                closeRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/ExitIcon.png"
            }
            onPressed:{
                closeRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/PressedExitIcon.png"
            }
            onClicked:{
                //初始化状态
                accountLineEdit.focus = false
                passwordLineEdit.focus = false
                initHorldTextInfo()
                inputNoDynamicIcon()
                loginDialog.close()


            }
        }


        Image{
            id: closeRectangleIcon
            anchors.fill: parent
            source:  "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/ExitIcon.png"
        }


    }
    //最小化按钮
    Rectangle{
        id: minimizedRectangle
        anchors.right: closeRectangle.left
        anchors.top: closeRectangle.top
        width: 30
        height: 30
        color: "transparent"


        MouseArea{
            id: minRectangleMouseArea
            anchors.fill: parent
            enabled: true
            hoverEnabled: true


            onEntered:{
                minRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/HoverMinimizedIcon.png"
            }
            onExited:{
                minRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/MinimizedIcon.png"
            }
            onPressed:{
                minRectangleIcon.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/PressedMinimizedIcon.png"
            }
            onClicked:{
                accountLineEdit.focus = false
                passwordLineEdit.focus = false
                initHorldTextInfo()
                inputNoDynamicIcon()
                loginDialog.showMinimized()
            }
        }


        Image{
            id: minRectangleIcon
            anchors.fill: parent
            source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/MinimizedIcon.png"
        }


    }


    //取消窗口
    Rectangle{
        id: baseCancelLoginRectangle
        anchors.fill: parent
        visible: false
        color: loginDialog.setRgb(127,183,223)


        AnimatedImage{
           id: loginDialogAnimatedImage1
           paused: true
           width: baseCancelLoginRectangle.width
           height: 100
           source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/LoginDialogBackground.gif"
          }


        Rectangle{
            id: cancelLoginRectangle
            anchors.centerIn: parent
            width: 110
            height: 100
            color: "transparent"


            MouseArea{
                id: cancelLoginRectangleMouseArea
                anchors.fill: parent
                enabled: true
                hoverEnabled: true


                onEntered:{
                    cancelLoginRectangle.scale = 1.1
                    cancelLoginRectangleText.color = "white"
                    cancelLoginRectangleImage.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/DynamicCancelLoginIcon.png"
                }
                onExited: {
                    cancelLoginRectangle.scale = 1.0
                    cancelLoginRectangleText.color = loginDialog.setRgb(141,141,141)
                    cancelLoginRectangleImage.source = "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/CancelLoginIcon.png"
                }
                onClicked: {
                    //暂停GIF播放同时另一个开启
                    loginDialogAnimatedImage1.paused = true
                    loginDialogAnimatedImage.paused = false
                    baseBackground.scale = 0.9
                    //启动旋转动画
                    rotateTimer.rotateFlag = false
                    rotateTimer.restart()
                }
            }


            Image{
                id: cancelLoginRectangleImage
                anchors.fill: parent
                source: "file:/C:/Users/FirstBoold-WANG/Desktop/FileCloudApplicationIcon/LoginIcon/LoginDialogIcon/CancelLoginIcon.png"
            }


            //旋转的动画
            RotationAnimator{
                id: rotationAnimator
                target: cancelLoginRectangle
                loops : Animation.Infinite
                easing.type: Easing.InOutElastic
                //direction: Counterclockwise
//                /direction: RotationAnimator.Shortest
                from: 0
                to: 360
                duration: 3000
            }
        }


        Text {
            id: cancelLoginRectangleText
            anchors.centerIn: cancelLoginRectangle
            text: "取消"
            font.bold: true
            font.family: "微软雅黑"
            font.pointSize: 9
            color: loginDialog.setRgb(141,141,141)
        }
    }


    //旋转是用定时器间隔来决定触发角的
    Timer{


        property bool  rotateFlag


        id: rotateTimer
        interval: 50
        repeat: true


        onTriggered: {
            if(rotateFlag){
                setLoginRectangleRotate()
            }else{
                setCancelLoginRectangleRotate()
            }
        }


        //登录界面下旋转
        function setLoginRectangleRotate(){
            if( ( baseBackground.rotateValue -= 15 ) === 90){
                     //显示取消界面
                     baseCancelLoginRectangle.visible = true
                     baseBackground.rotateTempValue = 0
                     rotationAnimator.start()
            }
            if(baseBackground.rotateValue <= 0){
                stop()
                baseBackground.rotateValue = 0
                baseBackground.scale = 1.0
            }


        }
        //取消界面下旋转
       function setCancelLoginRectangleRotate(){
           if( ( baseBackground.rotateValue += 15 ) === 90){
                    //隐藏取消界面
                    baseCancelLoginRectangle.visible = false
                    baseBackground.rotateTempValue = 180
                    rotationAnimator.stop()
            }
            if(baseBackground.rotateValue >= 180){
                stop()
                baseBackground.rotateValue = 180
                baseBackground.scale = 1.0
            }
       }
    }


    transform: Rotation{
         axis{
             x : 0
             y : 1
             z : 0
         }
         origin{
             x : baseBackground.width  / 2
             y : baseBackground.height / 2
         }
         angle: baseBackground.rotateValue +  baseBackground.rotateTempValue
    }


    layer.effect: DropShadow {
        id: baseDropShadow
        radius: 10
        color: "black"
        samples: parent.height / 10
    }
  }
}
### 设置或修改 QML 中 PopUp 组件的方向旋转 为了实现 `Popup` 组件的方向旋转,在 QML 中可以利用 `Rotation` 或者直接通过变换属性来调整 Popup 的显示角度。下面展示了一个具体的例子,说明如何应用旋转到 `Popup` 上: ```qml import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow { visible: true width: 640 height: 480 Button { text: "Open Rotated Popup" onClicked: popup.open() Popup { id: popup y: parent.height / 2 - contentItem.height / 2 // 使用 Transform 来添加旋转效果 transform: Rotation { origin.x: popup.width / 2 origin.y: popup.height / 2 axis { x: 0; y: 0; z: 1 } angle: 45 // 设定旋转的角度为45度 } Column { spacing: 20 Label { text: qsTr("This is a rotated popup!") font.pixelSize: 24 } Button { text: qsTr("Close") onClicked: popup.close() } } modal: true focus: true } } } ``` 上述代码片段展示了如何创建一个带有按钮的应用窗口,当点击该按钮时会打开一个已设置好特定旋转角度的弹窗[^1]。 #### 关键点解释 - **Transform 和 Rotation**: 这里的关键是使用了 `transform` 属性配合 `Rotation` 类型来进行旋转操作。`origin` 定义了旋转中心点的位置;而 `axis` 则指定了绕哪个轴线进行旋转,默认情况下是 Z 轴 (即屏幕平面内的顺/逆时针方向),这里保持默认即可。 - **Angle 参数**: 控制着实际的旋转程度,单位是以度数表示。可以根据需求调整此参数以获得不同的视觉效果。 - **Modal 和 Focus 属性**: 确保弹出框处于模态状态并获取输入焦点,从而防止用户交互其他界面元素直到关闭当前对话框为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值