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

转自

http://blog.csdn.net/r5014/article/details/70139689


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


分析:

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

上到下一次包含了:

a.标题栏

b.内容框

c.按钮栏

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


这里是代码示例:

[plain]  view plain  copy
  1. import QtQuick 2.0  
  2. import QtQuick.Layouts 1.1  
  3. import QtQuick.Window 2.0  
  4.   
  5. Window {  
  6.     id: eo_askDialog  
  7.   
  8.     width: 300  
  9.     height: 200  
  10.       
  11.     ColumnLayout{  
  12.         anchors.fill: parent  
  13.   
  14.         spacing:2  
  15.   
  16.         //标题栏  
  17.         Rectangle{  
  18.             id: titleBar  
  19.             Layout.fillWidth: parent  
  20.             implicitHeight: 30  
  21.             color: "darkgray"  
  22.         }  
  23.   
  24.         //内容框  
  25.         Rectangle{  
  26.             id: contentView  
  27.             Layout.fillWidth: parent  
  28.             Layout.fillHeight: parent  
  29.             color: "lightgray"  
  30.         }  
  31.   
  32.         //按钮栏  
  33.         Rectangle{  
  34.             id: buttonBar  
  35.             Layout.fillWidth: parent  
  36.             implicitHeight: 30  
  37.             color: "darkgray"  
  38.         }  
  39.     }  
  40. }  

功能确定:

1.返回确认信号

2.返回取消信号

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

4.返回关闭信号

5.可定制标题栏背景

6.可定制内容框背景

7.可定制按钮栏背景

8.可定制文字信息


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

[plain]  view plain  copy
  1. property string title: "ask dialog"          //对话框标题  
  2. property string content: "ask content."      //对话框内容  
  3. property string yesButtonString: "yes"       //yes按钮的文字  
  4. property string noButtonString: "no"         //no按钮的文字  
  5. property string checkBoxString: "check box"  //选择框的文字  
  6. property string titleBackgroundImage: ""     //标题栏背景图片  
  7. property string contentBackgroundImage: ""   //内容框的背景图片  
  8. property string buttonBarBackgroundImage: "" //按钮框的背景图片  
  9. property bool checked: false                 //选择框是否确认  

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

[plain]  view plain  copy
  1. flags: Qt.FramelessWindowHint | Qt.Window | Qt.WindowStaysOnTopHint  

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

[plain]  view plain  copy
  1. modality: Qt.ApplicationModal  

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

[plain]  view plain  copy
  1. /** 自定义信号  
  2.      1.accept, yes按钮被点击  
  3.      2.reject, no按钮被点击  
  4.      3.checkAndAccept, 选择框和yes按钮被点击  
  5.  **/  
  6.  signal accept();  
  7.  signal reject();  
  8.  signal checkAndAccept();  

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

这是Window现在的样子:


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

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


1.实现标题栏


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

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

[plain]  view plain  copy
  1. <span style="font-size:10px;">RowLayout{  
  2.     anchors.fill: parent  
  3.     spacing: 2  
  4.       
  5.     MouseArea{  
  6.         id: mouseControler  
  7.           
  8.         property point clickPos: "0,0"  
  9.           
  10.         Layout.fillHeight: parent  
  11.         Layout.fillWidth: parent  
  12.           
  13.         //title  
  14.         Text{  
  15.             text: title  
  16.             anchors.bottom: parent.bottom  
  17.             anchors.bottomMargin: 5  
  18.             anchors.left: parent.left  
  19.             anchors.leftMargin: 10  
  20.         }  
  21.           
  22.         onPressed: {  
  23.             clickPos = Qt.point(mouse.x,mouse.y)  
  24.         }  
  25.           
  26.         onPositionChanged: {  
  27.             //鼠标偏移量motai  
  28.             var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)  
  29.             //如果mainwindow继承自QWidget,用setPos  
  30.             eo_askDialog.setX(eo_askDialog.x+delta.x)  
  31.             eo_askDialog.setY(eo_askDialog.y+delta.y)  
  32.         }  
  33.     }  
  34.       
  35.     //close button  
  36.     MouseArea{  
  37.         id: closeButton  
  38.         Layout.fillHeight: parent  
  39.         implicitWidth: 45  
  40.           
  41.         Rectangle{  
  42.             anchors.fill: parent  
  43.             color:"red"  
  44.         }  
  45.           
  46.         onClicked: {  
  47.             console.log("close button clicked.");  
  48.               
  49.             eo_askDialog.visible = false;  
  50.             reject()  
  51.         }  
  52.     }  
  53. }</span>  


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

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

[plain]  view plain  copy
  1. <span style="font-size:10px;">Text{  
  2.     text: content  
  3.     anchors.centerIn: parent  
  4. }</span>  

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

[plain]  view plain  copy
  1. <span style="font-size:10px;">RowLayout{  
  2.     anchors.fill: parent  
  3.     spacing: 2  
  4.   
  5.     //checkBox  
  6.     MouseArea{  
  7.         id: checkBox  
  8.         Layout.fillHeight: parent  
  9.         width:100  
  10.   
  11.         Rectangle{  
  12.             anchors.fill: parent  
  13.             color:"lightgray"  
  14.         }  
  15.   
  16.         Text{  
  17.             text: checkBoxString  
  18.             anchors.centerIn: parent  
  19.         }  
  20.   
  21.         onClicked: {  
  22.             checked = checked == false  
  23.             console.log("checked changed.", checked)  
  24.         }  
  25.     }  
  26.   
  27.     //h spacer  
  28.     Rectangle{  
  29.         id: buttonBarSpacer  
  30.         color: Qt.rgba(0,0,0,0)  
  31.         Layout.fillWidth: parent  
  32.     }  
  33.   
  34.     //yes button  
  35.     MouseArea{  
  36.         id: yesButton  
  37.         Layout.fillHeight: parent  
  38.         width:75  
  39.   
  40.         Rectangle{  
  41.             anchors.fill: parent  
  42.             color:"lightgray"  
  43.         }  
  44.   
  45.         Text{  
  46.             text: yesButtonString  
  47.             anchors.centerIn: parent  
  48.         }  
  49.   
  50.         onClicked: {  
  51.             console.log("yes button clicked.")  
  52.             eo_askDialog.visible = false;  
  53.   
  54.             if(checked){  
  55.                 checkAndAccept()  
  56.             }  
  57.             else{  
  58.                 accept()  
  59.             }  
  60.         }  
  61.     }  
  62.   
  63.     //no button  
  64.     MouseArea{  
  65.         id: noButton  
  66.         Layout.fillHeight: parent  
  67.         width:75  
  68.   
  69.         Rectangle{  
  70.             anchors.fill: parent  
  71.             color:"lightgray"  
  72.         }  
  73.   
  74.         Text{  
  75.             text: noButtonString  
  76.             anchors.centerIn: parent  
  77.         }  
  78.   
  79.         onClicked: {  
  80.             console.log("no button clicked.")  
  81.             eo_askDialog.visible = false;  
  82.   
  83.             reject();  
  84.         }  
  85.     }  
  86.   
  87.   
  88. }</span>  
其中h space 只是一个占位置的框而已,用于把checkbox 和 yes、no 按钮分隔开。


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

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

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

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

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

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


猜你喜欢

转载自blog.csdn.net/skykingf/article/details/73821849