QML實現可定製模態對話方塊【核心部分詳解】
轉自
http://blog.csdn.net/r5014/article/details/70139689
不少朋友需要會用到模態對話方塊,那麼如何使用QML建立模態對話方塊呢?
分析:
我所需要的模態對話方塊是這樣的:
從上到下一次包含了:
a.標題欄
b.內容框
c.按鈕欄
為了方便介面使用,我們將這三個部分整合在一個Window中。
這裡是程式碼示例:
[plain] view plain copy
- 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中新增一些屬性:
[plain] view plain copy
- 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 //選擇框是否確認
因為我們需要實現自定義的標題欄,所以加上這個屬性可以忽略系統自帶的標題欄:
[plain] view plain copy
- flags: Qt.FramelessWindowHint | Qt.Window | Qt.WindowStaysOnTopHint
當然,不能忘了這是個模態對話方塊,加上如下的屬性:
[plain] view plain copy
- modality: Qt.ApplicationModal
我們需要告知外界Window的情況,所以加上自定義的訊號:
[plain] view plain copy
- /** 自定義訊號
- 1.accept, yes按鈕被點選
- 2.reject, no按鈕被點選
- 3.checkAndAccept, 選擇框和yes按鈕被點選
- **/
- signal accept();
- signal reject();
- signal checkAndAccept();
現在我們得到了一個基本的模態框,只是現在還沒有加上具體的標題、按鈕和內容,以及把訊號傳送出去的相關邏輯程式碼。
這是Window現在的樣子:
(你可以試著把它執行,但它就躺在那裡不會理你)
現在我們需要一些互動程式碼:
1.實現標題欄
往Window的標題欄中加入一個RowLayout,其中包含2個MouseArea,
一個用於標題欄的文字顯示和互動控制,另一個則作為關閉按鈕使用。
[plain] view plain copy
- <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的內容框中:
[plain] view plain copy
- <span style="font-size:10px;">Text{
- text: content
- anchors.centerIn: parent
- }</span>
最後則是按鈕欄,它和標題欄類似:
[plain] view plain copy
- <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
中新增一下不同的事件切換不同狀態的圖片的程式碼就好了,
當然你也可以根據自己