qt multiplatform development
TRANSCRIPT
start
Qt for beginners
Multiplatform development
with QtFramework
Sergiy Shevchenko
eTuitus S.r.l 2016
Part 2
Table of
Contents
01 Qml/C++ communicationBasic signal/slot concepts of qml/c++ communication
02 Qt for mobileCross-platform mobile development
03 Connecting C++ to nativeHow to interface with native Java and Objective C environments
next2
next4
QML/Qt communication
• Gui creates an event (click on button)• QML (via JS) invokes business logic in Qt• Business logic does something and returns a
result
next5
QML/Qt communicationPrepare object to expose (from C++ to QML)
//AbstractVibrator.h#include <QObject>
class AbstractVibrator : public QObject{ Q_OBJECTpublic: explicit AbstractVibrator(QObject *parent = 0);
Q_INVOKABLE virtual bool vibrate() = 0;};
Extends QObject
Q_INVOKABLE macro
next6
QML/Qt communicationExpose AbstractVibrator to QML
//main.cpp#include <QQmlApplicationEngine>#include <QQmlContext>
int main(int argc, char *argv[]){
QGuiApplication app(argc, argv);QQmlApplicationEngine engine;
qmlRegisterType<AbstractVibrator>();engine.rootContext()->setContextProperty("facadeVibrator", NativeAbstraction::getVibrateImpl());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));return app.exec();
}
Include DOM manipulation headers
Register new QML type
Set name and pass a pointer
next7
QML/Qt communicationAccess to facade from QML
Window { //...
MainForm { //...
vibrate.onClicked: { if(facadeVibrator.vibrate()){
console.log("Vibrate success");}else{
console.log("Vibration failed");}
}}
Just invoke function by name
next8
QML/Qt communicationDatatypes
JavaScript (QML) is dynamic, untyped, and interpreted programming language. On other side C++ is compiled and statically typed language.How do they deal together?
• QVariant (QString, int ecc..)• Registering type with qRegisterMetaType
and qmlRegisterType
next9
QML/Qt communicationDatatypes - pointers
Do not use pointers to C++ objects in QML!
If you have to, make a copy of object and return a pointer to a copy
Why? JavaScript has a GC so it will deallocate pointed object at most inconvenient time
next11
QML/Qt communicationSync/Async
Invoking C++ code from QML means that C++ will be executed in the same thread (GUI)
Solution use Facade pattern
next13
QML/Qt communicationAsync facade
Event starts here
Create new Thread and invoke getPrime
Invoke C++obtain a return
Once result is ready emit signal
next19
What do we need?
•Qt >= 5.5•Android SDK Tools e Android Studio•Android NDK•JDK v7 or major•XCode 7
next22
Simple projectOnce pressed "Vibrate" button device must
vibrate using integrated vibrator
Problem?Each platform realises vibration API differently and in native code!
QT -> NATIVE
next23
Things to do
• Lets create an empty project or use existing one (will be provided)
• Make gui with simple call to facade• Create platform independent
abstraction for vibration service• Write function calling Android
Vibration API in java• Write function calling iOS
Vibration API in Objective C• Implement bridges and trampoline
for Android and iOS respectively• Be happy!
next24
Project setup
• Modular structure• /platform/ contains all
native code• android project can be
opened with Android Studio• Once compiled iOS project
can be edited in XCode
next26
JNI
The Java Native Interface (JNI) is a programming framework that enables Java code running in a Java Virtual Machine (JVM) to call and be called by native applications or libraries written in other languages such as C, C++ and assembly.
next32
Handling device events
• For iOS things are simple: just include l• Android needs JNI exported functions
NATIVE -> QT
next34
Complex case: Android
•Export C functions using JNIEXPORT•Create "bridge" class with native methods in Java•Ensure Qt is running and invoke methods
Things to do
next36
Complex case: AndroidThread lifecycle
1.Call a Java method from C/C++ Qt thread. The Java method will be executed in Qt thread, so we we need a way to access Android APIs in Android UI thread.
2.Java method uses Activity.runOnUiThread to post a runnable on Android UI thread. This runnable will be executed by the Android event loop on Android UI thread.
3.The runnable accesses the Android APIs from Android UI thread.4.Call a C/C++ function from Android UI thread.5.Using QMetaObject::invokeMethod to post a method call on Qt event loop.6.Qt event loop will execute that function on Qt thread.
next42
Complex case: AndroidCheck Qt Startup NativeBridge.java
AndroidBridge.cpp
main.cpp
Somewhere in java...