qt multiplatform development

43
start Qt for beginners Multiplatform development with QtFramework Sergiy Shevchenko eTuitus S.r.l 2016 Part 2

Upload: sergio-shevchenko

Post on 22-Jan-2018

102 views

Category:

Technology


2 download

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

next3

QML/Qt communication

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

next10

QML/Qt communicationDatatypes - pointers

SigningLibrary.cpp

SigningFacade.cpp

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

next12

QML/Qt communicationFacade design pattern

QML

C++

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

next14

QML/Qt communicationAsync Facade

MainForm.ui.qml

next15

QML/Qt communicationAsync Facade MainForm.qml

next16

QML/Qt communicationAsync Facade

main.cpp

PrimeFacade.h PrimeFacade.cpp

PrimeGenerator.h

next17

QML/Qt communication

LIVE

next18

Cross-platform mobile development

Integration with native APIs

next19

What do we need?

•Qt >= 5.5•Android SDK Tools e Android Studio•Android NDK•JDK v7 or major•XCode 7

next20

Generic application

Packaging• .APK• Gradle or ANT• .IPA• XCode export

tool

next21

QtCreator config

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

next25

Vibration abstractions

<<use>>

<<use>>

<<use>>

<<use>>

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.

next27

Vibration abstractions

AbstractVibrator.h

AndroidVibrator.hSpecificimplementation

next28

Android Native Impl.

AndroidVibrator.cpp

EtMobileActivity.java

next29

IOS Native implementation

VibratorTrampoline.h

IOSVibrator.cpp

VibratorTrampoline.mm

next30

Orchestrating classesNativeAbstraction.cpp

NativeAbstraction.h

main.cpp

next31

Orchestrating filescore.pro

next32

Handling device events

• For iOS things are simple: just include l• Android needs JNI exported functions

NATIVE -> QT

next33

Simple case: iOS

AppDelegate.mm

just include *.h

use Qt/C++ code

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

next35

Complex case: AndroidExport C functions

src/it/infocert/mobile/dike/JNIOpener.java

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.

next37

Complex case: AndroidThread lifecycle

NO

main()

Start App

next38

Complex case: AndroidJava -> QT

next39

Complex case: AndroidJava -> QT

next40

Complex case: AndroidCheck Qt Startup

Start App

Complex case: AndroidCheck Qt Startup

QtStartMonitor.h

next

next42

Complex case: AndroidCheck Qt Startup NativeBridge.java

AndroidBridge.cpp

main.cpp

Somewhere in java...

close

Thank You

Presenter: Sergiy Shevchenko

eTuitus S.r.l 2016