QML Popup的绘制与Overlay的使用

Popup是一个模态窗口。当然,很多东西都是需要我们自己去自定义的!


目录

一、绘制一个Popup

二、Popup的两个特殊点

1.Popup与外部控件显示与隐藏独立,即不随父控的显隐而显隐

2.Popup的Z轴高于一切

三、Popup 常用用法

1.closePolicy 关闭属性

2.modal 模态窗口

3.Overlay.modal 修改模态窗口时的背景颜色

4.dim与Overlay.modeless 修改非模态窗口时的背景颜色

5.enter 打开动画

6.exit 退出动画

7.contentItem 绘制文本,窗口颜色等

8.添加按钮

9.当Popup窗口模态时,如何点击外部的按钮

四、根据自己的需求自定义Popup即可


一、绘制一个Popup

Popup {                                
    id: popup                          
    x: 100                             
    y: 100                             
    width: 200                         
    height: 300                        
                                       
    // 默认是不显示的,需要手动设置true才会显示          
    visible: true                    
                                       
    Component.onCompleted: {           
        console.log(visible)           
    }                                  
}                          

出现的只是一个矩形框;

除了通过自身属性 visible  设置显示与隐藏外,还可以通过外部调用open()close()函数,显示与隐藏;

新建一个按钮,在onClick中调用open()函数;然后将popup的visible设置为false;

Button {                                                          
    id: btn                                                       
    x: 10                                                         
    y: 10                                                         
    width: 50                                                     
    height: 30                                                    
                                                                  
    // 两种方式显示与关闭Popup                                             
    // 设置visib属性为true,或者调用open()函数也可让Popup显示;关闭则相反,close()函数和false
    onClicked: {                                                  
         popup.open()                                             
    }                                                             
}                                                          

二、Popup的两个特殊点

1.Popup与外部控件显示与隐藏独立,即不随父控的显隐而显隐

PopupPopup除外)

案例,定义一个Rectangle作为父,然后在Rectangle内部定义一个Popup作为子,将Rectangle的visible设置为false,将Popup的visible设置为true;

Rectangle {                               
    width: 200                            
    height: 100                           
    color: "black"                        
    visible: false  // 父亲的隐藏              
                                          
    Popup {                               
        width: 50                         
        height: 50                        
        background: Rectangle {           
            color: "red"                  
        }                                 
        visible: true   // 孩子的显示          
    }                                     
}                              

还是上面的案例,当把Rectangle换成Popup后:

Popup {                           
    width: 200                    
    height: 100                   
    background: Rectangle {       
        color: "black"            
    }                             
    visible: false  // 父亲的隐藏      
                                  
    Popup {                       
        width: 50                 
        height: 50                
        background: Rectangle {   
            color: "red"          
        }                         
        visible: true   // 孩子的显示  
    }                             
}                            

是没有任何Popup显示出来的;

2.Popup的Z轴高于一切

(Popup与Popup之间Z轴才会有效果)

案例,定义一个Rectangle和一个Popup,将Rectangle的Z轴设置为1000,将Popup的Z轴设置为1;

Rectangle {                 
    x: 300                  
    y: 200                  
    width: 200              
    height: 200             
    z: 1000                 
    color: "green";         
}                           
                            
Popup {                     
    x: 200                  
    y: 200                  
    width: 200              
    height: 200             
    z: 1                    
    visible: true           
    background: Rectangle { 
        color: "blue"       
    }                       
}                   

可以看出,Popup遮住了Rectangle,说明Popup是在Rectangle之上的;

再来看一看Popup与Popup的Z轴关系;

Popup {                            
    x: 200                         
    y: 200                         
    width: 200                     
    height: 200                    
    z: 1                           
    visible: true                  
    background: Rectangle {        
        color: "blue"              
    }                              
}                                  
                                   
Popup {                            
    x: 300                         
    y: 200                         
    width: 200                     
    height: 200                    
    z: 2                           
    visible: true                  
    background: Rectangle {        
        color: "red"               
    }                              
}                           

三、Popup 常用用法

新建一个Button用于关闭Popup;

Button {             
    width: 100       
    height: 50       
    onClicked: {     
        popup.close()
    }                
}               

1.closePolicy 关闭属性

枚举描述

Popup.NoAutoClose

设置为手动关闭Popup窗口

Popup.CloseOnPressOutside

鼠标按下除Popup以外的地方时关闭Popup窗口

Popup.CloseOnPressOutsideParent

鼠标在Poupu的父控件上按下时关闭Popup窗口

Popup.CloseOnReleaseOutside

