对话框Dialog的设计在许多的QML应用是经常用到的。许多新的开发者刚开始接触QML,有时找不到头绪。也许是由于QML的设计太过灵活,所以实现的方法有非常多。这里介绍几种简单的方式。
1)使用Ubuntu SDK提供的标准API
我们可以使用Ubuntu SDK提供的标准
Dialog接口。使用的方法非常简单:
import QtQuick 2.4
import Ubuntu.Components 1.2
import Ubuntu.Components.Popups 1.0
Item {
width: units.gu(80)
height: units.gu(80)
Component {
id: dialog
Dialog {
id: dialogue
title: "Save file"
text: "Are you sure that you want to save this file?"
Button {
text: "cancel"
onClicked: PopupUtils.close(dialogue)
}
Button {
text: "overwrite previous version"
color: UbuntuColors.orange
onClicked: PopupUtils.close(dialogue)
}
Button {
text: "save a copy"
color: UbuntuColors.orange
onClicked: PopupUtils.close(dialogue)
}
}
}
Button {
anchors.centerIn: parent
id: saveButton
text: "save"
onClicked: PopupUtils.open(dialog)
}
}
就像文档中介绍的那样,我们需要import Ubuntu.Components.Popups 1.0模块来完成这个。这是目前最简单的方法,而且使用这样的方法,我们可以得到Ubuntu的look and feel。在调用时也可以传人我们的caller:
Component {
id: dialog
Dialog {
id: dialogue
title: "Save file"
text: "Are you sure that you want to save this file?"
Button {
text: "cancel"
onClicked: PopupUtils.close(dialogue)
}
Button {
text: "overwrite previous version"
color: UbuntuColors.orange
onClicked: PopupUtils.close(dialogue)
}
Button {
text: "save a copy"
color: UbuntuColors.orange
onClicked: {
console.log("caller: " + caller );
if ( caller !== null ) {
caller.callback("file is saved!");
}
PopupUtils.close(dialogue);
}
}
}
}
Column {
anchors.centerIn: parent
spacing: units.gu(2)
Button {
id: saveButton
text: "save"
onClicked: PopupUtils.open(dialog)
function callback(message) {
console.log("returned: " + message);
}
}
Button {
id: anotherSave
text: "Another Save"
onClicked: PopupUtils.open(dialog, anotherSave)
function callback(message) {
console.log("returned: " + message);
}
}
}
这样我们可以通过caller来“callback”回调我们的方法。
2)创建我们自己的Dialog Component并动态调用它
我们可以自己创建一个自己的Dialog.qml文件来存放为我们的Dialog所需要的内容:
import QtQuick 2.0
Item {
id: dialogComponent
anchors.fill: parent
// Add a simple animation to fade in the popup
// let the opacity go from 0 to 1 in 400ms
PropertyAnimation { target: dialogComponent; property: "opacity";
duration: 400; from: 0; to: 1;
easing.type: Easing.InOutQuad ; running: true }
// This rectange is the a overlay to partially show the parent through it
// and clicking outside of the 'dialog' popup will do 'nothing'
Rectangle {
anchors.fill: parent
id: overlay
color: "#000000"
opacity: 0.6
// add a mouse area so that clicks outside
// the dialog window will not do anything
MouseArea {
anchors.fill: parent
}
}
// This rectangle is the actual popup
Rectangle {
id: dialogWindow
width: 300
height: 300
radius: 10
anchors.centerIn: parent
Text {
anchors.centerIn: parent
text: "This is the popup"
}
// For demo I do not put any buttons, or other fancy stuff on the popup
// clicking the whole dialogWindow will dismiss it
MouseArea{
anchors.fill: parent
onClicked: {
// destroy object is needed when you dynamically create it
dialogComponent.destroy()
}
}
}
}
我们可以通过如下的方法来动态创建这个Dialog:
Button {
id: mydialog
text: "My customized dialog"
onClicked: {
Qt.createComponent("Dialog.qml").createObject(mainpage, {});
}
}
MouseArea{
anchors.fill: parent
onClicked: {
// destroy object is needed when you dynamically create it
dialogComponent.destroy()
}
}
这里的设计因人而异。我们可以设计自己的按钮来销毁创建的Dialog,并同时传回自己的选择。这个方法的好处是设计的UI不必绑定特定的操作系统,比如Ubuntu。这样这样的代码可以在多个平台上运行。
3)创建一个不可见的页面,在需要是显现
这个方法的实现也是非常简单,也在许多的QML应用中被使用。在创建页面时,我们可以同时创建不可见的部分。它们可以是重叠在一起的。只是在某个时间,只有一个页面可以被显示。通常不可见的页面在启动时被设置为“Dialog”。只有在需要的时候才可以被设置为可见。
为了说明问题,我们同样设置了一个自己的AnotherDialog.qml文件:
import QtQuick 2.0
Item {
id: dialogComponent
anchors.fill: parent
// Add a simple animation to fade in the popup
// let the opacity go from 0 to 1 in 400ms
PropertyAnimation { target: dialogComponent; property: "opacity";
duration: 400; from: 0; to: 1;
easing.type: Easing.InOutQuad ; running: true }
// This rectange is the a overlay to partially show the parent through it
// and clicking outside of the 'dialog' popup will do 'nothing'
Rectangle {
anchors.fill: parent
id: overlay
color: "#000000"
opacity: 0.6
// add a mouse area so that clicks outside
// the dialog window will not do anything
MouseArea {
anchors.fill: parent
}
}
// This rectangle is the actual popup
Rectangle {
id: dialogWindow
width: 300
height: 300
radius: 10
anchors.centerIn: parent
Text {
anchors.centerIn: parent
text: "This is the popup"
}
// For demo I do not put any buttons, or other fancy stuff on the popup
// clicking the whole dialogWindow will dismiss it
MouseArea{
anchors.fill: parent
onClicked: {
// destroy object is needed when you dynamically create it
console.log("it is clicked!");
dialogComponent.visible = false;
}
}
}
}
在我们的Main.qml中:
Button {
id: myanotherdialog
text: "My another dialog"
onClicked: {
dialog1.visible = true;
}
}
...
AnotherDialog {
id: dialog1
anchors.fill: parent
visible: false
}
运行我们的测试应用:
整个项目的源码在:
https://github.com/liu-xiao-guo/dialog