转自
http://blog.csdn.net/r5014/article/details/70139689
不少朋友需要会用到模态对话框,那么如何使用QML创建模态对话框呢?
分析:
我所需要的模态对话框是这样的:
从上到下一次包含了:
a.标题栏
b.内容框
c.按钮栏
为了方便接口使用,我们将这三个部分整合在一个Window中。
这里是代码示例:
- import QtQuick 2.0
- import QtQuick.Layouts 1.1
- import QtQuick.Window 2.0
-
- Window {
- 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,
一个用于标题栏的文字显示和交互控制,另一个则作为关闭按钮使用。
- <span style="font-size:10px;">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()
- }
- }
- }</span>
这下我们的窗口就能拖动和关闭了!现在该轮到内容框了,
直接添加一个Text到Window的内容框中:
- <span style="font-size:10px;">Text{
- text: content
- anchors.centerIn: parent
- }</span>
最后则是按钮栏,它和标题栏类似:
- <span style="font-size:10px;">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();
- }
- }
-
-
- }</span>
其中h space 只是一个占位置的框而已,用于把checkbox 和 yes、no 按钮分隔开。
现在我们的框就是这样的:
具有完整的模态框的功能。
要完成背景图片的定制只需要往需要的MouseArea中加入一个Image
并引用Window的中定义的图片路径,并在Image
中添加一下不同的事件切换不同状态的图片的代码就好了,
当然你也可以根据自己的需要自行定制