鼠标在除Popup以外的地方释放时关闭Popup窗口

Popup.CloseOnReleaseOutsideParent

鼠标在Poupu的父控件上释放时关闭Popup窗口

Popup.CloseOnEscape

Popup上有焦点时,按下ESC键关闭Popup窗口

默认是: Popup.CloseOnEscape | Popup.CloseOnPressOutside.

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口
}

2.modal 模态窗口

true设置为模态窗口;

false设置为非模态窗口,默认值为false;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: true
}

背景颜色变成了灰色,而且按钮也无法点击了,实现了真正意义的模态;

3.Overlay.modal 修改模态窗口时的背景颜色

看着灰色的背景不好看,现在来修改一下模态窗口时的背景颜色;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: true
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "lightsteelblue"    // 高亮蓝色
    }
}

背景颜色被设置成了"lightsteelblue"色,但是背景的按钮也被遮住了;

这种情况下,可以使用ARGB模式设置颜色;

color: "#33aac3e4" // ARGB  33是透明度,16进行数;

4.dim与Overlay.modeless 修改非模态窗口时的背景颜色

dim就是设置非模态窗口下背景色的启动属性;

其中,dim属性必须实则为true;而且modal属性必须设置为false;否则无法正常实现!

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: false
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB

    // 3.设置非模态窗口情况下,Popup以外的颜色
    dim: true
    Overlay.modeless: Rectangle {
        anchors.fill: parent
        color: "#5500aa00"  // ARGB    A是透明度
    }
}

非模态窗口下,可以正常点击外部的按钮!

5.enter 打开动画

可以通过enter属性设置Popup窗口打开时的动画效果;

窗口打开时,将透明度有0.0提示到1.0;间隔2000ms;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: false
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB

    }

    // 3.设置非模态窗口情况下,Popup以外的颜色
    dim: true
    Overlay.modeless: Rectangle {
        anchors.fill: parent
        color: "#5500aa00"  // ARGB    A是透明度
    }


    // 4.打开动画
    enter: Transition {     // 打开的时候
        NumberAnimation {
            property: "opacity"
            from: 0.0
            to: 1.0
            duration: 2000
        }
    }
}

6.exit 退出动画

可以通过exit属性设置Popup窗口关闭时的动画效果;

退出时,将Popup窗口沿y轴移出;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: false
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB


    // 3.设置非模态窗口情况下,Popup以外的颜色
    dim: true
    Overlay.modeless: Rectangle {
        anchors.fill: parent
        color: "#5500aa00"  // ARGB    A是透明度
    }


    // 4.打开动画
    enter: Transition {     // 打开的时候
        NumberAnimation {
            property: "opacity"
            from: 0.0
            to: 1.0
            duration: 2000
        }
    }

    // 5.退出动画
    exit: Transition {
        NumberAnimation {
            property: "y"
            from: popup.y
            to: popup.height * 2
            duration: 1000
        }
    }
}

7.contentItem 绘制文本,窗口颜色等

在contentItem属性指定Rectangle,就可以在Rectangle内部设置文本颜色等;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: false
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB
    }

    // 3.设置非模态窗口情况下,Popup以外的颜色
    dim: true
    Overlay.modeless: Rectangle {
        anchors.fill: parent
        color: "#5500aa00"  // ARGB    A是透明度
    }


    // 4.打开动画
    enter: Transition {     // 打开的时候
        NumberAnimation {
            property: "opacity"
            from: 0.0
            to: 1.0
            duration: 2000
        }
    }

    // 5.退出动画
    exit: Transition {
        NumberAnimation {
            property: "y"
            from: popup.y
            to: popup.height * 2
            duration: 1000
        }
    }


    // 6.绘制
    contentItem: Rectangle {
        anchors.fill: parent    // 填充满父窗口
        Text {
            id: txt
            anchors.fill: parent
            text: qsTr("Message Box Area........")
            font.pixelSize: 30
            wrapMode: Text.WordWrap     // 文本换行
        }
        color: "LightGreen"
    }
}

8.添加按钮

