Qt C++ application connecting signals to JavaScript?
-
I am developing a Qt application that implements a GUI based on an XML file, so far so good, now I want to add Javascript to the XML file and connect signals from Qt controls to Javascript functions.
I've seen this on QML and Javascript:
http://doc.qt.io/archives/qt-4.8/qdeclarativejavascript.htmlIs it possible from a Qt C++ application?
Here is the definition that creates a QPushButton:
<button id="btn1" x="160" y="116" width="80" properties="QPushButton {border: 1px solid yellow; border-radius: 4px; padding: 1px 18px 1px 3px; min-width: 6em}"> <state value="off" text="Off"/> <state value="on" text="On"/> <signal name="pbtnClicked"> <subscriber sid="win2:title"/> <script> function onClick() { }; </script> </signal> <signal name="pbtnPressed"/> <signal name="pbtnReleased"/> <signal name="pbtnToggled"/> </button>
What I would like to do is be able to connect the javascript function with the signal in C++...
Can this be done?
-
@SPlatten said in Qt C++ application connecting signals to JavaScript?:
What I would like to do is be able to connect the javascript function with the signal in C++
Something like this?
QJSEngine* engine = ...; connect( button, &QPushButton::clicked, this, [engine] () { QString script = ... QJSValue returnValue = engine->evaluate(script); }
See the docs for how the script should look like
-
What sort of thing can QJSEngine do and not do?
In my simple test code I tried:
QObject::connect(pobjPushButton ,&QPushButton::clicked ,[pobjScriptEng]() { pobjScriptEng->evaluate("alert('hello');"); });
I put a break point on the line inside the callback and when I clicked on the pushbutton I could see the debugger stop on the evaluate line, but having executed the line, I didn't the alert displayed and no error was thrown.
Can anyone help?
I've got a little bit further by including a call:
mspobjJSeng->installExtensions(QJSEngine::AllExtensions);
I don't think 'alert()' is supported.
-
Hi
http://doc.qt.io/qt-5/qjsengine.html#details
Try
console.info()
instead. -
Hi
As far as i know, you cant.
However, if you see in
https://doc.qt.io/qt-5.11/whatsnew57.html
section Qt QML Module
says
"Enabled all debug services to work with QJSEngine (instead of QQmlEngine), which allows non-QML JavaScript debugging or profiling."so i assume if you have a js file, you can actualy debug this and see members.
However, Not inside a mere string in a c++ file. -
I've hit another problem now, I'm trying to pass in a QString containing a script that was read from file, however when I try to assign this:
QObject::connect(pobjPushButton ,&QPushButton::clicked ,[pobjScriptEng]() { pobjScriptEng->evaluate(static_cast<const QString>(strScript)); });
I get:
variable 'strScript' cannot be implicitly captured in a lambda with no capture-default specified
What does this mean?
-
Hi @SPlatten,
This means you need to "capture" the variable you want to use in the lambda. This tells to the compiler that have to keep the variable, usually a local one, in the memory to be accessible when the lambda is called.
Capturing the variable is done by adding its name inside the brackets []. You can also add
&
suffix for passing variable by reference, in.QObject::connect(pobjPushButton ,&QPushButton::clicked ,[pobjScriptEng, &strScript]() { //or [&] to use the "by-reference capture default" mode pobjScriptEng->evaluate(static_cast<const QString>(strScript)); });
More informations here: https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture
-
It's all in the docs http://doc.qt.io/qt-5/qjsengine.html
QJSvalue module = myEngine.importModule("./math.mjs"); QJSValue sumFunction = module.property("sum"); QJSValue result = sumFunction.call(args);
This will call the function
sum
from the modulemath.mjs
passingargs
as arguments