12. 對(duì)話(huà)框
一、對(duì)話(huà)框
??對(duì)話(huà)框窗口是一個(gè)用來(lái)完成簡(jiǎn)單任務(wù)或者和用戶(hù)進(jìn)行臨時(shí)交互的頂層窗口,通常用于輸入信息、確認(rèn)信息或者提示信息。Qt Quick 提供了一系列的標(biāo)準(zhǔn)對(duì)話(huà)框,如 FileDialog、ColorDialog、MessageDialog、FontDialog 等,它們繼承與 Qt.Dialogs.Dialog。Qt Quick 會(huì)首先使用平臺(tái)相關(guān)的標(biāo)準(zhǔn)對(duì)話(huà)框,如果不可用,就使用自己實(shí)現(xiàn)的版本。
??Qt.Dialogs.Dialog 的 visible 屬性默認(rèn)是 false,即對(duì)話(huà)框是不可見(jiàn)的。如果我們要顯示對(duì)話(huà)框,則需要調(diào)用 open() 方法或者手動(dòng)將 visable 屬性設(shè)置為 true。我們可以通過(guò) title 屬性 設(shè)置對(duì)話(huà)框的標(biāo)題。如果我們要關(guān)閉對(duì)話(huà)框,可以使用 close() 方法。
??我們可以通過(guò) modality 屬性 設(shè)置對(duì)話(huà)框的模態(tài)性,它是一個(gè)枚舉值,可以取值如下:
// 該對(duì)話(huà)框并非模態(tài)框,也不會(huì)阻止對(duì)其他窗口的輸入操作
Qt.NonModal
// 默認(rèn)值,該對(duì)話(huà)框僅適用于單一窗口層次結(jié)構(gòu),并會(huì)阻止其父窗口、所有祖級(jí)窗口以及其父窗口和祖級(jí)窗口的所有兄弟窗口的輸入操作
Qt.WindowModal
// 該對(duì)話(huà)框與應(yīng)用程序相關(guān)聯(lián),并會(huì)阻止所有窗口的輸入操作
Qt.ApplicationModal
??當(dāng)用戶(hù) 點(diǎn)擊確認(rèn)按鈕 后,會(huì)觸發(fā) accepted() 信號(hào)。當(dāng)用戶(hù) 點(diǎn)擊取消按鈕 時(shí),會(huì)觸發(fā) rejected() 信號(hào)。
Qt.Dialogs.Dialog為類(lèi)型,無(wú)法使用它創(chuàng)建控件,會(huì)報(bào)Dialog is not a type錯(cuò)誤。
??我們可以在終端中使用 pip 安裝 PySide6 模塊。默認(rèn)是從國(guó)外的主站上下載,因此,我們可能會(huì)遇到網(wǎng)絡(luò)不好的情況導(dǎo)致下載失敗。我們可以在 pip 指令后通過(guò) -i 指定國(guó)內(nèi)鏡像源下載。
pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple
??國(guó)內(nèi)常用的 pip 下載源列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple
- 清華大學(xué) https://pypi.tuna.tsinghua.edu.cn/simple
- 中國(guó)科學(xué)技術(shù)大學(xué) http://pypi.mirrors.ustc.edu.cn/simple
二、文件對(duì)話(huà)框
??FileDialog 是 Qt Quick 中的文件對(duì)話(huà)框,它繼承于 Qt.Dialogs.Dialog,它可以用來(lái)選擇已有的文件、文件夾,支持單選、多選,也可以用來(lái)在保存文件或創(chuàng)建文件夾時(shí)讓用戶(hù)提供一個(gè)名字。
??我們可以通過(guò) currentFolder 屬性 設(shè)置打開(kāi)文件對(duì)話(huà)框的初始目錄。我們還可以通過(guò) fileMode 屬性 設(shè)置文件對(duì)話(huà)框的模式,它是一個(gè)枚舉值,可以取值如下:
FileDialog.OpenFile // 該對(duì)話(huà)框用于選擇一個(gè)現(xiàn)有的文件(默認(rèn)選擇的是當(dāng)前文件)
FileDialog.OpenFiles // 該對(duì)話(huà)框用于選擇多個(gè)已存在的文件
FileDialog.SaveFile // 該對(duì)話(huà)框用于選擇任意文件,該文件無(wú)需存在
??我們可以通過(guò) nameFilters 屬性 設(shè)置文件過(guò)濾器。nameFilters 是一個(gè) 字符串類(lèi)型的列表,其中的每個(gè)字符串代表一種過(guò)濾器,它的語(yǔ)法格式如下:
nameFilters: ["過(guò)濾器名 (*.文件類(lèi)型1 *.文件類(lèi)型2 ...)"]
??在我們?cè)O(shè)置過(guò)濾器之后,我們可以使用 selectedNameFilter 屬性 設(shè)置默認(rèn)的過(guò)濾器。它是一個(gè)屬性組,我們可以通過(guò)如下屬性設(shè)置:
selectedNameFilter.index // 通過(guò)索引選擇過(guò)濾器
selectedNameFilter.name // 通過(guò)過(guò)濾器名選擇過(guò)濾器
selectedNameFilter.extensions // 通過(guò)文件擴(kuò)展名選擇過(guò)濾器
selectedNameFilter.globs // 通過(guò)通配符選擇過(guò)濾器
??在我們選擇單個(gè)文件后,選擇的文件會(huì)保存在 selectedFile 屬性中,如果我們選擇了多個(gè)文件該屬性指代第一個(gè)文件,此時(shí)我們可以使用 selectedFiles 屬性,該屬性是選擇的文件的列表。
??我們新建一個(gè) template.py 文件。
import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtQml import QQmlApplicationEngine
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.創(chuàng)建一個(gè)QApplication類(lèi)的實(shí)例
engine = QQmlApplicationEngine() # 2.創(chuàng)建QML引擎對(duì)象
engine.load("template.qml") # 3.加載QML文件
sys.exit(app.exec()) # 4.進(jìn)入程序的主循環(huán)并通過(guò)exit()函數(shù)確保主循環(huán)安全結(jié)束
??我們新建一個(gè) template.qml 文件。
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Text {
id: textId
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
font.family: "楷體"
font.pointSize: 14
color: "#FF6666"
}
Button {
id: buttonId
anchors.centerIn: parent
text: "文件對(duì)話(huà)框"
font.pointSize: 24
onClicked: {
fileDialogId.open() // 打開(kāi)文件對(duì)話(huà)框
}
}
// 文件對(duì)話(huà)框
FileDialog {
id: fileDialogId
title: "選擇文件" // 文件對(duì)話(huà)框的標(biāo)題
nameFilters: ["文本文件 (*.txt)", "圖像文件 (*.jpg *.png)", "所有文件 (*)"] // 文件對(duì)話(huà)框的文件類(lèi)型過(guò)濾器
fileMode: FileDialog.OpenFiles // 設(shè)置文件對(duì)話(huà)框的模式
onAccepted: {
// FileDialog的selectedFile保存了用戶(hù)選擇的文件路徑,如果是多個(gè)文件,則顯示第一個(gè)
textId.text = selectedFile
}
}
}
三、文件夾對(duì)話(huà)框
??FolderDialog 對(duì)話(huà)框用來(lái) 選擇一個(gè)文件夾,它繼承于 Qt.Dialogs.Dialog。我們可以通過(guò) currentFolder 屬性 設(shè)置打開(kāi)文件夾對(duì)話(huà)框的初始目錄,selectedFolder 屬性 獲取選中的文件夾路徑。
??修改 template.qml 文件的內(nèi)容。
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Text {
id: textId
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
font.family: "楷體"
font.pointSize: 14
color: "#FF6666"
}
Button {
id: buttonId
anchors.centerIn: parent
text: "文件夾對(duì)話(huà)框"
font.pointSize: 24
onClicked: {
folderDialogId.open() // 打開(kāi)文件對(duì)話(huà)框
// 如果用戶(hù)選擇了文件夾,則將其設(shè)置為當(dāng)前文件夾
if (folderDialogId.selectedFolder) {
folderDialogId.currentFolder = folderDialogId.selectedFolder
}
}
}
// 文件夾對(duì)話(huà)框
FolderDialog {
id: folderDialogId
title: "選擇文件夾" // 文件對(duì)話(huà)框的標(biāo)題
onAccepted: {
// FolderDialog的selectedFolder保存了用戶(hù)選擇的文件路徑,如果是多個(gè)文件,則顯示第一個(gè)
textId.text = selectedFolder
}
}
}
四、顏色對(duì)話(huà)框
??ColorDialog 對(duì)話(huà)框用來(lái) 選擇一個(gè)顏色,它繼承于 Qt.Dialogs.Dialog。我們可以通過(guò) selectedColor 屬性 獲取選擇的顏色,通過(guò) options 屬性 設(shè)置顏色對(duì)話(huà)框的樣式,它可以是以下值的集合:
ColorDialog.ShowAlphaChannel // 展示一個(gè)滑塊以及用于輸入alpha值的其他輸入字段。
ColorDialog.NoButtons // 不要顯示“打開(kāi)”和“取消”按鈕(適用于“實(shí)時(shí)對(duì)話(huà)框”)
ColorDialog.NoEyeDropperButton // 不要顯示“吸管”按鈕。此選項(xiàng)是在Qt6.6版本中添加的
ColorDialog.DontUseNativeDialog // 強(qiáng)制該對(duì)話(huà)使用非原生的快速實(shí)現(xiàn)方式
默認(rèn)狀態(tài)下,
options屬性未設(shè)置任何選項(xiàng)。
??修改 template.qml 文件的內(nèi)容。
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Text {
id: textId
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
font.family: "楷體"
font.pointSize: 32
color: "#EE5599"
text: "多情自古傷離別,此恨綿綿無(wú)絕期。"
}
Button {
id: buttonId
anchors.centerIn: parent
text: "顏色對(duì)話(huà)框"
font.pointSize: 24
onClicked: {
colorDialogId.open() // 打開(kāi)顏色對(duì)話(huà)框
}
}
// 顏色對(duì)話(huà)框
ColorDialog {
id: colorDialogId
title: "選擇顏色" // 顏色對(duì)話(huà)框的標(biāo)題
selectedColor: textId.color // 初始化顏色對(duì)話(huà)框的顏色為文本框的顏色
options: ColorDialog.ShowAlphaChannel // 顯示顏色對(duì)話(huà)框的Alpha通道
onAccepted: {
// ColorDialog的selectedColor保存了用戶(hù)選擇的顏色
textId.color = selectedColor
}
}
}
options屬性應(yīng)在顯示對(duì)話(huà)框之前設(shè)置選項(xiàng)。在對(duì)話(huà)框可見(jiàn)的情況下設(shè)置選項(xiàng),并不能保證能立即對(duì)對(duì)話(huà)框產(chǎn)生影響。
五、字體對(duì)話(huà)框
??FontDialog 對(duì)話(huà)框用來(lái) 選擇一個(gè)字體,它繼承于 Qt.Dialogs.Dialog。我們可以通過(guò) selectedFont 屬性 獲取選擇的字體,通過(guò) options 屬性 設(shè)置字體對(duì)話(huà)框的樣式,.它是一個(gè)枚舉值,它可以是以下值的集合:
// 默認(rèn)情況下,未設(shè)置任何選項(xiàng),這意味著所有字體類(lèi)型都會(huì)顯示出來(lái),并且對(duì)話(huà)框中會(huì)顯示標(biāo)準(zhǔn)的“選擇”和“取消”按鈕。
FontDialog.ScalableFonts // 顯示可縮放字體
FontDialog.NonScalableFonts // 顯示不可縮放字體
FontDialog.MonospacedFonts // 顯示等寬字體
FontDialog.ProportionalFonts // 顯示比例字體
FontDialog.NoButtons // 不要顯示“打開(kāi)”和“取消”按鈕(適用于“實(shí)時(shí)對(duì)話(huà)框)
FontDialog.DontUseNativeDialog // 強(qiáng)制該對(duì)話(huà)使用非原生的快速實(shí)現(xiàn)方式
默認(rèn)情況下,
option屬性未設(shè)置任何選項(xiàng),這意味著所有字體類(lèi)型都會(huì)顯示出來(lái),并且對(duì)話(huà)框中會(huì)顯示標(biāo)準(zhǔn)的“選擇”和“取消”按鈕。
??修改 template.qml 文件的內(nèi)容。
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Text {
id: textId
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
font.family: "楷體"
font.pointSize: 32
color: "#FF66CC"
text: "科學(xué)技術(shù)的價(jià)值,在于使用者的意圖。"
}
Button {
id: buttonId
anchors.centerIn: parent
text: "字體對(duì)話(huà)框"
font.pointSize: 24
onClicked: {
fontDialogId.open() // 打開(kāi)字體對(duì)話(huà)框
}
}
// 字體對(duì)話(huà)框
FontDialog {
id: fontDialogId
title: "選擇字體" // 字體對(duì)話(huà)框的標(biāo)題
selectedFont: textId.font // 初始化字體對(duì)話(huà)框的字體為文本框的字體
onAccepted: {
// FontDialog的selectedFont保存了用戶(hù)選擇的字體
textId.font = selectedFont
}
}
}
??當(dāng)我們運(yùn)行程序點(diǎn)擊按鈕彈出字體對(duì)話(huà)框時(shí),終端會(huì)輸入如下內(nèi)容,雖然不影響使用,但也不美觀。
qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FontDialogContent.qml:223:16: QML Label: The current style does not support customization of this control (property: "label" item: Label_QMLTYPE_24(0x1c0ab7fdb90, parent=0x0, geometry=0,0 0x0 ?)). Please customize a non-native style (such as Basic, Fusion, Material, etc). For more information, see: https://doc.qt.io/qt-6/qtquickcontrols2-customize.html#customization-reference
??這個(gè)問(wèn)題大致是說(shuō)當(dāng)前樣式不支持對(duì)此控件的自定義設(shè)置,請(qǐng)自定義非原生樣式(例如基本樣式 Basic、融合樣式 Fusion、材料樣式 Material 等)。此時(shí)我們需要在加載 QML 文件之前,使用 QQuickStyle.setStyle() 方法設(shè)置樣式。如果在加載 QML 之后設(shè)置,會(huì)報(bào)如下錯(cuò)誤:
ERROR: QQuickStyle::setStyle() must be called before loading QML that imports Qt Quick Controls 2.
??修改 template.py 文件的內(nèi)容。
import sys
from PySide6.QtWidgets import QApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.創(chuàng)建一個(gè)QApplication類(lèi)的實(shí)例
engine = QQmlApplicationEngine() # 2.創(chuàng)建QML引擎對(duì)象
QQuickStyle.setStyle("Material") # 3.設(shè)置QML引擎的樣式
engine.load("template.qml") # 4.加載QML文件
sys.exit(app.exec()) # 5.進(jìn)入程序的主循環(huán)并通過(guò)exit()函數(shù)確保主循環(huán)安全結(jié)束
在顯示對(duì)話(huà)框之前應(yīng)先設(shè)置選項(xiàng)。在對(duì)話(huà)框可見(jiàn)的情況下設(shè)置選項(xiàng),并不能保證能立即對(duì)對(duì)話(huà)框產(chǎn)生影響(這取決于選項(xiàng)以及所使用的平臺(tái))。
六、消息對(duì)話(huà)框
??MessageDialog 用來(lái)顯示一個(gè)彈出消息框。我們可以使用 text 屬性 設(shè)置要在消息對(duì)話(huà)框中顯示的文本內(nèi)容,使用 detailedText 屬性 設(shè)置要在詳細(xì)信息區(qū)域顯示的文本內(nèi)容, informativeText 屬性 包含了一段具有解釋性的文字,該文字對(duì)消息進(jìn)行了更詳細(xì)的描述。
??我們可以使用 buttons 屬性 設(shè)置使用的按鈕集合,它可以是以下值的集合:
MessageDialog.NoButton // 默認(rèn)值,該對(duì)話(huà)框中沒(méi)有按鈕
MessageDialog.Ok // 一個(gè)通過(guò)AcceptRole定義的“確定”按鈕
MessageDialog.Open // 一個(gè)通過(guò)AcceptRole定義的“打開(kāi)”按鈕
MessageDialog.Save // 一個(gè)通過(guò)AcceptRole定義的“保存”按鈕
MessageDialog.SaveAll // 一個(gè)通過(guò)AcceptRole定義的“保存所有”按鈕
MessageDialog.Retry // 一個(gè)通過(guò)AcceptRole定義的“重試”按鈕
MessageDialog.Ignore // 一個(gè)通過(guò)AcceptRole.定義的“忽略”按鈕
MessageDialog.Cancel // 一個(gè)通過(guò)RejectRole定義的“取消”按鈕
MessageDialog.Close // 一個(gè)通過(guò)RejectRole定義的“關(guān)閉”按鈕
MessageDialog.Abort // 一個(gè)通過(guò)RejectRole定義的“中止”按鈕
MessageDialog.Discard // 根據(jù)不同的平臺(tái),會(huì)有一個(gè)“丟棄”或“不保存”按鈕,其功能由DestructiveRole來(lái)定義
MessageDialog.Apply // 一個(gè)通過(guò)ApplyRole定義的“應(yīng)用”按鈕
MessageDialog.Reset // 一個(gè)通過(guò)ResetRole定義的“重置”按鈕
MessageDialog.RestoreDefaults // 一個(gè)通過(guò)ResetRole定義的“恢復(fù)默認(rèn)值”按鈕
MessageDialog.Help // 一個(gè)通過(guò)HelpRole定義的“幫助”按鈕
MessageDialog.Yes // 一個(gè)通過(guò)YesRole定義的“是”按鈕
MessageDialog.YesToAll // 一個(gè)通過(guò)YesRole定義的“全部同意”按鈕
MessageDialog.No // 一個(gè)通過(guò)NoRole定義的“否”按鈕
MessageDialog.NoToAll // 一個(gè)通過(guò)NoRole定義的“全部拒絕”按鈕
??修改 template.qml 文件的內(nèi)容。
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Dialogs
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Text {
id: textId
anchors.top: parent.top
anchors.topMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
font.family: "楷體"
font.pointSize: 32
color: "#FF66CC"
}
Button {
id: buttonId
anchors.centerIn: parent
text: "消息對(duì)話(huà)框"
font.pointSize: 24
onClicked: {
messageDialogId.open() // 打開(kāi)消息對(duì)話(huà)框
}
}
// 消息對(duì)話(huà)框
MessageDialog {
id: messageDialogId
// 消息對(duì)話(huà)框的按鈕
buttons: MessageDialog.Ok | MessageDialog.Cancel
title: "消息對(duì)話(huà)框" // 消息對(duì)話(huà)框的標(biāo)題
text: "確定要執(zhí)行此操作嗎?" // 消息對(duì)話(huà)框的文本內(nèi)容
onAccepted: {
textId.text = "用戶(hù)點(diǎn)擊了確定按鈕"
}
onRejected: {
// 用戶(hù)點(diǎn)擊了取消按鈕
textId.text = "用戶(hù)點(diǎn)擊了取消按鈕"
}
}
}
七、自定義對(duì)話(huà)框
??要顯示一個(gè)原生對(duì)話(huà)框,我們需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn) QtQuick.Controls.Dialog 類(lèi)的實(shí)例,然后再設(shè)置所需要的屬性。在 QtQuick.Dialogs 模塊中同樣有一個(gè) Dialog 控件,但是我們不能直接使用,會(huì)報(bào) Dialog is not a type 錯(cuò)誤。
??QtQuick.Controls.Dialog 的 visible 屬性默認(rèn)是 false,即對(duì)話(huà)框是不可見(jiàn)的。如果我們要顯示對(duì)話(huà)框,則需要調(diào)用 open() 方法或者手動(dòng)將 visable 屬性設(shè)置為 true。我們可以通過(guò) title 屬性 設(shè)置對(duì)話(huà)框的標(biāo)題, head 屬性 設(shè)置頁(yè)眉,footer 屬性 設(shè)置頁(yè)腳。如果我們要關(guān)閉對(duì)話(huà)框,可以使用 close() 方法。
??我們可以使用 standardButtons 屬性 設(shè)置使用的按鈕集合,它可以取值如下:
Dialog.NoButton // 默認(rèn)值,該對(duì)話(huà)框中沒(méi)有按鈕
Dialog.Ok // 一個(gè)通過(guò)AcceptRole定義的“確定”按鈕
Dialog.Open // 一個(gè)通過(guò)AcceptRole定義的“打開(kāi)”按鈕
Dialog.Save // 一個(gè)通過(guò)AcceptRole定義的“保存”按鈕
Dialog.SaveAll // 一個(gè)通過(guò)AcceptRole定義的“保存所有”按鈕
Dialog.Retry // 一個(gè)通過(guò)AcceptRole定義的“重試”按鈕
Dialog.Ignore // 一個(gè)通過(guò)AcceptRole.定義的“忽略”按鈕
Dialog.Cancel // 一個(gè)通過(guò)RejectRole定義的“取消”按鈕
Dialog.Close // 一個(gè)通過(guò)RejectRole定義的“關(guān)閉”按鈕
Dialog.Abort // 一個(gè)通過(guò)RejectRole定義的“中止”按鈕
Dialog.Discard // 根據(jù)不同的平臺(tái),會(huì)有一個(gè)“丟棄”或“不保存”按鈕,其功能由DestructiveRole來(lái)定義
Dialog.Apply // 一個(gè)通過(guò)ApplyRole定義的“應(yīng)用”按鈕
Dialog.Reset // 一個(gè)通過(guò)ResetRole定義的“重置”按鈕
Dialog.RestoreDefaults // 一個(gè)通過(guò)ResetRole定義的“恢復(fù)默認(rèn)值”按鈕
Dialog.Help // 一個(gè)通過(guò)HelpRole定義的“幫助”按鈕
Dialog.Yes // 一個(gè)通過(guò)YesRole定義的“是”按鈕
Dialog.YesToAll // 一個(gè)通過(guò)YesRole定義的“全部同意”按鈕
Dialog.No // 一個(gè)通過(guò)NoRole定義的“否”按鈕
Dialog.NoToAll // 一個(gè)通過(guò)NoRole定義的“全部拒絕”按鈕
??當(dāng)用戶(hù) 點(diǎn)擊確認(rèn)按鈕 后,會(huì)觸發(fā) accepted() 信號(hào)。當(dāng)用戶(hù) 點(diǎn)擊取消按鈕 時(shí),會(huì)觸發(fā) rejected() 信號(hào)。當(dāng)用戶(hù)點(diǎn)擊對(duì)話(huà)框的按鈕之后,我們可以通過(guò) result 屬性 獲取用戶(hù)點(diǎn)擊的結(jié)果,如果值為 Dialog.Accepted 則表示 該對(duì)話(huà)框已被接受,如果值為 Dialog.Rejected 表示 該對(duì)話(huà)框已被拒絕。
??當(dāng)我們點(diǎn)擊對(duì)話(huà)框外邊,會(huì)發(fā)現(xiàn)對(duì)話(huà)框消失了,這相當(dāng)于我們點(diǎn)擊取消按鈕關(guān)閉對(duì)話(huà)框。此時(shí),我們可以通過(guò) closePolicy 屬性 設(shè)置對(duì)話(huà)框的關(guān)閉策略,它可以是以下值的集合:
Popup.NoAutoClose // 只有在手動(dòng)發(fā)出關(guān)閉指令的情況下,該彈出窗口才會(huì)關(guān)閉
Popup.CloseOnPressOutside // 當(dāng)鼠標(biāo)在彈出窗口外按下時(shí),該彈出窗口將會(huì)關(guān)閉
Popup.CloseOnPressOutsideParent // 當(dāng)鼠標(biāo)在其父元素外按下時(shí),彈出窗口將會(huì)關(guān)閉
Popup.CloseOnReleaseOutside // 當(dāng)鼠標(biāo)在彈出外釋放時(shí),該彈出窗口將會(huì)關(guān)閉
Popup.CloseOnReleaseOutsideParent // 當(dāng)鼠標(biāo)在其父元素外釋放時(shí),彈出窗口會(huì)關(guān)閉
Popup.CloseOnEscape // 當(dāng)按下“退出”鍵且彈出窗口具有活動(dòng)焦點(diǎn)時(shí),該彈出窗口將會(huì)關(guān)閉
closePolicy屬性的默認(rèn)值是Popup.CloseOnEscape | Popup.CloseOnPressOutside。
CloseOnPress和CloseOnRelease策略?xún)H適用于彈出窗口之外的事件。也就是說(shuō),如果有兩個(gè)彈出窗口打開(kāi),而第一個(gè)彈出窗口的策略為Popup.CloseOnPressOutside,那么點(diǎn)擊第二個(gè)彈出窗?口并不會(huì)導(dǎo)致第一個(gè)彈出窗口關(guān)閉。
??修改 template.qml 文件的內(nèi)容。
import QtQuick.Window
import QtQuick.Controls
// Window控件表示一個(gè)頂級(jí)窗口
// 在QML中,元素是通過(guò)大括號(hào){}內(nèi)的屬性來(lái)配置的。
Window {
id: windowId
width: 800 // 窗口的寬度
height: 600 // 窗口的高度
visible: true // 顯示窗口
color: "lightgray" // 窗口的背景顏色
Page {
anchors.fill: parent
header: ToolBar {
ToolButton {
icon.name: "document-new"
text: "添加信息"
display: AbstractButton.TextUnderIcon
onClicked: {
dialogId.open() // 打開(kāi)對(duì)話(huà)框
}
}
}
TextArea {
id: textAreaId
anchors.fill: parent
readOnly: true
font.family: "楷體"
font.pointSize: 32
color: "#FF66CC"
}
}
// 對(duì)話(huà)框
Dialog {
id: dialogId
width: 200
anchors.centerIn: parent
// 對(duì)話(huà)框是模態(tài)的,即用戶(hù)必須先關(guān)閉對(duì)話(huà)框,才能繼續(xù)與應(yīng)用程序交互
modal: true
// 對(duì)話(huà)框的關(guān)閉策略
closePolicy: Popup.NoAutoClose
title: "添加信息" // 消息對(duì)話(huà)框的標(biāo)題
Column {
id: columnId
anchors.fill: parent
spacing: 10
Text {
id: nameTextId
font.family: "楷體"
font.pointSize: 16
color: "#FF66CC"
text: "請(qǐng)輸入姓名:"
}
TextField {
id: nameTextFieldId
width: columnId.width
font: nameTextId.font
color: nameTextId.color
placeholderText: "請(qǐng)輸入姓名"
}
Text {
font: nameTextId.font
color: nameTextId.color
text: "請(qǐng)選擇性別:"
}
ComboBox {
id: sexComboBoxId
width: columnId.width
model: ["保密", "男", "女"]
font: nameTextId.font
}
Text {
font: nameTextId.font
color: nameTextId.color
text: "請(qǐng)輸入年齡:"
}
SpinBox {
id: ageSpinBoxId
width: columnId.width
editable: true
from: 0
to: 300
stepSize: 1
font: nameTextId.font
}
}
footer: ToolBar {
Row {
anchors.right: parent.right
ToolButton {
id: resetToolButtonId
width: 60
text: "重置"
onClicked: {
nameTextFieldId.text = ""
sexComboBoxId.currentIndex = 0
ageSpinBoxId.value = 0
}
}
ToolButton {
width: resetToolButtonId.width
text: "取消"
onClicked: {
dialogId.reject() // 拒絕對(duì)話(huà)框
}
}
ToolButton {
width: resetToolButtonId.width
text: "確認(rèn)"
onClicked: {
if (nameTextFieldId.text.trim() != "") {
dialogId.accept()
} else {
nameTextFieldId.text = ""
errorDialogId.open()
}
}
}
}
}
onAccepted: {
textAreaId.text += (nameTextFieldId.text + " " + sexComboBoxId.currentText + " " + ageSpinBoxId.value + "\n")
resetToolButtonId.clicked()
}
onRejected: {
resetToolButtonId.clicked()
}
}
Dialog {
id: errorDialogId
anchors.centerIn: parent
modal: true
standardButtons: Dialog.Ok // 對(duì)話(huà)框的按鈕
title: "錯(cuò)誤" // 對(duì)話(huà)框的標(biāo)題
Text {
anchors.centerIn: parent
font.family: "楷體"
font.pointSize: 16
color: "#FF66CC"
text: "姓名不能為空"
}
}
}

浙公網(wǎng)安備 33010602011771號(hào)