scripting your qt application

65
Scripting Your Qt Application 09/25/09

Upload: qt-project

Post on 12-May-2015

12.175 views

Category:

Technology


2 download

DESCRIPTION

The Qt Script module enables you as a Qt/C++ application developer to seamlessly integrate scripting into your application, providing script authors with an interface for working in the context of your particular Qt application. The Qt Script language is very similar to JavaScript, so many developers and designers should already find it familiar. This session gives an overview of the main steps of embedding Qt Script into an application, and covers some typical patterns of usage. Presentation by Kent Hansen held during Qt Developer Days 2009. http://qt.nokia.com/developer/learning/elearning

TRANSCRIPT

Page 1: Scripting Your Qt Application

Scripting Your Qt Application09/25/09

Page 2: Scripting Your Qt Application

About Me (Kent Hansen)

• Working on Qt since 2005

• QtScript

• Qt State Machine framework

• Plays harmonica and Irish whistle

2

Page 3: Scripting Your Qt Application

Goals For This Talk

• Give overview of QtScript and things related to it

• Show how to embed QtScript into your application

3

Page 4: Scripting Your Qt Application

Agenda

• What is application scripting?

• QtScript tour (the essentials)

• Debugger

• Misc.

4

Page 5: Scripting Your Qt Application

“Scripting Your Application”: What?

• Premise: Core functionality implemented in C++

• Interface(s) exported to scripting environment

• Plugin-based, interactive (console), ...

5

Page 6: Scripting Your Qt Application

Golden Example: The Web Browser

• Script loaded as part of web page

• Browser exports tree-based API to page (DOM)

• Script manipulates the page

6

Page 7: Scripting Your Qt Application

What is QtScript?

• A Qt module

• A scripting language

• An “engine” for evaluating scripts

• An API for embedding into your application

7

Page 8: Scripting Your Qt Application

The QtScript Language

• Based on ECMA-262 standard–“JavaScript minus DOM”

• Object-oriented, dynamically typed

• Java-like syntax

8

Page 9: Scripting Your Qt Application

Disclaimer

This is not a JavaScript tutorial!

9

Page 10: Scripting Your Qt Application

The QtScript Engine

• Executes scripts

• Performs C++ <--> script bridging

• It's re-entrant

10

Page 11: Scripting Your Qt Application

The QtScript API

• Embed QtScript engine in your application

• Expose C++ objects to script environment

• Work with script values from C++

11

Page 12: Scripting Your Qt Application

Why should you use QtScript?

• Easy to embed into any Qt application

• Tight integration with rest of Qt

• Easy-to-use API

12

Page 13: Scripting Your Qt Application

Agenda

• What is application scripting?

• QtScript tour (the essentials)

• Debugger

• Misc.

13

Page 14: Scripting Your Qt Application

QtScript tour (the essentials)

• Basic embedding (example)

• Working with QScriptValues

• Configuring the script environment

• Qt meta-object system integration

14

Page 15: Scripting Your Qt Application

Example: Meaning of Life Calculator

15

“Our objective: Write an application that uses

QtScript to calculate the meaning of life”

Page 16: Scripting Your Qt Application

QScriptEngine object

16

QScriptEngine engine;

• “Vanilla” environment

• Built-in ECMA objects–Array, Math, RegExp, Error, ...–parseInt(), parseFloat(), ...

• No Qt-specific script APIs

Page 17: Scripting Your Qt Application

Mutating the Environment (I)

17

Page 18: Scripting Your Qt Application

Mutating the Environment (II)

• Evaluate scripts

• Operate on QtScript values in C++

18

Page 19: Scripting Your Qt Application

QtScript tour (the essentials)

• Basic embedding (example)

• Working with QScriptValues

• Configuring the script environment

• Qt meta-object system integration

19

Page 20: Scripting Your Qt Application

QScriptValue class

• Represents a QtScript (JavaScript) value• Undefined• Null• Boolean• Number• String• Object

–Functions, arrays, regexps, errors, ...• Invalid (no value)

20

Page 21: Scripting Your Qt Application

QScriptValue type checks & conversion

• isXXX(): Tests if value is of a certain type

• toXXX(): Converts to Qt/C++ type

• qscriptvalue_cast(): Converts to C++ type

21

Page 22: Scripting Your Qt Application

QScriptValue construction

• Constructors for standard Qt/C++ types

• qScriptValueFromValue()• Counterpart to qscriptvalue_cast()

