1. 程式人生 > >QML實現可定製模態對話方塊【核心部分詳解】

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

中新增一下不同的事件切換不同狀態的圖片的程式碼就好了,

當然你也可以根據自己