Solved Loading UI Form from disk, logic deployed as resource
-
Or does anyone know a way to make the UI customizable without exposing my program logic?
-
Is Page3Form.ui.qml in the same directory? I guess it cant be if one is in a qrc.
Also for importing:
https://stackoverflow.com/questions/22168457/include-another-qml-file-from-a-qml-fileMaybe try putting your user customizable qml in a directory that is imported?
-
I have tried to load qml files from the local directory and while it acts like it will work in the editor it will not see those files when running. I don't see a way to make qml files that are qrc resources to "see" files that are local on the disk. There has to be a way though. It seems silly that you could not mix them.
-
I checked the qml import path:
qInfo() << engine.importPathList();
It returns the local directory of the application. I have qml files and directories placed there and it will not import the files or directories from there.
-
I can import relative path qml files this way:
import 'file:qml' as QML ... QML.TestComponent02 { }
Where qml is a directory in the current directory of where the executable runs and TestComponent02 is TestComponent02.qml in that qml directory. I cannot find a way to import the current directory path.
I found this where some of this is discussed:
https://stackoverflow.com/questions/45484222/qml-import-external-javascript-file
-
@fcarney said in Loading UI Form from disk, logic deployed as resource:
I can import relative path qml files this way:
import 'file:qml' as QML ... QML.TestComponent02 { }
I could live with a fixed subdirectory of the applicationDirPath, but this only works for me with an absolute path, like
import "file:D:/Projects/qmltest/qml" as QML
I added both the applicationDirPath and the qml-subdir to the importPathList, with no luck. Did you add anything else to get this to work? Is the file containing this import loaded from qrc?
@fcarney said in Loading UI Form from disk, logic deployed as resource:
I found this where some of this is discussed:
https://stackoverflow.com/questions/45484222/qml-import-external-javascript-file
Unfortunately this seems to work only for javascript files (and not qml).
-
@ThoPa
I haven't tried this, but you could give your qml engine the applicationDir path as contextpropertysetContextProperty("applicationDirPath", QApplication::applicationDirPath());
Maybe the import accepts that as valid path ?
-
@J.Hilk said in Loading UI Form from disk, logic deployed as resource:
@ThoPa
I haven't tried this, but you could give your qml engine the applicationDir path as contextpropertysetContextProperty("applicationDirPath", QApplication::applicationDirPath());
Maybe the import accepts that as valid path ?
Yeah, I tried that, but you can't use variables in import statements.
But I guess I found another workaround.
If I create my own NetworkAccessManagerFactory and pass it to the qmlengine, use my own scheme in the import statement and redirect this to the local dir, it seems to work:QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& originalRequest, QIODevice* outgoingData = nullptr) { if (op == QNetworkAccessManager::GetOperation) { QUrl url = originalRequest.url(); if (originalRequest.url().scheme() == "test") { QUrl nurl = QUrl::fromLocalFile(QString("%1/qml%2").arg(qApp->applicationDirPath()).arg(url.path())); QNetworkRequest req(originalRequest); req.setUrl(nurl); return QNetworkAccessManager::createRequest(op, req, outgoingData); } } return QNetworkAccessManager::createRequest(op, originalRequest, outgoingData); }
And in my Page3.qml from qrc:
import "test://qml" as Test Test.Page3Form { }
Thanks for the help!
-
You have to copy the qml files to the actual run/build directory for it to see the files. The path of that directory is added to the qml import paths. So wherever the exe is actually running from is the path that shows up as "local" to the program. I had to explicitly copy those files. So if you want to have your source qml be seen after changes you may want to add the copying of those files to the build process script (pro file).
-
Another option that you could use for development is to add an additional import path:
engine.addImportPath("D:/Projects/qmltest/qml"); qInfo() << engine.importPathList();
Then during development you don't have to copy files.