• QScriptEngine::newXXX()• Object, QObject, Array, RegExp

22

Page 23: Scripting Your Qt Application

QScriptValue property access

23

JS: myObject.foo = 123;

myObject['foo'] = 123;

C++: myObject.setProperty(“foo”, 123);

Page 24: Scripting Your Qt Application

QScriptValue holds reference to object (I)

24

QScriptValue object = engine.evaluate(“{ foo: 123, toString: function() { return 'MyObject(foo=' + this.foo + ')'; }}”);

Page 25: Scripting Your Qt Application

QScriptValue holds reference to object (II)

25

QScriptValue same = object;object.setProperty(“foo”, 456);qDebug() << same.toString();

Page 26: Scripting Your Qt Application

QScriptValue called as function

26

JS: myArray.sort(); or

myArray['sort'].call(myArray);

C++: myArray.property(“sort”)

.call(myArray);

Page 27: Scripting Your Qt Application

Calling a function with arguments (I)

27

JS: myObject.myFunction(123, “foo”);

C++: myFunction.call(

myObject,

QScriptValueList()

<< 123 << “foo”);

Page 28: Scripting Your Qt Application

Calling a function with arguments (II)

28

QScriptValue adder = engine.evaluate(

“(function(a, b) { return a+b; })”);

QScriptValue result = adder.call(

/*thisObject=*/QScriptValue(),

QScriptValueList() << 41 << 1);

Page 29: Scripting Your Qt Application

Calling a function as constructor (I)

29

JS: function Point(x, y) {

this.x = x;

this.y = y;

}

...

new Point(10, 20);

Page 30: Scripting Your Qt Application

Calling a function as constructor (II)

30

C++:

QScriptValue p = Point.construct(

QScriptValueList() << 10 << 20);

qDebug() << p.property(“x”).toNumber();

Page 31: Scripting Your Qt Application

QScriptValueIterator class

31

QScriptValueIterator it(myObject);

while (it.hasNext()) {

it.next(); qDebug() << it.name();

}

Page 32: Scripting Your Qt Application

Working with JavaScript Arrays (I)

32

JS:

var a = [10, 20, 30];

print(a[0], a['0']); // same property

a.foo = 123;

a.push(40);

a[a.length] = 'appended';

Page 33: Scripting Your Qt Application

Working with JavaScript Arrays (II)

33

C++:

QScriptValue a = engine.evaluate(

“[10, 20, 30]”); // array literal

qDebug() << a.property(“length”).toInt32();

qDebug() << a.property(“0”).toNumber();

// for convenience + speed

qDebug() << a.property(0).toNumber();

Page 34: Scripting Your Qt Application

Error Handling (I)

34

// Uh-oh, this script will throw an error!

QScriptValue result = engine.evaluate(

“noSuchVariable”);

Page 35: Scripting Your Qt Application

Error Handling (II)

35

if (result.isError()) {

QString message = result.toString();

// Notify user about the problem ...

}

Page 36: Scripting Your Qt Application

QScriptValue API Summary

• isXXX(), toXXX()

• property() and setProperty()

• call(), construct()

• QScriptValueIterator for introspection

36

Page 37: Scripting Your Qt Application

QtScript tour (the essentials)

• Basic embedding (example)

• Working with QScriptValues

• Configuring the script environment

• Qt meta-object system integration

37

Page 38: Scripting Your Qt Application

The Global Object

• A built-in script object

• Every QScriptEngine has one• QScriptEngine::globalObject()

• Initially contains properties defined by ECMA-262

38

Page 39: Scripting Your Qt Application

Tailoring Scripting to Your Application

• Design “contract” of C++ <--> script interaction

• Set properties of Global Object

• Evaluate scripts that use your API

• (Optional: Call back into script objects as

appropriate)

39

Page 40: Scripting Your Qt Application

Example: Meaning of Life Environment

40

C++:QScriptEngine engine;

QScriptValue global = engine.globalObject();

global.setProperty(“meaningOfLife”, 42,

QScriptValue::ReadOnly);

JS:var myMeaningOfLife = Math.sqrt(meaningOfLife);

Page 41: Scripting Your Qt Application

Example: Fake Navigator Object

41

C++:

QScriptValue navigator = engine.newObject();

navigator.setProperty(“appVersion”, 1);

navigator.setProperty(“appMinorVersion”, 1);

navigator.setProperty(“cookieEnabled”, false);

