QML实现可定制模态对话框【核心部分详解】

来源:互联网 发布:windows api c 编辑:程序博客网 时间:2024/06/07 04:01


不少朋友需要会用到模态对话框,那么如何使用QML创建模态对话框呢?


分析:

我所需要的模态对话框是这样的:

上到下一次包含了:

a.标题栏

b.内容框

c.按钮栏

为了方便接口使用,我们将这三个部分整合在一个Window中。


这里是代码示例:

import QtQuick 2.0import QtQuick.Layouts 1.1import QtQuick.Window 2.0Window {    id: eo_askDialog    width: 300    height: 200        ColumnLayout{        anchors.fill: parent        spacing:2        //标题栏        Rectangle{            id: titleBar            Layout.fillWidth: parent            implicitHeight: 30            color: "darkgray"        }        //内容框        Rectangle{            id: contentView            Layout.fillWidth: parent            Layout.fillHeight: parent            color: "lightgray"        }        //按钮栏        Rectangle{            id: buttonBar            Layout.fillWidth: parent            implicitHeight: 30            color: "darkgray"        }    }}

功能确定:

1.返回确认信号

2.返回取消信号

3.返回checkBox被选中时候的确认信号

4.返回关闭信号

5.可定制标题栏背景

6.可定制内容框背景

7.可定制按钮栏背景

8.可定制文字信息


为了实现以下功能,我们需要往Window中添加一些属性:

    property string title: "ask dialog"          //对话框标题    property string content: "ask content."      //对话框内容    property string yesButtonString: "yes"       //yes按钮的文字    property string noButtonString: "no"         //no按钮的文字    property string checkBoxString: "check box"  //选择框的文字    property string titleBackgroundImage: ""     //标题栏背景图片    property string contentBackgroundImage: ""   //内容框的背景图片    property string buttonBarBackgroundImage: "" //按钮框的背景图片    property bool checked: false                 //选择框是否确认

因为我们需要实现自定义的标题栏,所以加上这个属性可以忽略系统自带的标题栏:

flags: Qt.FramelessWindowHint | Qt.Window | Qt.WindowStaysOnTopHint

当然,不能忘了这是个模态对话框,加上如下的属性:

modality: Qt.ApplicationModal

我们需要告知外界Window的情况,所以加上自定义的信号:

   /** 自定义信号        1.accept, yes按钮被点击        2.reject, no按钮被点击        3.checkAndAccept, 选择框和yes按钮被点击    **/    signal accept();    signal reject();    signal checkAndAccept();

现在我们得到了一个基本的模态框,只是现在还没有加上具体的标题、按钮和内容,以及把信号发送出去的相关逻辑代码。

这是Window现在的样子:


(你可以试着把它运行,但它就躺在那里不会理你)

现在我们需要一些交互代码:


1.实现标题栏


往Window的标题栏中加入一个RowLayout,其中包含2个MouseArea,

一个用于标题栏的文字显示和交互控制,另一个则作为关闭按钮使用。

RowLayout{    anchors.fill: parent    spacing: 2        MouseArea{        id: mouseControler                property point clickPos: "0,0"                Layout.fillHeight: parent        Layout.fillWidth: parent                //title        Text{            text: title            anchors.bottom: parent.bottom            anchors.bottomMargin: 5            anchors.left: parent.left            anchors.leftMargin: 10        }                onPressed: {            clickPos = Qt.point(mouse.x,mouse.y)        }                onPositionChanged: {            //鼠标偏移量motai            var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)            //如果mainwindow继承自QWidget,用setPos            eo_askDialog.setX(eo_askDialog.x+delta.x)            eo_askDialog.setY(eo_askDialog.y+delta.y)        }    }        //close button    MouseArea{        id: closeButton        Layout.fillHeight: parent        implicitWidth: 45                Rectangle{            anchors.fill: parent            color:"red"        }                onClicked: {            console.log("close button clicked.");                        eo_askDialog.visible = false;            reject()        }    }}


这下我们的窗口就能拖动和关闭了!现在该轮到内容框了,

直接添加一个Text到Window的内容框中:

Text{    text: content    anchors.centerIn: parent}

最后则是按钮栏,它和标题栏类似:

RowLayout{    anchors.fill: parent    spacing: 2    //checkBox    MouseArea{        id: checkBox        Layout.fillHeight: parent        width:100        Rectangle{            anchors.fill: parent            color:"lightgray"        }        Text{            text: checkBoxString            anchors.centerIn: parent        }        onClicked: {            checked = checked == false            console.log("checked changed.", checked)        }    }    //h spacer    Rectangle{        id: buttonBarSpacer        color: Qt.rgba(0,0,0,0)        Layout.fillWidth: parent    }    //yes button    MouseArea{        id: yesButton        Layout.fillHeight: parent        width:75        Rectangle{            anchors.fill: parent            color:"lightgray"        }        Text{            text: yesButtonString            anchors.centerIn: parent        }        onClicked: {            console.log("yes button clicked.")            eo_askDialog.visible = false;            if(checked){                checkAndAccept()            }            else{                accept()            }        }    }    //no button    MouseArea{        id: noButton        Layout.fillHeight: parent        width:75        Rectangle{            anchors.fill: parent            color:"lightgray"        }        Text{            text: noButtonString            anchors.centerIn: parent        }        onClicked: {            console.log("no button clicked.")            eo_askDialog.visible = false;            reject();        }    }}
其中h space 只是一个占位置的框而已,用于把checkbox 和 yes、no 按钮分隔开。


现在我们的框就是这样的:

具有完整的模态框的功能。

要完成背景图片的定制只需要往需要的MouseArea中加入一个Image

并引用Window的中定义的图片路径,并在Image

中添加一下不同的事件切换不同状态的图片的代码就好了

当然你也可以根据自己的需要自行定制



0 0
原创粉丝点击