PDA

View Full Version : Binding FileDialog folder to property



mentalmushroom
27th September 2016, 14:46
There is a Qt Quick application which allows the user to open some type of a file. The folder property of the file dialog is bound to the property of the application class (in my case it is faveFolder) and the application may change the value of this property. Thus I would expect the FileDialog to be positioned on the new folder. In fact, it respects only the initial value of the property.

My QML code is shown below:


import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

Window
{
visible: true

MouseArea
{
anchors.fill: parent

FileDialog
{
id: fileDialog
title: "Please choose a file"
nameFilters: "NZB Files (*.nzb)"
folder: app.faveFolder // binding to the property of Application

onAccepted:
{
//nzbFileDialog.folder = "file:///Z:/";
app.openFile(fileDialog.fileUrl);
print("new folder: " + fileDialog.folder);

// ! this line magically solves the issue :)
//fileDialog.folder = fileDialog.folder;
}
} // FileDialog

onClicked:
{
print("app.faveFolder = " + app.faveFolder + " fileDialog.folder = " + fileDialog.folder);
fileDialog.visible = true;
//fileDialog.open();
}
}

Text
{
text: qsTr("Click to open")
anchors.centerIn: parent
}
}


The Application instance (app) is passed to QML in main.cpp:


#include "application.h"

//#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

int main(int argc, char *argv[])
{
Application app(argc, argv);

QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("app", &app);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}


Application.h:


#ifndef APPLICATION_H
#define APPLICATION_H

#include <QGuiApplication>

class Application: public QGuiApplication
{
Q_OBJECT

//Q_PROPERTY(QString nzbFolder MEMBER nzbDir NOTIFY nzbFolderChanged)
Q_PROPERTY(QString faveFolder MEMBER faveDir NOTIFY faveFolderChanged)

public:
Application(int argc, char * argv[]);

Q_INVOKABLE void openFile(const QString &filePath);

signals:
void faveFolderChanged();
//void faveFolderChanged(const QString &newPath);

private:
QString faveDir;
};

#endif // APPLICATION_H




#include "application.h"

#include <QUrl>
#include <QFileInfo>
#include <QDebug>

Application::Application(int argc, char * argv[]): QGuiApplication(argc, argv)
{
this->faveDir = "file:///D:/temp"; // set the initial value
}

void Application::openFile(const QString &filePath)
{
qDebug() << filePath;
this->faveDir = "file:///Z:/"; // set the new value
//this->faveDir = QUrl::fromLocalFile(QFileInfo(QUrl(filePath).toLoc alFile()).absolutePath()).toString();
qDebug() << this->faveDir;
emit faveFolderChanged();
//emit faveFolderChanged(this->faveDir);
}


This is what was printed to the output window:


qml: app.faveFolder = file:///D:/temp fileDialog.folder = file:///D:/temp
"file:///Z:/crash_part29.nzb"
"file:///Z:/"
qml: new folder: file:///Z:/
qml: app.faveFolder = file:///Z:/ fileDialog.folder = file:///Z:/


As a one can see from the last line, which is printed right before showing the file dialog, it does have the updated value. In spite of this, when opened FileDialog is still positioned to the old folder. And the interesting thing here is that uncommenting the line "fileDialog.folder = fileDialog.folder" somehow solves the issue.

anda_skoa
27th September 2016, 16:28
The "folder" property is very likely set by the dialog if you change the folder, which overwrites the initial binding.

Why the commented line fixes that I don't know, usually it would be required to reset the binding, e.g. using Qt.binding().

Cheers,
_

mentalmushroom
27th September 2016, 16:56
The "folder" property is very likely set by the dialog if you change the folder, which overwrites the initial binding.
Not sure I understand you correctly. The thing is the dialog uses the initial value of the folder property regardless of what directory I navigated to and regardless of the new value of this property. For example, in my case the folder property is initialized with the value "file:///d:/temp". Then I open a file from the directory "z:/", the property is updated to "file:///z:/", but when I open the dialog again it still points to "d:/temp". So I can't understand what the dialog sets and why.

anda_skoa
27th September 2016, 16:59
Ah, interesting.

I guess it is an "input only" property then, assuming that the developer changes it if necessary.

Cheers,
_