Qt Signal Slot Call Order
As Qt WebKit is replaced by Qt WebEngine(you can refer to this post about porting issues), accessing html elements from C++ directly becomes impossible. Many works originally done by QWebKit classes are now transferred to javascript. Javascript is used to manipulate web content. And you need to call runJavaScript from C++ code to run javascript on the web page loaded by QWebEngineView.To get web elements, a communication mechanism is invented to bridge the C++ world and the javascript world. The bridging mechanism is more than obtaining the values of web page elements. It provides the ways in which C++ code can call javascript functions, and javascript can invoke C++ functions as well.The values of variables can also be passed from C++ to javascript, and vice versa. Let’s consider the following application scenarios:
Support for signals and slots pyqt 5.10.1 reference guide support for signals and slots one of the key features of qt is its use of signals and slots to. In order to call a Qt slot directly from Lisp, you can use this function. For a list of all available Qt slots to call, see example 3-dialogs-and-objects.lisp.
javascript code calls C++ function
Signals and Events in Qt. But lets start with Qt. Qt offers two different systems for our needs, Qt signal/slot and QEvents. While Qt signal/slot is the moc driven signaling system of Qt (which you can connect to via QObject::connect), there is a second Event interface informing you about certain system-like events, such as QMouseEvent, QKeyEvent or QFocusEvent. In contrast to slots, signals may be handled by none, one or many components. There is no guarantee that triggering a signal in C will actually run QML code, unless there’s a handler defined. Properties work both ways: Properties are read- and write-able from both C and QML. Qt's widgets have many pre-defined slots, but it is common practice to subclass widgets and add your own slots so that you can handle the signals that you are interested in. The signals and slots mechanism is type safe: The signature of a signal must match the signature of the receiving slot.
C++ code should provide a class which contains the to-be-called function(as a slot), then register an object of this class to a QWebChannel object, and set the web channel object to the web page object in the QWebEngineView
To invoke the C++ function jscallme, javascript should new an instance of QWebChannel object.
QWebChannel is defined in qwebchannel.js(you can find this file in the example folder of Qt installation directory) so the script should be loaded first. In the function passed as the second parameter of function QWebChannel, the exposed object from C++ world(webobj in C++) channel.objects.webobj is assigned to the javascript variable webobj, and then assigned to window.foo so you can use foo elsewhere to refer to the object. After the function is executed, javascript can call the C++ slot function jscallme as follows:
Pass data from javascript to C++
We’ve known how to call C++ function from javascript. You should be able to figure out a way to pass data from javascript to C++, i.e., as parameter(s) of function. We re-implement jscallme as follows:
, and invoking of the function from js would be:
Note that the “const” before the parameter can not be omitted, otherwise, you will get the following error:
Could not convert argument QJsonValue(string, “sd”) to target type .
Although data can be passed as parameters of function, it would be more convenient if we can pass data by setting an attribute of an object like:
We expect after the code is executed, “somedata” will be stored in a member variable of the exposed object (webobj) in C++. This is done by delaring a qt property in C++ class:
Now if you execute foo.someattribute=”somedata” in javascript, m_someattribute in C++ will be “somedata”.
Pass data from C++ to javascript
We can send data from C++ to javascript using signals. We emit a signal with the data to send as the parameter of the signal. Javascript must connect the signal to a function to receive the data.
The line “webobj.someattributeChanged.connect(updateattribute)” connects the C++ signal someattributeChanged to the javascript function updateattribute. Note that although updateattribute takes one parameter “text”, we did not provide the parameter value in connect. In fact, we do not know the parameter value passed to updateattribute until the signal is received. The signal is accompanied by a parameter “attr” which is passed as the “text” parameter of updateattribute. Now, if you call webobj->setsomeattribute(“hello”), you will see the value of the html element with id “#attrid” is set to “hello”. Note that although we connect the member m_someattribute to the qt property someattribute in the above example, it is not a required step. The signal mechanism alone can realize the delivery of data.
We can make things even simpler by adding the NOTIFY parameter when declaring the someattribute property.
Now, if you call webobj->setProperty(“someattribute”,”hello”) somewhere in C++, the signal “someattributeChanged” is automatically emitted and our web page gets updated.
C++ invokes javascript function
This is much straightforward compared with invoking C++ function from js. Just use runJavaScript passing the function as the parameter as follows:
It assumes the jsfun is already defined on your web page, otherwise, you have to define it in the string parameter. The return value is asynchronously passed to the lambda expression as the parameter v.
Now, back to the question raised at the beginning of the post: How to get the value of an html element in C++? It can be done as follows:
It uses jQuery functions so make sure jQuery lib is running on your web page.
Introduction
Remember old X-Windows call-back system? Generally it isn't type safe and flexible. There are many problems with them. Qt offers a new event handling system: signal-slot connections. Imagine an alarm clock. When alarm is ringing, a signal is being sent (emit). And you're handling it in a slot.
- Every QObject class may have as many signals and slots as you want
- You can emit signals only from within that class, where the signal is located
- You can connect signal with another signal (make chains of signals);
- Every signal and slot can have unlimited count of connections with other.
- ATTENTION! You can't set default value in slot attributes e.g. void mySlot(int i = 0);
Connection
You can connect signal with this template:
QObject::connect (
);
You have to wrap const char * signal and const char * method into SIGNAL() and SLOT() macros.
And you also can disconnect signal-slot:
QObject::disconnect (
);
Deeper
Widgets emit signals when events occur. For example, a button will emit a clicked signal when it is clicked. A developer can choose to connect to a signal by creating a function (a slot) and calling the connect() function to relate the signal to the slot. Qt's signals and slots mechanism does not require classes to have knowledge of each other, which makes it much easier to develop highly reusable classes. Since signals and slots are type-safe, type errors are reported as warnings and do not cause crashes to occur.
For example, if a Quit button's clicked() signal is connected to the application's quit() slot, a user's click on Quit makes the application terminate. In code, this is written as
connect(button, SIGNAL (clicked()), qApp, SLOT (quit()));
Connections can be added or removed at any time during the execution of a Qt application, they can be set up so that they are executed when a signal is emitted or queued for later execution, and they can be made between objects in different threads.
The signals and slots mechanism is implemented in standard C++. The implementation uses the C++ preprocessor and moc, the Meta Object Compiler, included with Qt. Code generation is performed automatically by Qt's build system. Developers never have to edit or even look at the generated code.
In addition to handling signals and slots, the Meta Object Compiler supports Qt's translation mechanism, its property system, and its extended runtime type information. It also makes runtime introspection of C++ programs possible in a way that works on all supported platforms.
Qt Signal Slot Call Orders
To make moc compile the meta object classes don't forget to add the Q_OBJECT macro to your class.