正确关闭 qml 对话框
Closing qml dialog properly
我一直在玩对话,但有些事情困扰着我。
我有以下代码:
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: dlgTest.open()
}
Dialog{
id:dlgTest
visible:false
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: dlgTest.close()
text: "Close"
}
}
}
}
当我第一次打开它时,我向 TextField 添加了一些文本,然后将其关闭。但是,如果我再次打开它,文本仍会存在。我想要的是 "reset" 对话框回到我第一次打开它时的原始状态(带有空的 TextField)。看来调用方法"close"和把visible改成false是一模一样的。
有没有办法做到这一点"reset"?
我有一个包含很多控件的其他对话框,必须手动恢复所有内容很烦人。
在您的代码中,您创建了一次对话框,作为 ApplicationWindow
的子项。
要'reset'它,你有两个选择:
- 有一个重置功能,你可以调用它来恢复一切。您也可以使用它来首先设置它
- 创建一个一切就绪的新对象。
对于后者,您可以使用 JavaScript 动态对象创建或 Loader
.
JavaScript 动态对象创建:
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: {
var d = diaComp.createObject(null)
d.open()
}
}
Component {
id: diaComp
Dialog{
id:dlgTest
visible:false
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: {
dlgTest.close()
dlgTest.destroy()
}
text: "Close"
}
}
}
}
但是,当您销毁该对象时,您的属性内容将丢失,并且您无法再访问它们。所以你需要确保首先将它们复制(而不是绑定它们)到一些没有被破坏的属性。
使用 Loader
,您可以在再次加载对话框之前卸载对话框,这基本上会重置它。但是在卸载它之前,您仍然可以访问它的值,正如您在 Button
s onClicked-handler 中看到的那样。
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: {
console.log((dlgLoad.status === Loader.Ready ? dlgLoad.item.value : 'was not loaded yet'))
dlgLoad.active = false
dlgLoad.active = true
dlgLoad.item.open()
}
}
Loader {
id: dlgLoad
sourceComponent: diaComp
active: false
}
Component {
id: diaComp
Dialog{
id:dlgTest
visible:false
property alias value: tfText.text
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: {
dlgTest.close()
}
text: "Close"
}
}
}
}
当然,您也可以复制 Loader 项目的值,然后提前卸载它,以尽可能释放内存。
但是如果 Dialog
经常(大部分时间)显示,避免创建和销毁对象可能是最明智的做法,方法是重用它并手动重置它。
我一直在玩对话,但有些事情困扰着我。
我有以下代码:
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: dlgTest.open()
}
Dialog{
id:dlgTest
visible:false
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: dlgTest.close()
text: "Close"
}
}
}
}
当我第一次打开它时,我向 TextField 添加了一些文本,然后将其关闭。但是,如果我再次打开它,文本仍会存在。我想要的是 "reset" 对话框回到我第一次打开它时的原始状态(带有空的 TextField)。看来调用方法"close"和把visible改成false是一模一样的。
有没有办法做到这一点"reset"?
我有一个包含很多控件的其他对话框,必须手动恢复所有内容很烦人。
在您的代码中,您创建了一次对话框,作为 ApplicationWindow
的子项。
要'reset'它,你有两个选择:
- 有一个重置功能,你可以调用它来恢复一切。您也可以使用它来首先设置它
- 创建一个一切就绪的新对象。
对于后者,您可以使用 JavaScript 动态对象创建或 Loader
.
JavaScript 动态对象创建:
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: {
var d = diaComp.createObject(null)
d.open()
}
}
Component {
id: diaComp
Dialog{
id:dlgTest
visible:false
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: {
dlgTest.close()
dlgTest.destroy()
}
text: "Close"
}
}
}
}
但是,当您销毁该对象时,您的属性内容将丢失,并且您无法再访问它们。所以你需要确保首先将它们复制(而不是绑定它们)到一些没有被破坏的属性。
使用 Loader
,您可以在再次加载对话框之前卸载对话框,这基本上会重置它。但是在卸载它之前,您仍然可以访问它的值,正如您在 Button
s onClicked-handler 中看到的那样。
Button {
id: click
x: 285
y: 189
text: qsTr("Click")
onClicked: {
console.log((dlgLoad.status === Loader.Ready ? dlgLoad.item.value : 'was not loaded yet'))
dlgLoad.active = false
dlgLoad.active = true
dlgLoad.item.open()
}
}
Loader {
id: dlgLoad
sourceComponent: diaComp
active: false
}
Component {
id: diaComp
Dialog{
id:dlgTest
visible:false
property alias value: tfText.text
contentItem: Rectangle{
width: 300
height: 300
TextField{
id: tfText
anchors.top: parent.top
}
Button{
anchors.top: tfText.bottom
onClicked: {
dlgTest.close()
}
text: "Close"
}
}
}
}
当然,您也可以复制 Loader 项目的值,然后提前卸载它,以尽可能释放内存。
但是如果 Dialog
经常(大部分时间)显示,避免创建和销毁对象可能是最明智的做法,方法是重用它并手动重置它。