web-dev-qa-db-ja.com

QML URLからパスを取得する

FileDialogはQML url変数を提供します。 theurl.toString()は、_file:///c:\foo\bar.txt_のようなものを提供します。 _c:\foo\bar.txt_を取得するにはどうすればよいですか?

私はクロスプラットフォームの方法で、理想的には正規表現スタイルのハックに依存せずにそれを実行したいです。 QUrlpath()メソッドを提供しますが、QMLからアクセスできないようです。

17
Timmmm

すでにコメントで述べられているように、正規表現なしでパス自体を取得する方法は(まだ?)ないようです。したがって、これが唯一の方法です。

基本的な解決策

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

この正規表現は、_file:///_を文字列の先頭から削除するだけなので、非常に堅牢でなければなりません。

一部のHTML文字のエスケープを解除する必要もあります(ファイル名にハッシュ_#_が含まれている場合、これは_%23_として返されます。JavaScript関数decodeURIComponent()を使用してこれをデコードします)。

フル機能の例

_file:///_だけでなく、_qrc://_および_http://_もフィルタリングする場合は、次のRegExを使用できます。

_^(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)
    }
}
_

これはRegExの良い遊び場です: http://regex101.com/r/zC1nD5/1

5
mozzbozz

上記の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);
    }
}
5
Anthony Hayward

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