- Install required packages for simStubsGen: see simStubsGen's README
- Download and install Qt (same version as CoppeliaSim)
- Checkout, compile and install into CoppeliaSim:
$ git clone https://github.com/CoppeliaRobotics/simQML.git
$ cd simQML
$ git checkout coppeliasim-v4.5.0-rev0
$ mkdir -p build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .
$ cmake --install .
NOTE: replace coppeliasim-v4.5.0-rev0
with the actual CoppeliaSim version you have.
NOTE: You may need to set the CMAKE_PREFIX_PATH
environment variable to the lib/cmake
subdirectory of your Qt installation, i.e. /path/to/Qt/Qt5.9.0/5.9/<platform>/lib/cmake
NOTE: You may need to run the deploy tool to copy additional Qt dependencies to CoppeliaSim, e.g.:
macdeployqt $COPPELIASIM_ROOT_DIR/../.. -qmldir=/path/to/simQML/qml -always-overwrite -verbose=2
In order to load QML components, a QML engine must be created:
engine = simQML.createEngine()
simQML.load(engine, '/path/to/Component.qml')
When the engine is not needed anymore, it should be destroyed with:
simQML.destroyEngine(engine)
Note: destroying the engine would destroy also all components created within that engine, e.g. all the windows.
It is also possible to load QML inline code, using simQML.loadData
.
This component can be found in the CoppeliaSimPlugin
QML module.
PluginWindow
is a subclass of QtQuick.Window
which sets some convenience properties and handlers.
It is possible to use any other component, such as QtQuick.Window
as the top-level component, but PluginWindow
is what makes sense most of the times.
Example:
simQML.loadData(engine, [[
import QtQuick 2.12
import CoppeliaSimPlugin 1.0
PluginWindow {
id: mainWindow
width: 400
height: 300
title: qsTr("QML plugin window")
}
]])
It is possible to send events from QML to Lua using the sendEvent
(or sendEventRaw
) method of the CoppeliaSimBridge
component.
For convenience, CoppeliaSimBridge
is already instantiated in the PluginWindow
component and exposed as the property simBridge
.
QML can call simBridge.sendEvent(eventName, eventData)
to send an event to Lua.
In order to receive the event in Lua, an event handler must be registered with simQML.setEventHandler
:
function myEventHandler(engine, eventName, eventData)
print('received event', eventName, eventData)
end
engine = simQML.createEngine()
simQML.setEventHandler(engine, 'myEventHandler')
simQML.loadData(engine, [[
import QtQuick 2.12
import QtQuick.Controls 2.12
import CoppeliaSimPlugin 1.0
PluginWindow {
id: mainWindow
width: 400
height: 300
title: qsTr("QML plugin window")
Button {
anchors.fill: parent
text: "Click me"
onClicked: mainWindow.simBridge.sendEvent('click', {someData: 42})
}
}
]])
It is possible to send events from Lua to QML using the simQML.sendEvent(engine, name, data)
Lua function.
In order to receive the event in QML, the handler onEventReceived
of the CoppeliaSimBridge
object must be implemented.
For convenience, if using the PluginWindow
component, that handler is already implemented, and the event will be dispatched as a call to a function defined in the PluginWindow
component.
engine = simQML.createEngine()
simQML.loadData(engine, [[
import QtQuick 2.12
import CoppeliaSimPlugin 1.0
PluginWindow {
id: mainWindow
width: 400
height: 300
title: qsTr("QML plugin window")
function myEvent(data) {
console.log("received event 'myEvent', someData=" + data.someData)
}
}
]])
simQML.sendEvent(engine, 'myEvent', {someData = 42})
An onInstanceSwitch
event with bool argument is sent each time the scene owning the engine becomes active/inactive.
The PluginWindow
component already implements the handler for this event, setting the visible
property of the Window
. Set the sticky
property to true
to override this behavior.