Qt 从QML url获取路径

Qt 从QML url获取路径,qt,url,qml,filedialog,Qt,Url,Qml,Filedialog,FileDialog提供一个QMLurl变量URL.toString()给出了类似于file:///c:\foo\bar.txt。如何获取c:\foo\bar.txt 我想以一种跨平台的方式来做这件事,理想情况下不需要依赖正则表达式风格的黑客QUrl提供了一个path()方法,但我似乎无法从QML访问它。正如注释中已经指出的那样,如果没有正则表达式,似乎无法(目前?)获取路径本身。所以这是唯一的出路: 碱性溶液 这个正则表达式应该非常健壮,因为它只从字符串开头删除文件:// 您还需要取消对一些H

FileDialog
提供一个QML
url
变量
URL.toString()
给出了类似于
file:///c:\foo\bar.txt
。如何获取
c:\foo\bar.txt


我想以一种跨平台的方式来做这件事,理想情况下不需要依赖正则表达式风格的黑客
QUrl
提供了一个
path()
方法,但我似乎无法从QML访问它。

正如注释中已经指出的那样,如果没有正则表达式,似乎无法(目前?)获取路径本身。所以这是唯一的出路:

碱性溶液 这个正则表达式应该非常健壮,因为它只从字符串开头删除
文件://

您还需要取消对一些HTML字符的扫描(如果文件名包含例如哈希
#
,这将作为
%23
返回。我们使用JavaScript函数
decodeURIComponent()
对其进行解码)

全功能示例 如果您不仅要筛选
文件://
,还要筛选
qrc://
http://
,则可以使用以下正则表达式:

^(file:\/{3})|(qrc:\/{2})|(http:\/{2})
因此,新的完整代码将是:

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)
    }
}
这是正则表达式的好去处:

在MS Windows中”file:///c:\应将“foo\bar.txt”转换为“c:\foo\bar.txt”。但是在Linux中,url“file:///Users/data/abcdef“的正确路径为“/Users/data/abcdef”。我创建了一个将url转换为路径的简单函数:

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);
}

按照上面Chris Dolan的回答,使用C++中的插槽处理这个问题可能是最简单的:

public slots:

void handleFileChosen(const QString &urlString) {
    const QUrl url(urlString);
    if (url.isLocalFile()) {
        setFile(QDir::toNativeSeparators(url.toLocalFile()));
    } else {
        setFile(urlString);
    }
}

如果你想你的应用程序将是跨平台的这个网址正是你需要的。根据
RFC3986
URL以协议开头。在您的情况下,它是
文件://
。所有Qt组件都理解它,更糟糕的是,有时您在传递类似
c:/bar.txt的内容时会出现错误。如果您仍然希望以错误的方式获取此URL,您只需要替换协议部分-
URL.toString().replace(“file:///”,“”)
是的,我说过我不想使用正则表达式风格的黑客。我想知道是否有一种方法可以直接给我路径数据(它存储在QUrl对象中)。这不是传递给Qt组件。向用户显示文件名。我深入研究了Qt源代码。QML“URL”类型似乎是由C++ QURL类支持的,它有一个非常好的ToCalFLIE()方法,但这不是一个QuiNojkabl方法,很遗憾。我认为删除Windows >代码> ///<代码> 3个斜线对于Windows是必要的,但是会在UNIX上中断。当然,它只适用于
文件://
URL(而不是
文件://
——对于两个或三个斜杠,请使用
/^(文件:\/{2,3})//
)。或者你是什么意思?作为参考,请参阅:我的意思是它不适用于其他方案,如
qrc://
http://
。我并不是说它在很多情况下都不起作用;只需指出它与
QUrl::path()
不同。我知道了。我假设,您只需要文件对话框中的文件。但是你是对的,你也可以在那里输入一个
http://
-URL。我适当地编辑了我的答案。我希望我现在已经涵盖了所有的案例。但是是的,当然像
QUrl::path()
-一样的函数是理想的。为什么要删除3个
//
,而不仅仅是2个呢?@pooya13这已经是很久以前的事了,所以对此要小心谨慎:我认为原因是
文件:///
总是有3个斜杠,而像
http://
这样的“协议”有2个斜杠。甚至不知道为什么。可能最后一个斜杠只是文件路径的一部分,即
/home/mozzbozz
(“根”斜杠)。可能依赖于平台?不确定(但不太可能用于Qt)。
public slots:

void handleFileChosen(const QString &urlString) {
    const QUrl url(urlString);
    if (url.isLocalFile()) {
        setFile(QDir::toNativeSeparators(url.toLocalFile()));
    } else {
        setFile(urlString);
    }
}