FileDialog
gives a QML url
variable. theurl.toString()
gives something like file:///c:\foo\bar.txt
. How do I get c:\foo\bar.txt
?
I want to do it in a cross-platform way, and ideally without relying on regex-style hacks. QUrl
provides a path()
method, but I don't seem to be able to access it from QML.
As noted in the comments already, there seems to be no way (yet?) to get the path itself without a regex. So this is the only way to go:
Basic solution
FileDialog {
onAccepted: {
var path = myFileDialog.fileUrl.toString();
// remove prefixed "file:///"
path = path.replace(/^(file:\/{3})/,"");
// unescape html codes like '%23' for '#'
cleanPath = decodeURIComponent(path);
console.log(cleanPath)
}
}
This regex should be quite robust as it only removes the file:///
from the beginning of the string.
You will also need to unescape some HTML characters (if the file name contains e.g. the hash #
, this would be returned as %23
. We decode this by using the JavaScript function decodeURIComponent()
).
Fully featured example
If you not only want to filter the file:///
but also qrc://
and http://
, you can use this RegEx:
^(file:\/{3})|(qrc:\/{2})|(http:\/{2})
So the new, complete code would be:
FileDialog {
onAccepted: {
var path = myFileDialog.fileUrl.toString();
// remove prefixed "file:///"
path= path.replace(/^(file:\/{3})|(qrc:\/{2})|(http:\/{2})/,"");
// unescape html codes like '%23' for '#'
cleanPath = decodeURIComponent(path);
console.log(cleanPath)
}
}
This is a good playground for RegEx'es: http://regex101.com/r/zC1nD5/1
In MS Windows "file:///c:\foo\bar.txt" should be converted to "c:\foo\bar.txt". However in Linux the url "file:///Users/data/abcdef" has the correct path as "/Users/data/abcdef". I have created a simple function to convert url to path:
function urlToPath(urlString) {
var s
if (urlString.startsWith("file:///")) {
var k = urlString.charAt(9) === ':' ? 8 : 7
s = urlString.substring(k)
} else {
s = urlString
}
return decodeURIComponent(s);
}
Following Chris Dolan's answer above, it's probably neatest to deal with this using a slot in C++:
public slots:
void handleFileChosen(const QString &urlString) {
const QUrl url(urlString);
if (url.isLocalFile()) {
setFile(QDir::toNativeSeparators(url.toLocalFile()));
} else {
setFile(urlString);
}
}