Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

FileDialog + Settings question



  • Win7, Qt 5.13.0

    I'm using a FileDialog object and using a Settings object to record the last folder used by it. Some very confusing things are happening. I read the docs on Settings, and it looked like I could do something like this:

        Settings {
            id: settings
            property url myDir
            }
    
        FileDialog {
            folder: settings.myDir || shortcuts.desktop
            ...
            onAccepted: {
                settings.myDir = folder
                ...
                close()
                }
            }
    

    The idea is that the first time the program is run, it will use the desktop, the first time the dialog is opened on subsequent runs, it will use whatever is in the registry, OK-ing the dialog will write the folder URL to the property and to the registry, and subsequent openings will use the property value.

    When I started the program the first time, it immediately created a registry entry "HKCU\Software\myCompany\myProduct\myDir" variable, and also created a "HKCU\Software\myCompany\myProduct\QQControlsFileDialog" key which contained parameters related to the QML DefaultFileDialog object which I'm not using, since Windows has a native dialog box.

    The dialog box started out showing the desktop, and as soon as I chose a file and OKed it, the console output said Error: Cannot assign to non-existent property "myDir".

    So I changed it to settings.setValue("myDir", folder). I no longer got an error, but instead of setting "myDir", it created and set a new "QQControlsFileDialog\myDir" variable.

    I restarted the program, reopened the dialog, and it was back to the desktop. I tried copying the directory URL from "QQControlsFileDialog\myDir" into "myDir" above it, and restarted the program, but it still went to the desktop. In other words, folder = settings.myDir doesn't find "myDir" in either location in the registry, even though the Settings object created the variable in both of those locations in the first place.

    I removed the static definition of "myDir" in the Settings object, since it seemed superfluous, cleared out the registry, and started over. It didn't complain about the lack of a property when it read it, but only when it tried to write it. And of course, it didn't create "myDir" in the registry any more on startup.

    I changed settings.myDir to settings.value("myDir"), and it successfully read "QQControlsFileDialog\myDir". So everything worked. But this left me with a few questions:

    1. What am I doing differently, which prevents the normal property syntax from working on the Settings object, as shown in the docs?

    2. Why are my property references being directed to the "QQControlsFileDialog" sub-key? I understand why DefaultFileDialog's internal properties would end up there, because it's putting them there, but when I call settings.value("myDir") or settings.setValue("myDir", ...), I'm not referring to that sub-key.

    3. Since it's using the native file dialog, why is it junking up my corner of the registry with this "QQControlsFileDialog" key anyway? I'd really rather have my variables where I put them, not in some obscurely named key that I didn't choose.



  • Settings {
        id: settings
        property url myDir: StandardPaths.writableLocation(StandardPaths.DesktopLocation)
    }
    
    FileDialog {
        folder: settings.myDir
        onAccepted: settings.myDir = folder
    }
    

    0_1561275344873_acc1e8b4-7d1b-4583-8f2a-35b5886cacbf-image.png



  • @Nifiro Not sure what you're trying to show me there. It looks like your initialization of the myDir property probably writes the URL into the registry, which doesn't surprise me. But when you activate the dialog, does it show the directly listed in the registry? When you OK it, does it change what's listed in the registry, or does it output an error to the console?



  • when you activate the dialog, does it show the directly listed in the registry

    yes

    does it change what's listed in the registry, or does it output an error to the console?

    It changes it on component destruction



  • @Nifiro Minor correction: like me, you're setting the property on OKing the dialog, not on destruction of the FileDialog (which never gets destroyed until the program closes). But you're right, it seems to work.

    But I'm doing something a little different in my program: I'm defining the Settings object in my Main.qml, with the id "settings", while the FileDialog is in a different .qml file that is instantiated as a descendent of the main window. So I wrote this little test program, consisting of this Main.qml:

    import QtQuick 2.13
    import QtQuick.Window 2.13
    import Qt.labs.settings 1.0
    
    Window {
        id: win
        visible: true
        width: 100
        height: 100
        title: qsTr("FileSettingsTest")
    
        Settings {
            id: settings
            property url myDir
            }
    
        Dialog {
            anchors.fill: parent
            }
        }
    

    and this Dialog.qml file:

    import QtQuick 2.13
    import QtQuick.Dialogs 1.3
    
    Rectangle {
    
        MouseArea {
            anchors.fill: parent
            onClicked: fileDlg.open()
            }
    
        FileDialog {
            id: fileDlg
            folder: settings.myDir || shortcuts.desktop
            onAccepted: {
                settings.myDir = folder
                close()
                }
            visible: false
            }
        }
    

    For some reason this fails, in the manner I described originally.

    I thought there might be some problem with the name "settings", so I changed it (in one place in Main.qml and two places in Dialog.qml) to "setngs", and all of a sudden it worked!

    So I went back into my much larger program, and changed "settings" to "setngs" in both files. It didn't work!

    I'm wondering if my understanding of the visibility of object ids across file boundaries is a little off. But this is really mysterious, because if my Dialog.qml can't refer to settings.myDir, why does it work to write settings.value("myDir")? It's as though something is interfering with my ability to refer to my Settings object sometimes, and I can't figure out when or why.

    Could you, or anyone, try my example, and figure out why I can refer to my Settings if I call it "setngs" but not "settings"? Or maybe you understand scope rules better than I do, and can see immediately what I'm doing wrong.


Log in to reply