navigator.setProperty(“browserLanguage”, “en_US”);

navigator.setProperty(“platform”, “No Such OS”);

navigator.setProperty(“userAgent”, “007”);

global.setProperty(“navigator”, navigator);

Page 42: Scripting Your Qt Application

QtScript tour (the essentials)

• Basic embedding (example)

• Working with QScriptValues

• Configuring the script environment

• Qt meta-object system integration

42

Page 43: Scripting Your Qt Application

Qt Meta-Object System

• In Qt, QObject-based classes can be introspected

at runtime• Properties• Signals & slots

• QObject::connect()

• Qt Designer property editor

• ...

43

Page 44: Scripting Your Qt Application

Relax! Leave it to magic

44

Page 45: Scripting Your Qt Application

QtScript <--> QObject Integration (I)

• QScriptEngine::newQObject(QObject*)

• Returns a script object that acts as proxy

• Proxy delegates property access to

QObject::property() and QObject::setProperty()

45

Page 46: Scripting Your Qt Application

QtScript <--> QObject Integration (II)

• Proxy provides signals and slots as properties

• Proxy provides named child objects as properties

46

Page 47: Scripting Your Qt Application

QtScript <--> QObject Integration (III)

• Ownership control

• Customize proxy behavior• Don't expose child objects• Don't expose super class contents

47

Page 48: Scripting Your Qt Application

Example: Scripting a QLineEdit

48

Page 49: Scripting Your Qt Application

qScriptConnect() function

• Connect a signal to a script function

• Let scripts define signal handlers

• Application does the “plumbing”

49

Page 50: Scripting Your Qt Application

Summary of “API essentials”

• QScriptValue

• QScriptEngine• evaluate()• globalObject()• newQObject()

• qScriptConnect()

50

Page 51: Scripting Your Qt Application

Agenda

• What is application scripting?

• QtScript tour (the essentials)

• Debugger

• Misc.

51

Page 52: Scripting Your Qt Application

The QtScript Debugger

• Graphical debugger

• Introduced in Qt 4.5

• To make the API available in your application:QT += scripttools#include <QtScriptTools>

52

Page 53: Scripting Your Qt Application

Debugger Demo

Look at the pretty little demo!

53

Page 54: Scripting Your Qt Application

The QtScript Debugger API (I)

One class in public API: QScriptEngineDebugger

54

QScriptEngine engine;

QScriptEngineDebugger debugger;

debugger.attachTo(&engine);

// evaluate scripts ...

Page 55: Scripting Your Qt Application

The QtScript Debugger API (II)

• Debugger actions can be programmatically

triggered

• Individual debugger widgets are accessible

55

Page 56: Scripting Your Qt Application

Invoking the Debugger from a Script

• Use the debugger keyword

• Becomes no-op if no debugger is attached

56

JS:

var a = Math.random();

debugger; // synchronously run debugger

var b = Math.random();

debugger;

return a + b;

Page 57: Scripting Your Qt Application

Agenda

• What is application scripting?

• QtScript tour (the essentials)

• Debugger

• Misc.

57

Page 58: Scripting Your Qt Application

Prototypes...?

58

Page 59: Scripting Your Qt Application

Prototype-based Inheritance (I)

59

Page 60: Scripting Your Qt Application

Prototype-based Inheritance: Why care?

• Not every QObject member is a property / signal /

slot

• Not everything is a QObject

• Not everything should/needs to be a QObject

• JS developers are familiar with prototypes

60

Page 61: Scripting Your Qt Application

Prototype-based Inheritance: How?

• Create a prototype object for the C++ type

• Register the type with Qt's meta-type system

• Associate prototype object with meta-type ID

• Create QScriptValues from the C++ type

(qScriptValueFromValue())

61

Page 62: Scripting Your Qt Application

Bindings for Qt's APIs (I)

• Available as stand-alone project

• qtscriptgenerator on Qt Labs

(http://labs.qt.nokia.com)

62

Page 63: Scripting Your Qt Application

Bindings for Qt's APIs (II)

• Creates plugins that can be imported into a script

engine

• Provides bindings for most of Qt's classes

• Makes it possible to write pure script applications

63

Page 64: Scripting Your Qt Application

Summary

• It's easy to make your Qt application scriptable

with QtScript

• There's a QtScript debugger (also part of Qt)

• You can achieve a lot by mastering a small API

64

Page 65: Scripting Your Qt Application

Thank You!

Questions?

65