正确关闭qml对话框

Abd*_*oui 1 qt qml qtquick2 qtquickcontrols

我一直在玩对话,有些东西困扰着我.

我有以下代码:

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"
            }


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我第一次打开它时,我将一些文本添加到TextField然后关闭它.但是,如果我再次打开它,文本仍将存在.我想要的是当我第一次打开它时(使用空的TextField)将对话框"重置"到它的原始状态.调用方法"close"似乎与将visible变为false完全相同.

有没有办法做这个"重置"?

我有一个其他对话框,有很多控件,很烦人必须手动恢复一切.

der*_*erM 6

在你的代码中,你创建了一次Dialog,作为一个孩子ApplicationWindow.要"重置"它,您有两种选择:

  • 有一个你可以调用的重置功能,并恢复所有功能.您也可以使用它来设置它
  • 创建一个新对象,其中包含所有设置.

对于后者,您可以使用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"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当您销毁对象时,属性的内容将丢失,您无法再访问它们.因此,您需要首先确保将它们(不绑定它们)复制到一些未被破坏的属性.

随着Loader你有posibility卸载对话框再次加载正确之前,基本上就复位.但是在你卸载之前,你仍然可以访问它的值,正如你在ButtononClicked-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"
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您也可以复制 Loader项目中的值,然后再将其卸载,以释放内存.

但是,如果Dialog经常(大部分时间)显示,通过重复使用并手动重置,可能最明智的做法是避免对象的创建和破坏.

  • 您可以通过执行`sourceComponent:Dialog {...}`直接在`Loader`的`sourceComponent`属性中声明`Dialog`组件.您不必显式创建`Component`对象,您可以像这样内联定义它,对于委托也是如此. (2认同)