Scripting Your Qt Application
-
Upload
qt-project -
Category
Technology
-
view
12.179 -
download
2
description
Transcript of Scripting Your Qt Application
Scripting Your Qt Application09/25/09
About Me (Kent Hansen)
• Working on Qt since 2005
• QtScript
• Qt State Machine framework
• Plays harmonica and Irish whistle
2
Goals For This Talk
• Give overview of QtScript and things related to it
• Show how to embed QtScript into your application
3
Agenda
• What is application scripting?
• QtScript tour (the essentials)
• Debugger
• Misc.
4
“Scripting Your Application”: What?
• Premise: Core functionality implemented in C++
• Interface(s) exported to scripting environment
• Plugin-based, interactive (console), ...
5
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
What is QtScript?
• A Qt module
• A scripting language
• An “engine” for evaluating scripts
• An API for embedding into your application
7
The QtScript Language
• Based on ECMA-262 standard–“JavaScript minus DOM”
• Object-oriented, dynamically typed
• Java-like syntax
8
Disclaimer
This is not a JavaScript tutorial!
9
The QtScript Engine
• Executes scripts
• Performs C++ <--> script bridging
• It's re-entrant
10
The QtScript API
• Embed QtScript engine in your application
• Expose C++ objects to script environment
• Work with script values from C++
11
Why should you use QtScript?
• Easy to embed into any Qt application
• Tight integration with rest of Qt
• Easy-to-use API
12
Agenda
• What is application scripting?
• QtScript tour (the essentials)
• Debugger
• Misc.
13
QtScript tour (the essentials)
• Basic embedding (example)
• Working with QScriptValues
• Configuring the script environment
• Qt meta-object system integration
14
Example: Meaning of Life Calculator
15
“Our objective: Write an application that uses
QtScript to calculate the meaning of life”
QScriptEngine object
16
QScriptEngine engine;
• “Vanilla” environment
• Built-in ECMA objects–Array, Math, RegExp, Error, ...–parseInt(), parseFloat(), ...
• No Qt-specific script APIs
Mutating the Environment (I)
17
Mutating the Environment (II)
• Evaluate scripts
• Operate on QtScript values in C++
18
QtScript tour (the essentials)
• Basic embedding (example)
• Working with QScriptValues
• Configuring the script environment
• Qt meta-object system integration
19
QScriptValue class
• Represents a QtScript (JavaScript) value• Undefined• Null• Boolean• Number• String• Object
–Functions, arrays, regexps, errors, ...• Invalid (no value)
20
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
QScriptValue construction
• Constructors for standard Qt/C++ types
• qScriptValueFromValue()• Counterpart to qscriptvalue_cast()
• QScriptEngine::newXXX()• Object, QObject, Array, RegExp
22
QScriptValue property access
23
JS: myObject.foo = 123;
myObject['foo'] = 123;
C++: myObject.setProperty(“foo”, 123);
QScriptValue holds reference to object (I)
24
QScriptValue object = engine.evaluate(“{ foo: 123, toString: function() { return 'MyObject(foo=' + this.foo + ')'; }}”);
QScriptValue holds reference to object (II)
25
QScriptValue same = object;object.setProperty(“foo”, 456);qDebug() << same.toString();
QScriptValue called as function
26
JS: myArray.sort(); or
myArray['sort'].call(myArray);
C++: myArray.property(“sort”)
.call(myArray);
Calling a function with arguments (I)
27
JS: myObject.myFunction(123, “foo”);
C++: myFunction.call(
myObject,
QScriptValueList()
<< 123 << “foo”);
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);
Calling a function as constructor (I)
29
JS: function Point(x, y) {
this.x = x;
this.y = y;
}
...
new Point(10, 20);
Calling a function as constructor (II)
30
C++:
QScriptValue p = Point.construct(
QScriptValueList() << 10 << 20);
qDebug() << p.property(“x”).toNumber();
QScriptValueIterator class
31
QScriptValueIterator it(myObject);
while (it.hasNext()) {
it.next(); qDebug() << it.name();
}
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';
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();
Error Handling (I)
34
// Uh-oh, this script will throw an error!
QScriptValue result = engine.evaluate(
“noSuchVariable”);
Error Handling (II)
35
if (result.isError()) {
QString message = result.toString();
// Notify user about the problem ...
}
QScriptValue API Summary
• isXXX(), toXXX()
• property() and setProperty()
• call(), construct()
• QScriptValueIterator for introspection
36
QtScript tour (the essentials)
• Basic embedding (example)
• Working with QScriptValues
• Configuring the script environment
• Qt meta-object system integration
37
The Global Object
• A built-in script object
• Every QScriptEngine has one• QScriptEngine::globalObject()
• Initially contains properties defined by ECMA-262
38
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
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);
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);
QtScript tour (the essentials)
• Basic embedding (example)
• Working with QScriptValues
• Configuring the script environment
• Qt meta-object system integration
42
Qt Meta-Object System
• In Qt, QObject-based classes can be introspected
at runtime• Properties• Signals & slots
• QObject::connect()
• Qt Designer property editor
• ...
43
Relax! Leave it to magic
44
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
QtScript <--> QObject Integration (II)
• Proxy provides signals and slots as properties
• Proxy provides named child objects as properties
46
QtScript <--> QObject Integration (III)
• Ownership control
• Customize proxy behavior• Don't expose child objects• Don't expose super class contents
47
Example: Scripting a QLineEdit
48
qScriptConnect() function
• Connect a signal to a script function
• Let scripts define signal handlers
• Application does the “plumbing”
49
Summary of “API essentials”
• QScriptValue
• QScriptEngine• evaluate()• globalObject()• newQObject()
• qScriptConnect()
50
Agenda
• What is application scripting?
• QtScript tour (the essentials)
• Debugger
• Misc.
51
The QtScript Debugger
• Graphical debugger
• Introduced in Qt 4.5
• To make the API available in your application:QT += scripttools#include <QtScriptTools>
52
Debugger Demo
Look at the pretty little demo!
53
The QtScript Debugger API (I)
One class in public API: QScriptEngineDebugger
54
QScriptEngine engine;
QScriptEngineDebugger debugger;
debugger.attachTo(&engine);
// evaluate scripts ...
The QtScript Debugger API (II)
• Debugger actions can be programmatically
triggered
• Individual debugger widgets are accessible
55
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;
Agenda
• What is application scripting?
• QtScript tour (the essentials)
• Debugger
• Misc.
57
Prototypes...?
58
Prototype-based Inheritance (I)
59
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
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
Bindings for Qt's APIs (I)
• Available as stand-alone project
• qtscriptgenerator on Qt Labs
(http://labs.qt.nokia.com)
62
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
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
Thank You!
Questions?
65