Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between `:/foo`, `qrc:/foo` and `qrc:///foo` paths in Qt

This code succeeds:

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

This code prints "failure":

QFile file("qrc:/main.qml");
if ( file.open(QIODevice::ReadOnly) ) {
    cout << "success" << endl;
} else {
    cout << "failure" << endl;
}

Changing the QFile constructor argument to qrc:///main.qml (as in the Qt documentation) doesn't fix it. Changing it to :/main.qml makes it print "success" though.

So I'm confused as to when to use each of the 3 forms.

like image 266
Stefan Monov Avatar asked Sep 26 '16 11:09

Stefan Monov


1 Answers

As stated in your link, :/main.qml is a file path, while qrc:/main.qml is an url.

The former can be used where a file path is required -- basically a QString, like with QFile constructor.

The latter can be used where an url is required, like with QQmlApplicationEngine::load through QUrl. It can not be used with QFile constructor where a path is needed.

About qrc:///, a simplified url syntax (without query, user/password, nor port) can be:

scheme:[//host][/]path

Which can lead to scheme:/path if you skip host part, or scheme:///path if you specify host as an empty string. From RFC 3986:

For example, the "file" URI scheme is defined so that no authority, an empty host, and "localhost" all mean the end-user's machine, whereas the "http" scheme considers a missing authority or empty host invalid.

Looks like Qt's developers followed the rules of the file scheme when designing their qrc scheme. After all, the resources here are just files "on the end-user's machine" (in fact, inside an executable on the end-user's machine). So qrc:/main.qml and qrc:///main.qml are just two writings of the same url.

See here for complete url syntax.

like image 117
rgmt Avatar answered Oct 13 '22 20:10

rgmt