在按钮的onClicked方法中将Popup窗口关闭;

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置为手动关闭Popup窗口

    // 2.模态对话框
    modal: false
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB
    }

    // 3.设置非模态窗口情况下,Popup以外的颜色
    dim: true
    Overlay.modeless: Rectangle {
        anchors.fill: parent
        color: "#5500aa00"  // ARGB    A是透明度
    }


    // 4.打开动画
    enter: Transition {     // 打开的时候
        NumberAnimation {
            property: "opacity"
            from: 0.0
            to: 1.0
            duration: 2000
        }
    }

    // 5.退出动画
    exit: Transition {
        NumberAnimation {
            property: "y"
            from: popup.y
            to: popup.height * 2
            duration: 1000
        }
    }


    // 6.绘制
    contentItem: Rectangle {
        anchors.fill: parent    // 填充满父窗口
        Text {
            id: txt
            anchors.fill: parent
            text: qsTr("Message Box Area........")
            font.pixelSize: 30
            wrapMode: Text.WordWrap     // 文本换行
        }
        color: "lightsteelblue"
    }


    Button {
        id: btnCancle
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        anchors.right: parent.right
        anchors.rightMargin: 30
        text: "取消"
        onClicked: {
            popup.close();
        }
    }

    Button {
        anchors.right: btnCancle.left
        anchors.rightMargin: 30
        anchors.bottom: btnCancle.bottom
        text: "确定"
        onClicked: {
            popup.close();
        }
    }
}

9.当Popup窗口模态时,如何点击外部的按钮

在 Overlay.modal 内部写上一个Popup,然后再设置的他的显示区域大小即可! 

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: true

    // 2.模态对话框
    modal: true
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#33aac3e4"  // ARGB

        Popup {
            width: parent.width     // 设置Popup宽的区域
            height: 80              // 设置Popup高的区域
            closePolicy: Popup.NoAutoClose
            visible: true
            background: Rectangle {
                color: "#00000000"  // 或者 "transparent"  透明色
            }

            Button {
                width: 100
                height: 50
                anchors.right: parent.right
                onClicked: {
                    console.log("clicked!")
                }
            }
        }
    }
}

四、根据自己的需求自定义Popup即可

Popup {
    id: popup
    x: 100
    y: 100
    width: 400
    height: 300
    visible: false
    property point dragPosition: Qt.point(0, 0)

    // 1.Poupu默认属性:The default value is Popup.CloseOnEscape | Popup.CloseOnPressOutside.
    // 按下esc键和鼠标点击任意位置,都会关闭Popup
    closePolicy: Popup.NoAutoClose      // 设置不手动关闭

    // 2.模态对话框
    modal: true
    // 模态窗口时,设置Popup以外的背景颜色
    Overlay.modal: Rectangle {
        anchors.fill: parent
        color: "#00000000"  // 或者 "transparent"  透明色
    }

    // 3.打开动画
    enter: Transition {     // 打开的时候
        NumberAnimation {
            property: "opacity"
            from: 0.0
            to: 1.0
            duration: 500
        }
    }

    // 4.退出动画
    exit: Transition {
        NumberAnimation {
            property: "opacity"
            from: 1.0
            to: 0
            duration: 500
        }
    }


    // 5.绘制
    contentItem: Rectangle {
        anchors.fill: parent    // 填充满父窗口
        Text {
            id: txt
            anchors.fill: parent
            anchors.centerIn: parent // 让文本在父容器中居中
            text: qsTr("Message Box Area........")
            font.pixelSize: 30
            wrapMode: Text.WordWrap     // 文本换行
            horizontalAlignment: Text.AlignHCenter // 水平居中
            verticalAlignment: Text.AlignVCenter   // 垂直居中
        }
        color: "lightsteelblue"
    }


    Button {
        id: btnCancle
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 20
        anchors.right: parent.right
        anchors.rightMargin: 30
        text: "取消"
        onClicked: {
            popup.close();
        }
    }

    Button {
        anchors.right: btnCancle.left
        anchors.rightMargin: 30
        anchors.bottom: btnCancle.bottom
        text: "确定"
        onClicked: {
            popup.close();
        }
    }

    Button {
        anchors.right: parent.right
        anchors.rightMargin: 10
        anchors.top: parent.top
        anchors.topMargin: 10
        width: 30
        height: 30
        text: "X"
        onClicked: {
            popup.close();
        }
    }


    // 拖动区域仅覆盖标题栏
    MouseArea {
       anchors.top: parent.top
       anchors.left: parent.left
       height: 40                   // 标题栏高度
       width: popup.width - 50      // 标题栏宽度
       onPressed: dragPosition = Qt.point(mouse.x, mouse.y)
       onPositionChanged: {
           if (pressed) {
               let deltaX = mouse.x - dragPosition.x
               let deltaY = mouse.y - dragPosition.y
               popup.x += deltaX
               popup.y += deltaY
           }
       }
    }
}

最后,Popup的常用属性基本都是这些了,后续可以根据自己的需求再去扩展即可。

完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值