QQmlApplicationEngine: Yet another fix after QUrl behavior changes in QtBase

Picture the following application:
    QQmlApplication qAppEngine("main.qml");

With main.qml:
    ...
    AComponentInTheSameDirectory {
    }
    ...

This was failing, with the error:
    file:main.qml:13 AComponentInTheSameDirectory is not a type

Which is wrong, but also reveals the root cause in that the
original filename was not a fully resolved path.

Change-Id: Ifc5557cc43f4bb92fd121ea9f7a37f09b3b38a9b
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Robin Burchell 2017-01-15 15:25:25 +01:00
parent d8ce18b323
commit 01f7a9dbe2
4 changed files with 49 additions and 5 deletions

View File

@ -190,9 +190,14 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
/*!
\fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url)
This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object.
Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the
QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath).
This signal is emitted when an object finishes loading. If loading was
successful, \a object contains a pointer to the loaded object, otherwise
the pointer is NULL.
The \a url to the component the \a object came from is also provided.
\note If the path to the component was provided as a QString containing a
relative path, the \a url will contain a fully resolved path to the file.
*/
/*!
@ -226,7 +231,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent)
This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards.
*/
QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent)
: QQmlApplicationEngine(QUrl::fromLocalFile(filePath), parent)
: QQmlApplicationEngine(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile), parent)
{
}
@ -265,7 +270,7 @@ void QQmlApplicationEngine::load(const QUrl &url)
void QQmlApplicationEngine::load(const QString &filePath)
{
Q_D(QQmlApplicationEngine);
d->startLoad(QUrl::fromLocalFile(filePath));
d->startLoad(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile));
}
/*!

View File

@ -0,0 +1,6 @@
import QtQml 2.0
// used in nonResolvedLocal
QtObject {
}

View File

@ -0,0 +1,9 @@
import QtQml 2.0
QtObject {
property bool success: true
property QtObject local: LocalComponent {
}
}

View File

@ -42,6 +42,7 @@ public:
private slots:
void initTestCase();
void basicLoading();
void testNonResolvedPath();
void application();
void applicationProperties();
private:
@ -83,6 +84,29 @@ void tst_qqmlapplicationengine::basicLoading()
delete test;
}
// make sure we resolve a relative URL to an absolute one, otherwise things
// will break.
void tst_qqmlapplicationengine::testNonResolvedPath()
{
{
// NOTE NOTE NOTE! Missing testFileUrl is *WANTED* here! We want a
// non-resolved URL.
QQmlApplicationEngine test("data/nonResolvedLocal.qml");
QCOMPARE(test.rootObjects().size(), 1);
QVERIFY(test.rootObjects()[0]);
QVERIFY(test.rootObjects()[0]->property("success").toBool());
}
{
QQmlApplicationEngine test;
// NOTE NOTE NOTE! Missing testFileUrl is *WANTED* here! We want a
// non-resolved URL.
test.load("data/nonResolvedLocal.qml");
QCOMPARE(test.rootObjects().size(), 1);
QVERIFY(test.rootObjects()[0]);
QVERIFY(test.rootObjects()[0]->property("success").toBool());
}
}
void tst_qqmlapplicationengine::application()
{
/* This test batches together some tests about running an external application