Hi all
I want to learn how to make a qml application scriptable. I would like to have user defined scripts that can be changed without having to recompile the app. Also, I would like to create an object and call a function from anywhere in javascript. During researching the topic I found some webpages mentioning that QtScript is no longer maintained. Is that true? What is the recommanded way to make a qml-application fully scriptable in qt5.4 (for qml applications)?
Some background:
At first I thought, that there is already a javascript functionality in qml. So, I started to write some javascripts and loaded them from a file. I can make my c++ objects available with:
// in main.cpp
qmlRegisterType<CustonObject>("MyCustonObject", 1, 0, "QmlCustonObject");
// In my qml I can use a script with
import "someFile.js" as File
// in main.cpp
qmlRegisterType<CustonObject>("MyCustonObject", 1, 0, "QmlCustonObject");
// In my qml I can use a script with
import "someFile.js" as File
To copy to clipboard, switch view to plain text mode
This works great as long as the file is in the resources (qrc). However, I want to be able to change the scripts without having to recompile the application. So, I looked at
Qt.import("otherFile.js")
Qt.import("otherFile.js")
To copy to clipboard, switch view to plain text mode
And wanted to import that file from the "someFile.js" which is in the resources. I found that I need an absolute path for this to work. The problem is then that the path will change across different platforms. So I needed a way to have the path dynamic. The only way here was to wrap the import in a function
// function in "someFile.js"
function loadScript(path)
{
Qt.import(path);
}
// function in "someFile.js"
function loadScript(path)
{
Qt.import(path);
}
To copy to clipboard, switch view to plain text mode
While that works, the script is then only available inside the function scope. If I warp everything in such a function call, the script gets laoded every time the function is called. So, I packed it into an object instead to avoid loading the script multiple times.
// defined in "someFile.js"
function Loader() {
Qt.import(getPathFromQmlFunction());
}
Loader.prototype.Execute() {
// do stuff here...
}
var MyLoader = new Loader();
// defined in "someFile.js"
function Loader() {
Qt.import(getPathFromQmlFunction());
}
Loader.prototype.Execute() {
// do stuff here...
}
var MyLoader = new Loader();
To copy to clipboard, switch view to plain text mode
In a qml file I can then add a helper function. The only part to be aware of is that this function must be declared before the "someFile.js" gets included.
// defined in qml
function getPathFromQmlFunction()
{
// figure out path for plattform
return "some/path/goes/here/otherFile.js";
}
// defined in qml
function getPathFromQmlFunction()
{
// figure out path for plattform
return "some/path/goes/here/otherFile.js";
}
To copy to clipboard, switch view to plain text mode
while this works, it requires me to fiddle with the Loader object and extend it depending on what I want to make available to the scripts. It seams a cumbersome way to implement scripting and I am unsure about it's limitations and restrictions across platforms. Hence, my initial question. What is the proper/recommanded way to make a qml application fully scriptable? Should I continue with this approach or should I use Qt Script instead and load my scripts with a QScriptEngine?
Edit: fixed some typo
Bookmarks