|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the documentation of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \group script |
|
44 \title Scripting Classes and Overviews |
|
45 |
|
46 \brief Classes that add scripting capabilities to Qt applications. |
|
47 */ |
|
48 |
|
49 /*! |
|
50 \page scripting.html |
|
51 \title Making Applications Scriptable |
|
52 \ingroup frameworks-technologies |
|
53 |
|
54 Qt 4.3 and later provides support for application scripting with ECMAScript. |
|
55 The following guides and references cover aspects of programming with |
|
56 ECMAScript and Qt. |
|
57 |
|
58 \tableofcontents |
|
59 |
|
60 \section1 Scripting Classes |
|
61 |
|
62 The following classes add scripting capabilities to Qt applications. |
|
63 |
|
64 \annotatedlist script |
|
65 |
|
66 \section1 Language Overview |
|
67 |
|
68 Qt Script is based on the ECMAScript scripting language, as defined |
|
69 in standard \l{ECMA-262}. Microsoft's JScript, and Netscape's |
|
70 JavaScript are also based on the ECMAScript standard. For an |
|
71 overview of ECMAScript, see the |
|
72 \l{ECMAScript Reference}{ECMAScript reference}. |
|
73 If you are not familiar with the ECMAScript language, there are |
|
74 several existing tutorials and books that cover this subject, such |
|
75 as \l{JavaScript: The Definitive Guide}. |
|
76 |
|
77 Existing users of \l{Qt Script for Applications (QSA)} may find the |
|
78 \l{Moving from QSA to Qt Script} document useful when porting |
|
79 QSA scripts to Qt Script. |
|
80 |
|
81 \section1 Basic Usage |
|
82 |
|
83 To evaluate script code, you create a QScriptEngine and call its |
|
84 evaluate() function, passing the script code (text) to evaluate |
|
85 as argument. |
|
86 |
|
87 \snippet doc/src/snippets/qtscript/evaluation/main.cpp 0 |
|
88 |
|
89 The return value will be the result of the evaluation (represented |
|
90 as a QScriptValue object); this can be converted to standard C++ |
|
91 and Qt types. |
|
92 |
|
93 Custom properties can be made available to scripts by registering |
|
94 them with the script engine. This is most easily done by setting |
|
95 properties of the script engine's \e{Global Object}: |
|
96 |
|
97 \snippet doc/src/snippets/qtscript/registeringvalues/main.cpp 0 |
|
98 |
|
99 This places the properties in the script environment, thus making them |
|
100 available to script code. |
|
101 |
|
102 \section1 Making a QObject Available to the Script Engine |
|
103 |
|
104 Any QObject-based instance can be made available for use with scripts. |
|
105 |
|
106 When a QObject is passed to the QScriptEngine::newQObject() function, |
|
107 a Qt Script wrapper object is created that can be used to make the |
|
108 QObject's signals, slots, properties, and child objects available |
|
109 to scripts. |
|
110 |
|
111 Here's an example of making an instance of a QObject subclass |
|
112 available to script code under the name \c{"myObject"}: |
|
113 |
|
114 \snippet doc/src/snippets/qtscript/registeringobjects/main.cpp 0 |
|
115 |
|
116 This will create a global variable called \c{myObject} in the |
|
117 script environment. The variable serves as a proxy to the |
|
118 underlying C++ object. Note that the name of the script variable |
|
119 can be anything; i.e., it is not dependent upon QObject::objectName(). |
|
120 |
|
121 The \l{QScriptEngine::}{newQObject()} function accepts two additional |
|
122 optional arguments: one is the ownership mode, and the other is a |
|
123 collection of options that allow you to control certain aspects of how |
|
124 the QScriptValue that wraps the QObject should behave. We will come |
|
125 back to the usage of these arguments later. |
|
126 |
|
127 \section2 Using Signals and Slots |
|
128 |
|
129 Qt Script adapts Qt's central \l{Signals and Slots} feature for |
|
130 scripting. There are three principal ways to use signals and slots |
|
131 with Qt Script: |
|
132 |
|
133 \list |
|
134 \i \bold{Hybrid C++/script}: C++ application code connects a |
|
135 signal to a script function. The script function can, for example, be |
|
136 a function that the user has typed in, or one that you have read from a |
|
137 file. This approach is useful if you have a QObject but don't want |
|
138 to expose the object itself to the scripting environment; you just |
|
139 want a script to be able to define how a signal should be reacted |
|
140 to, and leave it up to the C++ side of your application to establish |
|
141 the connection. |
|
142 |
|
143 \i \bold{Hybrid script/C++}: A script can connect signals and slots |
|
144 to establish connections between pre-defined objects that the |
|
145 application exposes to the scripting environment. In this scenario, |
|
146 the slots themselves are still written in C++, but the definition of |
|
147 the connections is fully dynamic (script-defined). |
|
148 |
|
149 \i \bold{Purely script-defined}: A script can both define signal |
|
150 handler functions (effectively "slots written in Qt Script"), |
|
151 \e{and} set up the connections that utilize those handlers. For |
|
152 example, a script can define a function that will handle the |
|
153 QLineEdit::returnPressed() signal, and then connect that signal to the |
|
154 script function. |
|
155 \endlist |
|
156 |
|
157 Use the qScriptConnect() function to connect a C++ signal to a |
|
158 script function. In the following example a script signal handler is |
|
159 defined that will handle the QLineEdit::textChanged() signal: |
|
160 |
|
161 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 47 |
|
162 |
|
163 The first two arguments to qScriptConnect() are the same |
|
164 as you would pass to QObject::connect() to establish a normal C++ |
|
165 connection. The third argument is the script object that will act |
|
166 as the \c this object when the signal handler is invoked; in the above |
|
167 example we pass an invalid script value, so the \c this object will |
|
168 be the Global Object. The fourth argument is the script function |
|
169 ("slot") itself. The following example shows how the \c this argument |
|
170 can be put to use: |
|
171 |
|
172 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 48 |
|
173 |
|
174 We create two QLineEdit objects and define a single signal handler |
|
175 function. The connections use the same handler function, but the |
|
176 function will be invoked with a different \c this object depending on |
|
177 which object's signal was triggered, so the output of the print() |
|
178 statement will be different for each. |
|
179 |
|
180 In script code, Qt Script uses a different syntax for connecting to |
|
181 and disconnecting from signals than the familiar C++ syntax; i.e., |
|
182 QObject::connect(). |
|
183 To connect to a signal, you reference the relevant signal as a property |
|
184 of the sender object, and invoke its \c{connect()} function. There |
|
185 are three overloads of \c{connect()}, each with a corresponding |
|
186 \c{disconnect()} overload. The following subsections describe these |
|
187 three forms. |
|
188 |
|
189 \section3 Signal to Function Connections |
|
190 |
|
191 \c{connect(function)} |
|
192 |
|
193 In this form of connection, the argument to \c{connect()} is the |
|
194 function to connect to the signal. |
|
195 |
|
196 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 2 |
|
197 |
|
198 The argument can be a Qt Script function, as in the above |
|
199 example, or it can be a QObject slot, as in |
|
200 the following example: |
|
201 |
|
202 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 3 |
|
203 |
|
204 When the argument is a QObject slot, the argument types of the |
|
205 signal and slot do not necessarily have to be compatible; |
|
206 QtScript will, if necessary, perform conversion of the signal |
|
207 arguments to match the argument types of the slot. |
|
208 |
|
209 To disconnect from a signal, you invoke the signal's |
|
210 \c{disconnect()} function, passing the function to disconnect |
|
211 as argument: |
|
212 |
|
213 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 4 |
|
214 |
|
215 When a script function is invoked in response to a signal, the |
|
216 \c this object will be the Global Object. |
|
217 |
|
218 \section3 Signal to Member Function Connections |
|
219 |
|
220 \c{connect(thisObject, function)} |
|
221 |
|
222 In this form of the \c{connect()} function, the first argument |
|
223 is the object that will be bound to the variable, \c this, when |
|
224 the function specified using the second argument is invoked. |
|
225 |
|
226 If you have a push button in a form, you typically want to do |
|
227 something involving the form in response to the button's |
|
228 \c{clicked} signal; passing the form as the \c this object |
|
229 makes sense in such a case. |
|
230 |
|
231 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 5 |
|
232 |
|
233 To disconnect from the signal, pass the same arguments to \c{disconnect()}: |
|
234 |
|
235 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 6 |
|
236 |
|
237 \section3 Signal to Named Member Function Connections |
|
238 |
|
239 \c{connect(thisObject, functionName)} |
|
240 |
|
241 In this form of the \c{connect()} function, the first argument is |
|
242 the object that will be bound to the variable, \c this, when |
|
243 a function is invoked in response to the signal. The second argument |
|
244 specifies the name of a function that is connected to the signal, |
|
245 and this refers to a member function of the object passed as the |
|
246 first argument (\c thisObject in the above scheme). |
|
247 |
|
248 Note that the function is resolved when the connection is made, not |
|
249 when the signal is emitted. |
|
250 |
|
251 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 7 |
|
252 |
|
253 To disconnect from the signal, pass the same arguments to \c{disconnect()}: |
|
254 |
|
255 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 8 |
|
256 |
|
257 \section3 Error Handling |
|
258 |
|
259 When \c{connect()} or \c{disconnect()} succeeds, the function will |
|
260 return \c{undefined}; otherwise, it will throw a script exception. |
|
261 You can obtain an error message from the resulting \c{Error} object. |
|
262 Example: |
|
263 |
|
264 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 9 |
|
265 |
|
266 \section3 Emitting Signals from Scripts |
|
267 |
|
268 To emit a signal from script code, you simply invoke the signal |
|
269 function, passing the relevant arguments: |
|
270 |
|
271 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 10 |
|
272 |
|
273 It is currently not possible to define a new signal in a script; |
|
274 i.e., all signals must be defined by C++ classes. |
|
275 |
|
276 \section3 Overloaded Signals and Slots |
|
277 |
|
278 When a signal or slot is overloaded, QtScript will attempt to |
|
279 pick the right overload based on the actual types of the QScriptValue arguments |
|
280 involved in the function invocation. For example, if your class has slots |
|
281 \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following |
|
282 script code will behave reasonably: |
|
283 |
|
284 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 11 |
|
285 |
|
286 You can specify a particular overload by using array-style property access |
|
287 with the \l{QMetaObject::normalizedSignature()}{normalized signature} of |
|
288 the C++ function as the property name: |
|
289 |
|
290 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 12 |
|
291 |
|
292 If the overloads have different number of arguments, QtScript will |
|
293 pick the overload with the argument count that best matches the |
|
294 actual number of arguments passed to the slot. |
|
295 |
|
296 For overloaded signals, Qt Script will throw an error if you try to connect |
|
297 to the signal by name; you have to refer to the signal with the full |
|
298 normalized signature of the particular overload you want to connect to. |
|
299 |
|
300 \section2 Accessing Properties |
|
301 |
|
302 The properties of the QObject are available as properties |
|
303 of the corresponding QtScript object. When you manipulate |
|
304 a property in script code, the C++ get/set method for that |
|
305 property will automatically be invoked. For example, if your |
|
306 C++ class has a property declared as follows: |
|
307 |
|
308 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 13 |
|
309 |
|
310 then script code can do things like the following: |
|
311 |
|
312 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 14 |
|
313 |
|
314 \section2 Accessing Child QObjects |
|
315 |
|
316 Every named child of the QObject (that is, for which |
|
317 QObject::objectName() is not an empty string) is by default available as |
|
318 a property of the QtScript wrapper object. For example, |
|
319 if you have a QDialog with a child widget whose \c{objectName} property is |
|
320 \c{"okButton"}, you can access this object in script code through |
|
321 the expression |
|
322 |
|
323 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 15 |
|
324 |
|
325 Since \c{objectName} is itself a Q_PROPERTY, you can manipulate |
|
326 the name in script code to, for example, rename an object: |
|
327 |
|
328 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 16 |
|
329 |
|
330 You can also use the functions \c{findChild()} and \c{findChildren()} |
|
331 to find children. These two functions behave identically to |
|
332 QObject::findChild() and QObject::findChildren(), respectively. |
|
333 |
|
334 For example, we can use these functions to find objects using strings |
|
335 and regular expressions: |
|
336 |
|
337 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 17 |
|
338 |
|
339 You typically want to use \c{findChild()} when manipulating a form |
|
340 that uses nested layouts; that way the script is isolated from the |
|
341 details about which particular layout a widget is located in. |
|
342 |
|
343 \section2 Controlling QObject Ownership |
|
344 |
|
345 Qt Script uses garbage collection to reclaim memory used by script |
|
346 objects when they are no longer needed; an object's memory can be |
|
347 automatically reclaimed when it is no longer referenced anywhere in |
|
348 the scripting environment. Qt Script lets you control what happens |
|
349 to the underlying C++ QObject when the wrapper object is reclaimed |
|
350 (i.e., whether the QObject is deleted or not); you do this when you |
|
351 create an object by passing an ownership mode as the second argument |
|
352 to QScriptEngine::newQObject(). |
|
353 |
|
354 Knowing how Qt Script deals with ownership is important, since it can |
|
355 help you avoid situations where a C++ object isn't deleted when it |
|
356 should be (causing memory leaks), or where a C++ object \e{is} |
|
357 deleted when it shouldn't be (typically causing a crash if C++ code |
|
358 later tries to access that object). |
|
359 |
|
360 \section3 Qt Ownership |
|
361 |
|
362 By default, the script engine does not take ownership of the |
|
363 QObject that is passed to QScriptEngine::newQObject(); the object |
|
364 is managed according to Qt's object ownership (see |
|
365 \l{Object Trees and Object Ownership}). This mode is appropriate |
|
366 when, for example, you are wrapping C++ objects that are part of |
|
367 your application's core; that is, they should persist regardless of |
|
368 what happens in the scripting environment. Another way of stating |
|
369 this is that the C++ objects should outlive the script engine. |
|
370 |
|
371 \section3 Script Ownership |
|
372 |
|
373 Specifying QScriptEngine::ScriptOwnership as the ownership mode |
|
374 will cause the script engine to take full ownership of the QObject |
|
375 and delete it when it determines that it is safe to do so |
|
376 (i.e., when there are no more references to it in script code). |
|
377 This ownership mode is appropriate if the QObject does not have a |
|
378 parent object, and/or the QObject is created in the context of the |
|
379 script engine and is not intended to outlive the script engine. |
|
380 |
|
381 For example, a constructor function that constructs QObjects |
|
382 only to be used in the script environment is a good candidate: |
|
383 |
|
384 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 18 |
|
385 |
|
386 \section3 Auto-Ownership |
|
387 |
|
388 With QScriptEngine::AutoOwnership the ownership is based on whether |
|
389 the QObject has a parent or not. |
|
390 If the QtScript garbage collector finds that the QObject is no |
|
391 longer referenced within the script environment, the QObject will |
|
392 be deleted \e{only} if it does not have a parent. |
|
393 |
|
394 \section3 What Happens When Someone Else Deletes the QObject? |
|
395 |
|
396 It is possible that a wrapped QObject is deleted outside of |
|
397 Qt Script's control; i.e., without regard to the ownership mode |
|
398 specified. In this case, the wrapper object will still |
|
399 be an object (unlike the C++ pointer it wraps, the script object |
|
400 won't become null). Any attempt to access properties of the script |
|
401 object will, however, result in a script exception being thrown. |
|
402 |
|
403 Note that QScriptValue::isQObject() will still return true for a |
|
404 deleted QObject, since it tests the type of the script object, not |
|
405 whether the internal pointer is non-null. In other words, if |
|
406 QScriptValue::isQObject() returns true but QScriptValue::toQObject() |
|
407 returns a null pointer, this indicates that the QObject has been |
|
408 deleted outside of Qt Script (perhaps accidentally). |
|
409 |
|
410 \section2 Customizing Access to the QObject |
|
411 |
|
412 QScriptEngine::newQObject() can take a third argument which allows |
|
413 you to control various aspects of the access to the QObject through |
|
414 the QtScript wrapper object it returns. |
|
415 |
|
416 QScriptEngine::ExcludeChildObjects specifies that child objects of |
|
417 the QObject should not appear as properties of the wrapper object. |
|
418 |
|
419 QScriptEngine::ExcludeSuperClassProperties and |
|
420 QScriptEngine::ExcludeSuperClassMethods can be used to avoid |
|
421 exposing members that are inherited from the QObject's superclass. |
|
422 This is useful for defining a "pure" interface where inherited members |
|
423 don't make sense from a scripting perspective; e.g., you don't want |
|
424 script authors to be able to change the \c{objectName} property of |
|
425 the object or invoke the \c{deleteLater()} slot. |
|
426 |
|
427 QScriptEngine::AutoCreateDynamicProperties specifies that properties |
|
428 that don't already exist in the QObject should be created as dynamic |
|
429 properties of the QObject, rather than as properties of the QtScript |
|
430 wrapper object. If you want new properties to truly become persistent |
|
431 properties of the QObject, rather than properties that are destroyed |
|
432 along with the wrapper object (and that aren't shared if the QObject |
|
433 is wrapped multiple times with QScriptEngine::newQObject()), you |
|
434 should use this option. |
|
435 |
|
436 QScriptEngine::SkipMethodsInEnumeration specifies that signals and |
|
437 slots should be skipped when enumerating the properties of the QObject |
|
438 wrapper in a for-in script statement. This is useful when defining |
|
439 prototype objects, since by convention function properties of |
|
440 prototypes should not be enumerable. |
|
441 |
|
442 \section2 Making a QObject-based Class New-able from a Script |
|
443 |
|
444 The QScriptEngine::newQObject() function is used to wrap an |
|
445 existing QObject instance, so that it can be made available to |
|
446 scripts. A different scenario is that you want scripts to be |
|
447 able to construct new objects, not just access existing ones. |
|
448 |
|
449 The Qt meta-type system currently does not provide dynamic |
|
450 binding of constructors for QObject-based classes. If you want to |
|
451 make such a class new-able from scripts, Qt Script can generate |
|
452 a reasonable script constructor for you; see |
|
453 QScriptEngine::scriptValueFromQMetaObject(). |
|
454 |
|
455 You can also use QScriptEngine::newFunction() to wrap your own |
|
456 factory function, and add it to the script environment; see |
|
457 QScriptEngine::newQMetaObject() for an example. |
|
458 |
|
459 \section2 Enum Values |
|
460 |
|
461 Values for enums declared with Q_ENUMS are not available as |
|
462 properties of individual wrapper objects; rather, they are |
|
463 properties of the QMetaObject wrapper object that can be created |
|
464 with QScriptEngine::newQMetaObject(). |
|
465 |
|
466 \section1 Conversion Between QtScript and C++ Types |
|
467 |
|
468 QtScript will perform type conversion when a value needs to be |
|
469 converted from the script side to the C++ side or vice versa; for |
|
470 instance, when a C++ signal triggers a script function, when |
|
471 you access a QObject property in script code, or when |
|
472 you call QScriptEngine::toScriptValue() or |
|
473 QScriptEngine::fromScriptValue() in C++. QtScript provides default |
|
474 conversion operations for many of the built-in Qt types. You can |
|
475 change the conversion operation for a type (including your custom |
|
476 C++ types) by registering your own conversion functions with |
|
477 qScriptRegisterMetaType(). |
|
478 |
|
479 \section2 Default Conversion from Qt Script to C++ |
|
480 |
|
481 The following table describes the default conversion from a |
|
482 QScriptValue to a C++ type. |
|
483 |
|
484 \table 80% |
|
485 \header \o C++ Type \o Default Conversion |
|
486 \row \o bool \o QScriptValue::toBool() |
|
487 \row \o int \o QScriptValue::toInt32() |
|
488 \row \o uint \o QScriptValue::toUInt32() |
|
489 \row \o float \o float(QScriptValue::toNumber()) |
|
490 \row \o double \o QScriptValue::toNumber() |
|
491 \row \o short \o short(QScriptValue::toInt32()) |
|
492 \row \o ushort \o QScriptValue::toUInt16() |
|
493 \row \o char \o char(QScriptValue::toInt32()) |
|
494 \row \o uchar \o unsigned char(QScriptValue::toInt32()) |
|
495 \row \o qlonglong \o qlonglong(QScriptValue::toInteger()) |
|
496 \row \o qulonglong \o qulonglong(QScriptValue::toInteger()) |
|
497 \row \o QString \o An empty string if the QScriptValue is null |
|
498 or undefined; QScriptValue::toString() otherwise. |
|
499 \row \o QDateTime \o QScriptValue::toDateTime() |
|
500 \row \o QDate \o QScriptValue::toDateTime().date() |
|
501 \row \o QRegExp \o QScriptValue::toRegExp() |
|
502 \row \o QObject* \o QScriptValue::toQObject() |
|
503 \row \o QWidget* \o QScriptValue::toQObject() |
|
504 \row \o QVariant \o QScriptValue::toVariant() |
|
505 \row \o QChar \o If the QScriptValue is a string, the result |
|
506 is the first character of the string, or a null QChar |
|
507 if the string is empty; otherwise, the result is a QChar |
|
508 constructed from the unicode obtained by converting the |
|
509 QScriptValue to a \c{ushort}. |
|
510 \row \o QStringList \o If the QScriptValue is an array, the |
|
511 result is a QStringList constructed from the result of |
|
512 QScriptValue::toString() for each array element; otherwise, |
|
513 the result is an empty QStringList. |
|
514 \row \o QVariantList \o If the QScriptValue is an array, the result |
|
515 is a QVariantList constructed from the result of |
|
516 QScriptValue::toVariant() for each array element; otherwise, |
|
517 the result is an empty QVariantList. |
|
518 \row \o QVariantMap \o If the QScriptValue is an object, the result |
|
519 is a QVariantMap with a (key, value) pair of the form |
|
520 (propertyName, propertyValue.toVariant()) for each property, |
|
521 using QScriptValueIterator to iterate over the object's |
|
522 properties. |
|
523 \row \o QObjectList \o If the QScriptValue is an array, the result |
|
524 is a QObjectList constructed from the result of |
|
525 QScriptValue::toQObject() for each array element; otherwise, |
|
526 the result is an empty QObjectList. |
|
527 \row \o QList<int> \o If the QScriptValue is an array, the result is |
|
528 a QList<int> constructed from the result of |
|
529 QScriptValue::toInt32() for each array element; otherwise, |
|
530 the result is an empty QList<int>. |
|
531 \endtable |
|
532 |
|
533 Additionally, QtScript will handle the following cases: |
|
534 |
|
535 \list |
|
536 \i If the QScriptValue is a QObject and the target type name ends with |
|
537 \c * (i.e., it is a pointer), the QObject pointer will be cast to the |
|
538 target type with qobject_cast(). |
|
539 \i If the QScriptValue is a QVariant and the target type name ends with |
|
540 \c * (i.e., it is a pointer), and the \l{QVariant::userType()}{userType()} |
|
541 of the QVariant is the type that the target type points to, the result |
|
542 is a pointer to the QVariant's data. |
|
543 \i If the QScriptValue is a QVariant and it can be converted to the |
|
544 target type (according to QVariant::canConvert()), the QVariant will |
|
545 be cast to the target type with qvariant_cast(). |
|
546 \endlist |
|
547 |
|
548 \section2 Default Conversion from C++ to Qt Script |
|
549 |
|
550 The following table describes the default behavior when a QScriptValue is |
|
551 constructed from a C++ type: |
|
552 |
|
553 \table 80% |
|
554 \header \o C++ Type \o Default Construction |
|
555 \row \o void \o QScriptEngine::undefinedValue() |
|
556 \row \o bool \o QScriptValue(engine, value) |
|
557 \row \o int \o QScriptValue(engine, value) |
|
558 \row \o uint \o QScriptValue(engine, value) |
|
559 \row \o float \o QScriptValue(engine, value) |
|
560 \row \o double \o QScriptValue(engine, value) |
|
561 \row \o short \o QScriptValue(engine, value) |
|
562 \row \o ushort \o QScriptValue(engine, value) |
|
563 \row \o char \o QScriptValue(engine, value) |
|
564 \row \o uchar \o QScriptValue(engine, value) |
|
565 \row \o QString \o QScriptValue(engine, value) |
|
566 \row \o qlonglong \o QScriptValue(engine, qsreal(value)). Note that |
|
567 the conversion may lead to loss of precision, since not all |
|
568 64-bit integers can be represented using the qsreal type. |
|
569 \row \o qulonglong \o QScriptValue(engine, qsreal(value)). Note that |
|
570 the conversion may lead to loss of precision, since not all |
|
571 64-bit unsigned integers can be represented using the qsreal |
|
572 type. |
|
573 \row \o QChar \o QScriptValue(this, value.unicode()) |
|
574 \row \o QDateTime \o \l{QScriptEngine::newDate()}{QScriptEngine::newDate}(value) |
|
575 \row \o QDate \o \l{QScriptEngine::newDate()}{QScriptEngine::newDate}(value) |
|
576 \row \o QRegExp \o \l{QScriptEngine::newRegExp()}{QScriptEngine::newRegExp}(value) |
|
577 \row \o QObject* \o \l{QScriptEngine::newQObject()}{QScriptEngine::newQObject}(value) |
|
578 \row \o QWidget* \o \l{QScriptEngine::newQObject()}{QScriptEngine::newQObject}(value) |
|
579 \row \o QVariant \o \l{QScriptEngine::newVariant()}{QScriptEngine::newVariant}(value) |
|
580 \row \o QStringList \o A new script array (created with |
|
581 QScriptEngine::newArray()), whose elements are created using |
|
582 the QScriptValue(QScriptEngine *, QString) constructor for |
|
583 each element of the list. |
|
584 \row \o QVariantList \o A new script array (created with |
|
585 QScriptEngine::newArray()), whose elements are created using |
|
586 QScriptEngine::newVariant() for each element of the list. |
|
587 \row \o QVariantMap \o A new script object (created with |
|
588 QScriptEngine::newObject()), whose properties are initialized |
|
589 according to the (key, value) pairs of the map. |
|
590 \row \o QObjectList \o A new script array (created with |
|
591 QScriptEngine::newArray()), whose elements are created using |
|
592 QScriptEngine::newQObject() for each element of the list. |
|
593 \row \o QList<int> \o A new script array (created with |
|
594 QScriptEngine::newArray()), whose elements are created using |
|
595 the QScriptValue(QScriptEngine *, int) constructor for each |
|
596 element of the list. |
|
597 \endtable |
|
598 |
|
599 Other types (including custom types) will be wrapped using |
|
600 QScriptEngine::newVariant(). For null pointers of any type, the |
|
601 result is QScriptEngine::nullValue(). |
|
602 |
|
603 \section1 How to Design and Implement Application Objects |
|
604 |
|
605 This section explains how to implement application objects and |
|
606 provides the necessary technical background material. |
|
607 |
|
608 \section2 Making a C++ object available to Scripts Written in QtScript |
|
609 |
|
610 Making C++ classes and objects available to a scripting language is |
|
611 not trivial because scripting languages tend to be more dynamic than |
|
612 C++, and it must be possible to introspect objects (query information |
|
613 such as function names, function signatures, properties, etc., at |
|
614 run-time). Standard C++ does not provide features for this. |
|
615 |
|
616 We can achieve the functionality we want by extending C++, using |
|
617 C++'s own facilities so our code is still standard C++. The Qt |
|
618 meta-object system provides the necessary additional functionality. |
|
619 It allows us to write using an extended C++ syntax, but converts this |
|
620 into standard C++ using a small utility program called \l{moc} |
|
621 (Meta-Object Compiler). Classes that wish to take advantage of the |
|
622 meta-object facilities are either subclasses of QObject, or use the |
|
623 \c{Q_OBJECT} macro. Qt has used this approach for many years and it has |
|
624 proven to be solid and reliable. QtScript uses this meta-object |
|
625 technology to provide scripters with dynamic access to C++ classes |
|
626 and objects. |
|
627 |
|
628 To completely understand how to make C++ objects available to Qt |
|
629 Script, some basic knowledge of the Qt meta-object system is very |
|
630 helpful. We recommend that you read the \l{Qt Object Model}. The |
|
631 information in this document and the documents it links to are very |
|
632 useful for understanding how to implement application objects. |
|
633 |
|
634 However, this knowledge is not essential in the simplest cases. |
|
635 To make an object available in QtScript, it must derive from |
|
636 QObject. All classes which derive from QObject can be introspected |
|
637 and can provide the information needed by the scripting engine at |
|
638 run-time; e.g., class name, functions, signatures. Because we obtain |
|
639 the information we need about classes dynamically at run-time, there |
|
640 is no need to write wrappers for QObject derived classes. |
|
641 |
|
642 \section2 Making C++ Class Member Functions Available in QtScript |
|
643 |
|
644 The meta-object system also makes information about signals and slots |
|
645 dynamically available at run-time. By default, for QObject subclasses, |
|
646 only the signals and slots are automatically made available to scripts. |
|
647 This is very convenient because, in practice, we normally only want to |
|
648 make specially chosen functions available to scripters. When you create |
|
649 a QObject subclass, make sure that the functions you want to expose to |
|
650 QtScript are public slots. |
|
651 |
|
652 For example, the following class definition enables scripting only for |
|
653 certain functions: |
|
654 |
|
655 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 19 |
|
656 |
|
657 In the example above, aNonScriptableFunction() is not declared as a |
|
658 slot, so it will not be available in QtScript. The other three |
|
659 functions will automatically be made available in QtScript because |
|
660 they are declared in the \c{public slots} section of the class |
|
661 definition. |
|
662 |
|
663 It is possible to make any function script-invokable by specifying |
|
664 the \c{Q_INVOKABLE} modifier when declaring the function: |
|
665 |
|
666 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 20 |
|
667 |
|
668 Once declared with \c{Q_INVOKABLE}, the method can be invoked from |
|
669 QtScript code just as if it were a slot. Although such a method is |
|
670 not a slot, you can still specify it as the target function in a |
|
671 call to \c{connect()} in script code; \c{connect()} accepts both |
|
672 native and non-native functions as targets. |
|
673 |
|
674 \section2 Making C++ Class Properties Available in QtScript |
|
675 |
|
676 In the previous example, if we wanted to get or set a property using |
|
677 QtScript we would have to write code like the following: |
|
678 |
|
679 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 21 |
|
680 |
|
681 Scripting languages often provide a property syntax to modify and |
|
682 retrieve properties (in our case the enabled state) of an |
|
683 object. Many script programmers would want to write the above code |
|
684 like this: |
|
685 |
|
686 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 22 |
|
687 |
|
688 To make this possible, you must define properties in the C++ QObject |
|
689 subclass. For example, the following \c MyObject class declaration |
|
690 declares a boolean property called \c enabled, which uses the function |
|
691 \c{setEnabled(bool)} as its setter function and \c{isEnabled()} as its |
|
692 getter function: |
|
693 |
|
694 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 23 |
|
695 |
|
696 The only difference from the original code is the use of the macro |
|
697 \c{Q_PROPERTY}, which takes the type and name of the property, and |
|
698 the names of the setter and getter functions as arguments. |
|
699 |
|
700 If you don't want a property of your class to be accessible in |
|
701 QtScript, you set the \c{SCRIPTABLE} attribute to \c false when |
|
702 declaring the property; by default, the \c{SCRIPTABLE} attribute is |
|
703 \c true. For example: |
|
704 |
|
705 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 24 |
|
706 |
|
707 \section2 Reacting to C++ Objects Signals in Scripts |
|
708 |
|
709 In the Qt object model, signals are used as a notification mechanism |
|
710 between QObjects. This means one object can connect a signal to |
|
711 another object's slot and, every time the signal is emitted, the slot |
|
712 is called. This connection is established using the QObject::connect() |
|
713 function. |
|
714 |
|
715 The signals and slots mechanism is also available to QtScript |
|
716 programmers. The code to declare a signal in C++ is the same, |
|
717 regardless of whether the signal will be connected to a slot in C++ |
|
718 or in QtScript. |
|
719 |
|
720 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 25 |
|
721 |
|
722 The only change we have made to the code in the previous section is |
|
723 to declare a signals section with the relevant signal. Now, the |
|
724 script writer can define a function and connect to the object like |
|
725 this: |
|
726 |
|
727 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 26 |
|
728 |
|
729 \section2 Design of Application Objects |
|
730 |
|
731 The previous section described how to implement C++ objects which |
|
732 can be used in QtScript. Application objects are the same kind of |
|
733 objects, and they make your application's functionality available to |
|
734 QtScript scripters. Since the C++ application is already written |
|
735 in Qt, many objects are already QObjects. The easiest approach would |
|
736 be to simply add all these QObjects as application objects to the |
|
737 scripting engine. For small applications this might be sufficient, |
|
738 but for larger applications this is probably not the right |
|
739 approach. The problem is that this method reveals too much of the |
|
740 internal API and gives script programmers access to application |
|
741 internals which should not be exposed. |
|
742 |
|
743 Generally, the best way of making application functionality available |
|
744 to scripters is to code some QObjects which define the applications |
|
745 public API using signals, slots, and properties. This gives you |
|
746 complete control of the functionality made available by the |
|
747 application. The implementations of these objects simply call the |
|
748 functions in the application which do the real work. So, instead of |
|
749 making all your QObjects available to the scripting engine, just add |
|
750 the wrapper QObjects. |
|
751 |
|
752 \section3 Returning QObject Pointers |
|
753 |
|
754 If you have a slot that returns a QObject pointer, you should note |
|
755 that, by default, Qt Script only handles conversion of the types |
|
756 QObject* and QWidget*. This means that if your slot is declared |
|
757 with a signature like "MyObject* getMyObject()", QtScript doesn't |
|
758 automatically know that MyObject* should be handled in the same way |
|
759 as QObject* and QWidget*. The simplest way to solve this is to only |
|
760 use QObject* and QWidget* in the method signatures of your scripting |
|
761 interface. |
|
762 |
|
763 Alternatively, you can register conversion functions for your custom |
|
764 type with the qScriptRegisterMetaType() function. In this way, you |
|
765 can preserve the precise typing in your C++ declarations, while |
|
766 still allowing pointers to your custom objects to flow seamlessly |
|
767 between C++ and scripts. Example: |
|
768 |
|
769 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 43 |
|
770 |
|
771 \section1 Function Objects and Native Functions |
|
772 |
|
773 In Qt Script, functions are first-class values; they are objects that |
|
774 can have properties of their own, just like any other type of |
|
775 object. They can be stored in variables and passed as arguments to |
|
776 other functions. Knowing how function calls in Qt Script behave is |
|
777 useful when you want to define and use your own script functions. |
|
778 This section discusses this matter, and also explains how you can |
|
779 implement native functions; that is, Qt Script functions written in |
|
780 C++, as opposed to functions written in the scripting language |
|
781 itself. Even if you will be relying mostly on the dynamic QObject |
|
782 binding that Qt Script provides, knowing about these powerful |
|
783 concepts and techniques is important to understand what's actually |
|
784 going on when script functions are executed. |
|
785 |
|
786 \section2 Calling a Qt Script Function from C++ |
|
787 |
|
788 Calling a Qt Script function from C++ is achieved with the |
|
789 QScriptValue::call() function. A typical scenario is that you evaluate a |
|
790 script that defines a function, and at some point you want to call that |
|
791 function from C++, perhaps passing it some arguments, and then handle the |
|
792 result. The following script defines a Qt Script object that has a |
|
793 toKelvin() function: |
|
794 |
|
795 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 90 |
|
796 |
|
797 The toKelvin() function takes a temperature in Kelvin as argument, and |
|
798 returns the temperature converted to Celsius. The following snippet shows |
|
799 how the toKelvin() function might be obtained and called from C++: |
|
800 |
|
801 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 91 |
|
802 |
|
803 If a script defines a global function, you can access the function as a |
|
804 property of QScriptEngine::globalObject(). For example, the following script |
|
805 defines a global function add(): |
|
806 |
|
807 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 56 |
|
808 |
|
809 C++ code might call the add() function as follows: |
|
810 |
|
811 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 92 |
|
812 |
|
813 As already mentioned, functions are just values in Qt Script; a function by |
|
814 itself is not "tied to" a particular object. This is why you have to specify |
|
815 a \c{this} object (the first argument to QScriptValue::call()) that the |
|
816 function should be applied to. |
|
817 |
|
818 If the function is supposed to act as a method (i.e. it can only be applied |
|
819 to a certain class of objects), it is up to the function itself to check |
|
820 that it is being called with a compatible \c{this} object. |
|
821 |
|
822 Passing an invalid QScriptValue as the \c{this} argument to |
|
823 QScriptValue::call() indicates that the Global Object should be used as the |
|
824 \c{this} object; in other words, that the function should be invoked as a |
|
825 global function. |
|
826 |
|
827 \section2 The \c this Object |
|
828 |
|
829 When a Qt Script function is invoked from a script, the \e{way} in which it |
|
830 is invoked determines the \c this object when the function body is executed, |
|
831 as the following script example illustrates: |
|
832 |
|
833 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 49 |
|
834 |
|
835 An important thing to note is that in Qt Script, unlike C++ and Java, the |
|
836 \c this object is not part of the execution scope. This means that |
|
837 member functions (i.e., functions that operate on \c this) must always |
|
838 use the \c this keyword to access the object's properties. For example, |
|
839 the following script probably doesn't do what you want: |
|
840 |
|
841 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 50 |
|
842 |
|
843 You will get a reference error saying that 'a is not defined' or, worse, |
|
844 two totally unrelated global variables \c a and \c b will be used to |
|
845 perform the computation, if they exist. Instead, the script should look |
|
846 like this: |
|
847 |
|
848 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 51 |
|
849 |
|
850 Accidentally omitting the \c this keyword is a typical source of |
|
851 error for programmers who are used to the scoping rules of C++ and Java. |
|
852 |
|
853 \section2 Wrapping a Native Function |
|
854 |
|
855 Qt Script provides QScriptEngine::newFunction() as a way of wrapping a |
|
856 C++ function pointer; this enables you to implement a function in |
|
857 C++ and add it to the script environment, so that scripts can invoke |
|
858 your function as if it were a "normal" script function. Here is how the |
|
859 previous \c{getProperty()} function can be written in C++: |
|
860 |
|
861 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 52 |
|
862 |
|
863 Call QScriptEngine::newFunction() to wrap the function. This will |
|
864 produce a special type of function object that carries a pointer to |
|
865 the C++ function internally. Once the resulting wrapper has been |
|
866 added to the scripting environment (e.g., by setting it as a property |
|
867 of the Global Object), scripts can call the function without having |
|
868 to know nor care that it is, in fact, a native function. |
|
869 |
|
870 Note that the name of the C++ function doesn't matter in the |
|
871 scripting sense; the name by which the function is invoked by |
|
872 scripts depends only on what you call the script object property |
|
873 in which you store the function wrapper. |
|
874 |
|
875 It is currently not possible to wrap member functions; i.e., methods |
|
876 of a C++ class that require a \c this object. |
|
877 |
|
878 \section2 The QScriptContext Object |
|
879 |
|
880 A QScriptContext holds all the state associated with a particular |
|
881 invocation of your function. Through the QScriptContext, you can: |
|
882 \list |
|
883 \i Get the arguments that were passed to the function. |
|
884 \i Get the \c this object. |
|
885 \i Find out whether the function was called with the \c new operator |
|
886 (the significance of this will be explained later). |
|
887 \i Throw a script error. |
|
888 \i Get the function object that's being invoked. |
|
889 \i Get the activation object (the object used to hold local variables). |
|
890 \endlist |
|
891 |
|
892 The following sections explain how to make use of this |
|
893 functionality. |
|
894 |
|
895 \section2 Processing Function Arguments |
|
896 |
|
897 Two things are worth noting about function arguments: |
|
898 |
|
899 \list 1 |
|
900 \o Any script function \mdash including native functions \mdash can |
|
901 be invoked with any number of arguments. This means that it is up to |
|
902 the function itself to check the argument count if necessary, and act |
|
903 accordingly (e.g., throw an error if the number of arguments is |
|
904 too large, or prepare a default value if the number is too small). |
|
905 \o A value of any type can be supplied as an argument to any |
|
906 function. This means that it is up to you to check the type of the |
|
907 arguments if necessary, and act accordingly (e.g., throw an error |
|
908 if an argument is not an object of a certain type). |
|
909 \endlist |
|
910 |
|
911 In summary: Qt Script does not automatically enforce any constraints on the |
|
912 number or type of arguments involved in a function call. |
|
913 |
|
914 \section3 Formal Parameters and the Arguments Object |
|
915 |
|
916 A native Qt Script function is analogous to a script function that defines no |
|
917 formal parameters and only uses the built-in \c arguments variable to |
|
918 process its arguments. To see this, let's first consider how a |
|
919 script would normally define an \c{add()} function that takes two |
|
920 arguments, adds them together and returns the result: |
|
921 |
|
922 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 56 |
|
923 |
|
924 When a script function is defined with formal parameters, their |
|
925 names can be viewed as mere aliases of properties of the \c |
|
926 arguments object; for example, in the \c{add(a, b)} definition's |
|
927 function body, \c a and \c arguments[0] refer to the same |
|
928 variable. This means that the \c{add()} function can equivalently be |
|
929 written like this: |
|
930 |
|
931 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 57 |
|
932 |
|
933 This latter form closely matches what a native implementation |
|
934 typically looks like: |
|
935 |
|
936 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 58 |
|
937 |
|
938 \section3 Checking the Number of Arguments |
|
939 |
|
940 Again, remember that the presence (or lack) of formal parameter |
|
941 names in a function definition does not affect how the function |
|
942 may be invoked; \c{add(1, 2, 3)} is allowed by the engine, as is |
|
943 \c{add(42)}. In the case of the \c {add()} function, the function |
|
944 really needs two arguments in order to do something useful. This |
|
945 can be expressed by the script definition as follows: |
|
946 |
|
947 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 59 |
|
948 |
|
949 This would result in an error being thrown if a script invokes |
|
950 \c{add()} with anything other than two arguments. The native |
|
951 function can be modified to perform the same check: |
|
952 |
|
953 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 62 |
|
954 |
|
955 \section3 Checking the Types of Arguments |
|
956 |
|
957 In addition to expecting a certain number of arguments, a function might |
|
958 expect that those arguments are of certain types (e.g., that the first |
|
959 argument is a number and that the second is a string). Such a function |
|
960 should explicitly check the type of arguments and/or perform a conversion, |
|
961 or throw an error if the type of an argument is incompatible. |
|
962 |
|
963 As it is, the native implementation of \c{add()} shown above doesn't |
|
964 have the exact same semantics as the script counterpart; this is |
|
965 because the behavior of the Qt Script \c{+} operator depends on the |
|
966 types of its operands (for example, if one of the operands is a string, |
|
967 string concatenation is performed). To give the script function |
|
968 stricter semantics (namely, that it should only add numeric |
|
969 operands), the argument types can be tested: |
|
970 |
|
971 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 60 |
|
972 |
|
973 Then an invocation like \c{add("foo", new Array())} will |
|
974 cause an error to be thrown. |
|
975 |
|
976 The C++ version can call QScriptValue::isNumber() to perform similar |
|
977 tests: |
|
978 |
|
979 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 63 |
|
980 |
|
981 A less strict script implementation might settle for performing an |
|
982 explicit to-number conversion before applying the \c{+} operator: |
|
983 |
|
984 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 61 |
|
985 |
|
986 In a native implementation, this is equivalent to calling |
|
987 QScriptValue::toNumber() without performing any type test first, |
|
988 since QScriptValue::toNumber() will automatically perform a type |
|
989 conversion if necessary. |
|
990 |
|
991 To check if an argument is of a certain object type (class), |
|
992 scripts can use the \c instanceof operator (e.g., \c{"arguments[0] |
|
993 instanceof Array"} evaluates to true if the first argument is an |
|
994 Array object); native functions can call QScriptValue::instanceOf(). |
|
995 |
|
996 To check if an argument is of a custom C++ type, you typically use |
|
997 qscriptvalue_cast() and check if the result is valid. For object types, |
|
998 this means casting to a pointer and checking if it is non-zero; for |
|
999 value types, the class should have an \c{isNull()}, \c{isValid()} |
|
1000 or similar method. Alternatively, since most custom types are |
|
1001 transported in \l{QVariant}s, you can check if the script value is a |
|
1002 QVariant using QScriptValue::isVariant(), and then check if the |
|
1003 QVariant can be converted to your type using QVariant::canConvert(). |
|
1004 |
|
1005 \section3 Functions with Variable Numbers of Arguments |
|
1006 |
|
1007 Because of the presence of the built-in \c arguments object, |
|
1008 implementing functions that take a variable number of arguments |
|
1009 is simple. In fact, as we have seen, in the technical sense \e{all} |
|
1010 Qt Script functions can be seen as variable-argument functions). |
|
1011 As an example, consider a concat() function that takes an arbitrary |
|
1012 number of arguments, converts the arguments to their string |
|
1013 representation and concatenates the results; for example, |
|
1014 \c{concat("Qt", " ", "Script ", 101)} would return "Qt Script 101". |
|
1015 A script definition of \c{concat()} might look like this: |
|
1016 |
|
1017 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 64 |
|
1018 |
|
1019 Here is an equivalent native implementation: |
|
1020 |
|
1021 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 65 |
|
1022 |
|
1023 A second use case for a variable number of arguments is to implement |
|
1024 optional arguments. Here's how a script definition typically does |
|
1025 it: |
|
1026 |
|
1027 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 66 |
|
1028 |
|
1029 And here's the native equivalent: |
|
1030 |
|
1031 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 67 |
|
1032 |
|
1033 A third use case for a variable number of arguments is to simulate |
|
1034 C++ overloads. This involves checking the number of arguments and/or |
|
1035 their type at the beginning of the function body (as already shown), |
|
1036 and acting accordingly. It might be worth thinking twice before |
|
1037 doing this, and instead favor unique function names; e.g., having |
|
1038 separate \c{processNumber(number)} and \c{processString(string)} |
|
1039 functions rather than a generic \c{process(anything)} function. |
|
1040 On the caller side, this makes it harder for scripts to accidentally |
|
1041 call the wrong overload (since they don't know or don't comprehend |
|
1042 your custom sophisticated overloading resolution rules), and on the |
|
1043 callee side, you avoid the need for potentially complex (read: |
|
1044 error-prone) checks to resolve ambiguity. |
|
1045 |
|
1046 \section3 Accessing the Arguments Object |
|
1047 |
|
1048 Most native functions use the QScriptContext::argument() function to |
|
1049 access function arguments. However, it is also possible to access |
|
1050 the built-in \c arguments object itself (the one referred to by the |
|
1051 \c arguments variable in script code), by calling the |
|
1052 QScriptContext::argumentsObject() function. This has three principal |
|
1053 applications: |
|
1054 |
|
1055 \list |
|
1056 \o The \c arguments object can be used to easily forward a function |
|
1057 call to another function. In script code, this is what it |
|
1058 typically looks like: |
|
1059 |
|
1060 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 68 |
|
1061 |
|
1062 For example, \c{foo(10, 20, 30)} would result in the \c{foo()} function |
|
1063 executing the equivalent of \c{bar(10, 20, 30)}. This is useful if |
|
1064 you want to perform some special pre- or post-processing when |
|
1065 calling a function (e.g., to log the call to \c{bar()} without having |
|
1066 to modify the \c{bar()} function itself, like the above example), or if |
|
1067 you want to call a "base implementation" from a prototype |
|
1068 function that has the exact same "signature". In C++, the forwarding |
|
1069 function might look like this: |
|
1070 |
|
1071 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 69 |
|
1072 |
|
1073 \o The arguments object can serve as input to a QScriptValueIterator, |
|
1074 providing a generic way to iterate over the arguments. A debugger |
|
1075 might use this to display the arguments object in a general purpose |
|
1076 "Qt Script Object Explorer", for example. |
|
1077 |
|
1078 \o The arguments object can be serialized (e.g., with JSON) and transferred |
|
1079 to another entity (e.g., a script engine running in another thread), |
|
1080 where the object can be deserialized and passed as argument to |
|
1081 another script function. |
|
1082 \endlist |
|
1083 |
|
1084 \section2 Constructor Functions |
|
1085 |
|
1086 Some script functions are constructors; they are expected to initialize |
|
1087 new objects. The following snippet is a small example: |
|
1088 |
|
1089 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 75 |
|
1090 |
|
1091 There is nothing special about constructor functions. In fact, any |
|
1092 script function can act as a constructor function (i.e., any function |
|
1093 can serve as the operand to \c{new}). Some functions behave differently |
|
1094 depending on whether they are called as part of a \c{new} expression |
|
1095 or not; for example, the expression \c{new Number(1)} will create a |
|
1096 Number object, whereas \c{Number("123")} will perform a type |
|
1097 conversion. Other functions, like \c{Array()}, will always create |
|
1098 and initialize a new object (e.g., \c{new Array()} and \c{Array()} have |
|
1099 the same effect). |
|
1100 |
|
1101 A native Qt Script function can call the |
|
1102 QScriptContext::isCalledAsConstructor() function to determine if it |
|
1103 is being called as a constructor or as a regular function. When a |
|
1104 function is called as a constructor (i.e., it is the operand in a |
|
1105 \c{new} expression), this has two important implications: |
|
1106 |
|
1107 \list |
|
1108 \i The \c this object, QScriptContext::thisObject(), contains |
|
1109 the new object to be initialized; the engine creates this |
|
1110 new object automatically before invoking your function. This means |
|
1111 that your native constructor function normally doesn't have to (and |
|
1112 shouldn't) create a new object when it is called as a |
|
1113 constructor, since the engine has already prepared a new |
|
1114 object. Instead your function should operate on the supplied |
|
1115 \c this object. |
|
1116 \i The constructor function should return an undefined value, |
|
1117 QScriptEngine::undefinedValue(), to tell the engine that the |
|
1118 \c this object should be the final result of the \c new |
|
1119 operator. Alternatively, the function can return the \c this |
|
1120 object itself. |
|
1121 \endlist |
|
1122 |
|
1123 When QScriptContext::isCalledAsConstructor() returns false, how your |
|
1124 constructor handles this case depends on what behavior you desire. |
|
1125 If, like the built-in \c{Number()} function, a plain function call should |
|
1126 perform a type conversion of its argument, then you perform the conversion |
|
1127 and return the result. If, on the other hand, you want your constructor |
|
1128 to behave \e{as if it was called as a constructor} (with |
|
1129 \c{new}), you have to explicitly create a new object (that is, |
|
1130 ignore the \c this object), initialize that object, and return it. |
|
1131 |
|
1132 The following example implements a constructor function that always |
|
1133 creates and initializes a new object: |
|
1134 |
|
1135 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 76 |
|
1136 |
|
1137 Given this constructor, scripts would be able to use either the |
|
1138 expression \c{new Person("Bob")} or \c{Person("Bob")} to create a |
|
1139 new \c{Person} object; both behave in the same way. |
|
1140 |
|
1141 There is no equivalent way for a function defined in script |
|
1142 code to determine whether or not it was invoked as a constructor. |
|
1143 |
|
1144 Note that, even though it is not considered good practice, there is |
|
1145 nothing that stops you from choosing to ignore the default |
|
1146 constructed (\c this) object when your function is called as a |
|
1147 constructor and creating your own object anyway; simply have the |
|
1148 constructor return that object. The object will "override" the |
|
1149 default object that the engine constructed (i.e., the default |
|
1150 object will simply be discarded internally). |
|
1151 |
|
1152 \section2 Associating Data with a Function |
|
1153 |
|
1154 Even if a function is global \mdash i.e., not associated with any particular |
|
1155 (type of) object \mdash you might still want to associate some data with it, |
|
1156 so that it becomes self-contained; for example, the function could have |
|
1157 a pointer to some C++ resource that it needs to access. If your application |
|
1158 only uses a single script engine, or the same C++ resource can/should be |
|
1159 shared among all script engines, you can simply use a static C++ variable |
|
1160 and access it from within the native Qt Script function. |
|
1161 |
|
1162 In the case where a static C++ variable or singleton class is |
|
1163 not appropriate, you can call QScriptValue::setProperty() on the |
|
1164 function object, but be aware that those properties will also be |
|
1165 accessible to script code. The alternative is to use QScriptValue::setData(); |
|
1166 this data is not script-accessible. The implementation can access this |
|
1167 internal data through the QScriptContext::callee() function, which |
|
1168 returns the function object being invoked. The following example |
|
1169 shows how this might be used: |
|
1170 |
|
1171 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 55 |
|
1172 |
|
1173 \section2 Native Functions as Arguments to Functions |
|
1174 |
|
1175 As previously mentioned, a function object can be passed as argument |
|
1176 to another function; this is also true for native functions, |
|
1177 naturally. As an example, here's a native comparison function |
|
1178 that compares its two arguments numerically: |
|
1179 |
|
1180 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 53 |
|
1181 |
|
1182 The above function can be passed as argument to the standard |
|
1183 \c{Array.prototype.sort} function to sort an array numerically, |
|
1184 as the following C++ code illustrates: |
|
1185 |
|
1186 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 54 |
|
1187 |
|
1188 Note that, in this case, we are truly treating the native function |
|
1189 object as a value \mdash i.e., we don't store it as a property of the |
|
1190 scripting environment \mdash we simply pass it on as an "anonymous" |
|
1191 argument to another script function and then forget about it. |
|
1192 |
|
1193 \section2 The Activation Object |
|
1194 |
|
1195 Every Qt Script function invocation has an \e{activation object} |
|
1196 associated with it; this object is accessible through the |
|
1197 QScriptContext::activationObject() function. The activation object |
|
1198 is a script object whose properties are the local variables |
|
1199 associated with the invocation (including the arguments for which |
|
1200 the script function has a corresponding formal parameter name). |
|
1201 Thus, getting, modifying, creating and deleting local variables |
|
1202 from C++ is done using the regular QScriptValue::property() and |
|
1203 QScriptValue::setProperty() functions. The activation object itself |
|
1204 is not directly accessible from script code (but it is implicitly |
|
1205 accessed whenever a local variable is read from or written to). |
|
1206 |
|
1207 For C++ code, there are two principal applications of the |
|
1208 activation object: |
|
1209 |
|
1210 \list |
|
1211 \i The activation object provides a standard way to traverse the |
|
1212 variables associated with a function call, by using it as the input |
|
1213 to QScriptValueIterator. This is useful for debugging purposes. |
|
1214 |
|
1215 \i The activation object can be used to prepare local variables |
|
1216 that should be available when a script is evaluated inline; this |
|
1217 can be viewed as a way of passing arguments to the script |
|
1218 itself. This technique is typically used in conjunction with |
|
1219 QScriptEngine::pushContext(), as in the following example: |
|
1220 |
|
1221 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 77 |
|
1222 |
|
1223 We create a temporary execution context, create a local variable |
|
1224 for it, evaluate the script, and finally restore the old context. |
|
1225 \endlist |
|
1226 |
|
1227 \section2 Property Getters and Setters |
|
1228 |
|
1229 A script object property can be defined in terms of a getter/setter |
|
1230 function, similar to how a Qt C++ property has read and write |
|
1231 functions associated with it. This makes it possible for a script to |
|
1232 use expressions like \c{object.x} instead of \c{object.getX()}; the |
|
1233 getter/setter function for \c{x} will implicitly be invoked |
|
1234 whenever the property is accessed. To scripts, the property looks |
|
1235 and behaves just like a regular object property. |
|
1236 |
|
1237 A single Qt Script function can act as both getter and setter for |
|
1238 a property. When it is called as a getter, the argument count is 0. |
|
1239 When it is called as a setter, the argument count is 1; the argument |
|
1240 is the new value of the property. In the following example, we |
|
1241 define a native combined getter/setter that transforms the value |
|
1242 slightly: |
|
1243 |
|
1244 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 78 |
|
1245 |
|
1246 The example uses the internal data of the object to store and |
|
1247 retrieve the transformed value. Alternatively, the property |
|
1248 could be stored in another, "hidden" property of the object itself |
|
1249 (e.g., \c{__x__}). A native function is free to implement whatever |
|
1250 storage scheme it wants, as long as the external behavior of the |
|
1251 property itself is consistent (e.g., that scripts should not be able |
|
1252 to distinguish it from a regular property). |
|
1253 |
|
1254 The following C++ code shows how an object property can be defined |
|
1255 in terms of the native getter/setter: |
|
1256 |
|
1257 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 79 |
|
1258 |
|
1259 When the property is accessed, like in the following script, the |
|
1260 getter/setter does its job behind the scenes: |
|
1261 |
|
1262 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 80 |
|
1263 |
|
1264 \note It is important that the setter function, not just the getter, |
|
1265 returns the value of the property; i.e., the setter should \e{not} |
|
1266 return QScriptValue::UndefinedValue. This is because the result of |
|
1267 the property assignment is the value returned by the setter, and |
|
1268 not the right-hand side expression. Also note that you normally |
|
1269 should not attempt to read the same property that the getter modifies |
|
1270 within the getter itself, since this will cause the getter to be |
|
1271 called recursively. |
|
1272 |
|
1273 You can remove a property getter/setter by calling |
|
1274 QScriptValue::setProperty(), passing an invalid QScriptValue |
|
1275 as the getter/setter. Remember to specify the |
|
1276 QScriptValue::PropertyGetter/QScriptValue::PropertySetter flag(s), |
|
1277 otherwise the only thing that will happen is that the setter will be |
|
1278 invoked with an invalid QScriptValue as its argument! |
|
1279 |
|
1280 Property getters and setters can be defined and installed by script |
|
1281 code as well, as in the following example: |
|
1282 |
|
1283 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 81 |
|
1284 |
|
1285 Getters and setters can only be used to implement "a priori |
|
1286 properties"; i.e., the technique can't be used to react to an access |
|
1287 to a property that the object doesn't already have. To gain total |
|
1288 control of property access in this way, you need to subclass |
|
1289 QScriptClass. |
|
1290 |
|
1291 \section1 Making Use of Prototype-Based Inheritance |
|
1292 |
|
1293 In ECMAScript, inheritance is based on the concept of \e{shared |
|
1294 prototype objects}; this is quite different from the class-based |
|
1295 inheritance familiar to C++ programmers. With QtScript, you can |
|
1296 associate a custom prototype object with a C++ type using |
|
1297 QScriptEngine::setDefaultPrototype(); this is the key to providing |
|
1298 a script interface to that type. Since the QtScript module is built |
|
1299 on top of Qt's meta-type system, this can be done for any C++ type. |
|
1300 |
|
1301 You might be wondering when exactly you would need to use this |
|
1302 functionality in your application; isn't the automatic binding |
|
1303 provided by QScriptEngine::newQObject() enough? No, not under all |
|
1304 circumstances. |
|
1305 Firstly, not every C++ type is derived from QObject; types that |
|
1306 are not QObjects cannot be introspected through Qt's meta-object |
|
1307 system (they do not have properties, signals and slots). Secondly, |
|
1308 even if a type is QObject-derived, the functionality you want to |
|
1309 expose to scripts might not all be available, since it is unusual to |
|
1310 define every function to be a slot (and it's not always |
|
1311 possible/desirable to change the C++ API to make it so). |
|
1312 |
|
1313 It is perfectly possible to solve this problem by using "conventional" |
|
1314 C++ techniques. For instance, the QRect class could effectively be |
|
1315 made scriptable by creating a QObject-based C++ wrapper class with |
|
1316 \c{x}, \c{y}, \c{width} properties and so on, which forwarded property |
|
1317 access and function calls to the wrapped value. However, as we shall |
|
1318 see, by taking advantage of the ECMAScript object model and combining |
|
1319 it with Qt's meta-object system, we can arrive at a solution that is |
|
1320 more elegant, consistent and lightweight, supported by a small API. |
|
1321 |
|
1322 This section explains the underlying concepts of prototype-based |
|
1323 inheritance. Once these concepts are understood, the associated |
|
1324 practices can be applied throughout the QtScript API in order to |
|
1325 create well-behaved, consistent bindings to C++ that will fit nicely |
|
1326 into the ECMAScript universe. |
|
1327 |
|
1328 When experimenting with QtScript objects and inheritance, it can be |
|
1329 helpful to use the interactive interpreter included with the |
|
1330 \l{Qt Script Examples}, located in \c{examples/script/qscript}. |
|
1331 |
|
1332 \section2 Prototype Objects and Shared Properties |
|
1333 |
|
1334 The purpose of a QtScript \e{prototype object} is to define |
|
1335 behavior that should be shared by a set of other QtScript |
|
1336 objects. We say that objects which share the same prototype object |
|
1337 belong to the same \e{class} (again, on the technical side this |
|
1338 should not to be confused with the class constructs of languages |
|
1339 like C++ and Java; ECMAScript has no such construct). |
|
1340 |
|
1341 The basic prototype-based inheritance mechanism works as follows: Each |
|
1342 QtScript object has an internal link to another object, its |
|
1343 \e{prototype}. When a property is looked up in an object, and the |
|
1344 object itself does not have the property, the property is looked up |
|
1345 in the prototype object instead; if the prototype has the property, |
|
1346 then that property is returned. Otherwise, the property is looked up |
|
1347 in the prototype of the prototype object, and so on; this chain of |
|
1348 objects constitutes a \e{prototype chain}. The chain of prototype |
|
1349 objects is followed until the property is found or the end of the |
|
1350 chain is reached. |
|
1351 |
|
1352 For example, when you create a new object by the expression \c{new |
|
1353 Object()}, the resulting object will have as its prototype the |
|
1354 standard \c{Object} prototype, \c{Object.prototype}; through this |
|
1355 prototype relation, the new object inherits a set of properties, |
|
1356 including the \c{hasOwnProperty()} function and \c{toString()} |
|
1357 function: |
|
1358 |
|
1359 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 27 |
|
1360 |
|
1361 The \c{toString()} function itself is not defined in \c{o} (since we |
|
1362 did not assign anything to \c{o.toString}), so instead the |
|
1363 \c{toString()} function in the standard \c{Object} prototype is |
|
1364 called, which returns a highly generic string representation of |
|
1365 \c{o} ("[object Object]"). |
|
1366 |
|
1367 Note that the properties of the prototype object are not \e{copied} to |
|
1368 the new object; only a \e{link} from the new object to the prototype |
|
1369 object is maintained. This means that changes done to the prototype |
|
1370 object will immediately be reflected in the behavior of all objects |
|
1371 that have the modified object as their prototype. |
|
1372 |
|
1373 \section2 Defining Classes in a Prototype-Based Universe |
|
1374 |
|
1375 In QtScript, a class is not defined explicitly; there is no |
|
1376 \c{class} keyword. Instead, you define a new class in two steps: |
|
1377 |
|
1378 \list 1 |
|
1379 \i Define a \e{constructor function} that will initialize new objects. |
|
1380 \i Set up a \e{prototype object} that defines the class interface, and |
|
1381 assign this object to the public \c{prototype} property of the |
|
1382 constructor function. |
|
1383 \endlist |
|
1384 |
|
1385 With this arrangement, the constructor's public \c{prototype} |
|
1386 property will automatically be set as the prototype of objects created |
|
1387 by applying the \c{new} operator to your constructor function; |
|
1388 e.g., the prototype of an object created by \c{new Foo()} will be the |
|
1389 value of \c{Foo.prototype}. |
|
1390 |
|
1391 Functions that don't operate on the \c this object ("static" methods) |
|
1392 are typically stored as properties of the constructor function, not |
|
1393 as properties of the prototype object. The same is true for |
|
1394 constants, such as enum values. |
|
1395 |
|
1396 The following code defines a simple constructor function for a class |
|
1397 called \c{Person}: |
|
1398 |
|
1399 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 28 |
|
1400 |
|
1401 Next, you want to set up \c{Person.prototype} as your prototype |
|
1402 object; i.e., define the interface that should be common to all |
|
1403 \c{Person} objects. QtScript automatically creates a default |
|
1404 prototype object (by the expression \c{new Object()}) for every |
|
1405 script function; you can add properties to this object, or you can |
|
1406 assign your own custom object. (Generally speaking, any QtScript |
|
1407 object can act as prototype for any other object.) |
|
1408 |
|
1409 Here's an example of how you might want to override the |
|
1410 \c{toString()} function that \c{Person.prototype} inherits from |
|
1411 \c{Object.prototype}, to give your \c{Person} objects a more |
|
1412 appropriate string representation: |
|
1413 |
|
1414 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 29 |
|
1415 |
|
1416 This resembles the process of reimplementing a virtual function |
|
1417 in C++. Henceforth, when the property named \c{toString} is |
|
1418 looked up in a \c{Person} object, it will be resolved in |
|
1419 \c{Person.prototype}, not in \c{Object.prototype} as before: |
|
1420 |
|
1421 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 30 |
|
1422 |
|
1423 There are also some other interesting things we can learn about a |
|
1424 \c{Person} object: |
|
1425 |
|
1426 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 31 |
|
1427 |
|
1428 The \c{hasOwnProperty()} function is not inherited from |
|
1429 \c{Person.prototype}, but rather from \c{Object.prototype}, which is |
|
1430 the prototype of \c{Person.prototype} itself; i.e., the prototype |
|
1431 chain of \c{Person} objects is \c{Person.prototype} followed by |
|
1432 \c{Object.prototype}. This prototype chain establishes a \e{class |
|
1433 hierarchy}, as demonstrated by applying the \c{instanceof} operator; |
|
1434 \c{instanceof} checks if the value of the public \c{prototype} |
|
1435 property of the constructor function on the right-hand side is |
|
1436 reached by following the prototype chain of the object on the |
|
1437 left-hand side. |
|
1438 |
|
1439 When defining subclasses, there's a general pattern you can use. The |
|
1440 following example shows how one can create a subclass of \c{Person} |
|
1441 called \c{Employee}: |
|
1442 |
|
1443 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 32 |
|
1444 |
|
1445 Again, you can use the \c{instanceof} to verify that the |
|
1446 class relationship between \c{Employee} and \c{Person} has been |
|
1447 correctly established: |
|
1448 |
|
1449 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 33 |
|
1450 |
|
1451 This shows that the prototype chain of \c{Employee} objects is the |
|
1452 same as that of \c{Person} objects, but with \c{Employee.prototype} |
|
1453 added to the front of the chain. |
|
1454 |
|
1455 \section2 Prototype-Based Programming with the QtScript C++ API |
|
1456 |
|
1457 You can use QScriptEngine::newFunction() to wrap |
|
1458 native functions. When implementing a constructor function, |
|
1459 you also pass the prototype object as an argument to |
|
1460 QScriptEngine::newFunction(). |
|
1461 You can call QScriptValue::construct() to call a constructor |
|
1462 function, and you can use QScriptValue::call() from within a |
|
1463 native constructor function if you need to call a base class |
|
1464 constructor. |
|
1465 |
|
1466 The QScriptable class provides a convenient way to implement a |
|
1467 prototype object in terms of C++ slots and properties. Take a look |
|
1468 at the \l{Default Prototypes Example} to see how this is done. |
|
1469 Alternatively, the prototype functionality can be implemented in |
|
1470 terms of standalone native functions that you wrap with |
|
1471 QScriptEngine::newFunction() and set as properties of your prototype |
|
1472 object by calling QScriptValue::setProperty(). |
|
1473 |
|
1474 In the implementation of your prototype functions, you use |
|
1475 QScriptable::thisObject() (or QScriptContext::thisObject()) to |
|
1476 obtain a reference to the QScriptValue being operated upon; then you |
|
1477 call qscriptvalue_cast() to cast it to your C++ type, and perform |
|
1478 the relevant operations using the usual C++ API for the type. |
|
1479 |
|
1480 You associate a prototype object with a C++ type by calling |
|
1481 QScriptEngine::setDefaultPrototype(). Once this mapping is |
|
1482 established, QtScript will automatically assign the correct |
|
1483 prototype when a value of such a type is wrapped in a QScriptValue; |
|
1484 either when you explicitly call QScriptEngine::toScriptValue(), or |
|
1485 when a value of such a type is returned from a C++ slot and |
|
1486 internally passed back to script code by the engine. This means you |
|
1487 \e{don't} have to implement wrapper classes if you use this |
|
1488 approach. |
|
1489 |
|
1490 As an example, let's consider how the \c{Person} class from the |
|
1491 preceding section can be implemented in terms of the Qt Script API. |
|
1492 We begin with the native constructor function: |
|
1493 |
|
1494 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 34 |
|
1495 |
|
1496 Here's the native equivalent of the \c{Person.prototype.toString} |
|
1497 function we saw before: |
|
1498 |
|
1499 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 35 |
|
1500 |
|
1501 The \c{Person} class can then be initialized as follows: |
|
1502 |
|
1503 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 36 |
|
1504 |
|
1505 The implementation of the \c{Employee} subclass is similar. We |
|
1506 use QScriptValue::call() to call the super-class (Person) constructor: |
|
1507 |
|
1508 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 37 |
|
1509 |
|
1510 The \c{Employee} class can then be initialized as follows: |
|
1511 |
|
1512 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 38 |
|
1513 |
|
1514 When implementing the prototype object of a class, you may want to use |
|
1515 the QScriptable class, as it enables you to define the API of your |
|
1516 script class in terms of Qt properties, signals and slots, and |
|
1517 automatically handles value conversion between the Qt Script and C++ |
|
1518 side. |
|
1519 |
|
1520 \section2 Implementing Prototype Objects for Value-based Types |
|
1521 |
|
1522 When implementing a prototype object for a value-based type -- |
|
1523 e.g. QPointF -- the same general technique applies; you populate |
|
1524 a prototype object with functionality that should be shared |
|
1525 among instances. You then associate the prototype object with |
|
1526 the type by calling QScriptEngine::setDefaultPrototype(). This |
|
1527 ensures that when e.g. a value of the relevant type is returned |
|
1528 from a slot back to the script, the prototype link of the script |
|
1529 value will be initialized correctly. |
|
1530 |
|
1531 When values of the custom type are stored in QVariants -- which Qt |
|
1532 Script does by default --, qscriptvalue_cast() enables you to safely |
|
1533 cast the script value to a pointer to the C++ type. This makes it |
|
1534 easy to do type-checking, and, for prototype functions that should |
|
1535 modify the underlying C++ value, lets you modify the actual value |
|
1536 contained in the script value (and not a copy of it). |
|
1537 |
|
1538 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 39 |
|
1539 |
|
1540 \section2 Implementing Constructors for Value-based Types |
|
1541 |
|
1542 You can implement a constructor function for a value-based type |
|
1543 by wrapping a native factory function. For example, the following |
|
1544 function implements a simple constructor for QPoint: |
|
1545 |
|
1546 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 44 |
|
1547 |
|
1548 In the above code we simplified things a bit, e.g. we didn't check |
|
1549 the argument count to decide which QPoint C++ constructor to use. |
|
1550 In your own constructors you have to do this type of resolution |
|
1551 yourself, i.e. by checking the number of arguments passed to the |
|
1552 native function, and/or by checking the type of the arguments and |
|
1553 converting the arguments to the desired type. If you detect a problem |
|
1554 with the arguments you may want to signal this by throwing a script |
|
1555 exception; see QScriptContext::throwError(). |
|
1556 |
|
1557 \section2 Managing Non-QObject-based Objects |
|
1558 |
|
1559 For value-based types (e.g. QPoint), the C++ object will be destroyed when |
|
1560 the Qt Script object is garbage-collected, so managing the memory of the C++ |
|
1561 object is not an issue. For QObjects, Qt Script provides several |
|
1562 alternatives for managing the underlying C++ object's lifetime; see the |
|
1563 \l{Controlling QObject Ownership} section. However, for polymorphic types |
|
1564 that don't inherit from QObject, and when you can't (or won't) wrap the type |
|
1565 in a QObject, you have to manage the lifetime of the C++ object yourself. |
|
1566 |
|
1567 A behavior that's often reasonable when a Qt Script object wraps a C++ |
|
1568 object, is that the C++ object is deleted when the Qt Script object is |
|
1569 garbage-collected; this is typically the case when the objects can be |
|
1570 constructed by scripts, as opposed to the application providing the scripts |
|
1571 with pre-made "environment" objects. A way of making the lifetime of the C++ |
|
1572 object follow the lifetime of the Qt Script object is by using a shared |
|
1573 pointer class, such as QSharedPointer, to hold a pointer to your object; |
|
1574 when the Qt Script object containing the QSharedPointer is |
|
1575 garbage-collected, the underlying C++ object will be deleted if there are no |
|
1576 other references to the object. |
|
1577 |
|
1578 The following snippet shows a constructor function that constructs |
|
1579 QXmlStreamReader objects that are stored using QSharedPointer: |
|
1580 |
|
1581 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 93 |
|
1582 |
|
1583 Prototype functions can use qscriptvalue_cast() to cast the \c this object |
|
1584 to the proper type: |
|
1585 |
|
1586 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 94 |
|
1587 |
|
1588 The prototype and constructor objects are set up in the usual way: |
|
1589 |
|
1590 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 95 |
|
1591 |
|
1592 Scripts can now construct QXmlStreamReader objects by calling the \c |
|
1593 XmlStreamReader constructor, and when the Qt Script object is |
|
1594 garbage-collected (or the script engine is destroyed), the QXmlStreamReader |
|
1595 object is destroyed as well. |
|
1596 |
|
1597 \section1 Defining Custom Script Classes with QScriptClass |
|
1598 |
|
1599 There are cases where neither the dynamic QObject binding provided |
|
1600 by QScriptEngine::newQObject() or the manual binding provided by |
|
1601 QScriptEngine::newFunction() is sufficient. For example, you might |
|
1602 want to implement a dynamic script proxy to an underlying object; |
|
1603 or you might want to implement an array-like class (i.e. that gives |
|
1604 special treatment to properties that are valid array indexes, and |
|
1605 to the property "length"). In such cases, you can subclass |
|
1606 QScriptClass to achieve the desired behavior. |
|
1607 |
|
1608 QScriptClass allows you to handle all property access for a |
|
1609 (class of) script object through virtual get/set property functions. |
|
1610 Iteration of custom properties is also supported through the |
|
1611 QScriptClassPropertyIterator class; this means you can advertise |
|
1612 properties to be reported by for-in script statements and |
|
1613 QScriptValueIterator. |
|
1614 |
|
1615 \section1 Error Handling and Debugging Facilities |
|
1616 |
|
1617 Syntax errors in scripts will be reported as soon as a script is |
|
1618 evaluated; QScriptEngine::evaluate() will return a SyntaxError object |
|
1619 that you can convert to a string to get a description of the error. |
|
1620 |
|
1621 The QScriptEngine::uncaughtExceptionBacktrace() function gives you |
|
1622 a human-readable backtrace of the last uncaught exception. In order |
|
1623 to get useful filename information in backtraces, you should pass |
|
1624 proper filenames to QScriptEngine::evaluate() when evaluating your |
|
1625 scripts. |
|
1626 |
|
1627 Often an exception doesn't happen at the time the script is evaluated, |
|
1628 but at a later time when a function defined by the script is actually |
|
1629 executed. For C++ signal handlers, this is tricky; consider the case |
|
1630 where the clicked() signal of a button is connected to a script function, |
|
1631 and that script function causes a script exception when it is handling |
|
1632 the signal. Where is that script exception propagated to? |
|
1633 |
|
1634 The solution is to connect to the QScriptEngine::signalHandlerException() |
|
1635 signal; this will give you notification when a signal handler causes |
|
1636 an exception, so that you can find out what happened and/or recover |
|
1637 from it. |
|
1638 |
|
1639 In Qt 4.4 the QScriptEngineAgent class was introduced. QScriptEngineAgent |
|
1640 provides an interface for reporting low-level "events" in a script engine, |
|
1641 such as when a function is entered or when a new script statement is |
|
1642 reached. By subclassing QScriptEngineAgent you can be notified of these |
|
1643 events and perform some action, if you want. QScriptEngineAgent itself |
|
1644 doesn't provide any debugging-specific functionality (e.g. setting |
|
1645 breakpoints), but it is the basis of tools that do. |
|
1646 |
|
1647 The QScriptEngineDebugger class introduced in Qt 4.5 provides a |
|
1648 \l{Qt Script Debugger Manual}{Qt Script debugger} that can be embedded |
|
1649 into your application. |
|
1650 |
|
1651 \section2 Redefining print() |
|
1652 |
|
1653 Qt Script provides a built-in print() function that can be useful for |
|
1654 simple debugging purposes. The built-in print() function writes to |
|
1655 standard output. You can redefine the print() function (or add your |
|
1656 own function, e.g. debug() or log()) that redirects the text to |
|
1657 somewhere else. The following code shows a custom print() that adds |
|
1658 text to a QPlainTextEdit. |
|
1659 |
|
1660 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 45 |
|
1661 |
|
1662 The following code shows how the custom print() function may be |
|
1663 initialized and used. |
|
1664 |
|
1665 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 46 |
|
1666 |
|
1667 A pointer to the QPlainTextEdit is stored as an internal property |
|
1668 of the script function itself, so that it can be retrieved when |
|
1669 the function is called. |
|
1670 |
|
1671 \section1 Using QtScript Extensions |
|
1672 |
|
1673 The QScriptEngine::importExtension() function can be used to load plugins |
|
1674 into a script engine. Plugins typically add some extra functionality to |
|
1675 the engine; for example, a plugin might add full bindings for the Qt |
|
1676 Arthur painting API, so that those classes may be used from Qt Script |
|
1677 scripts. There are currently no script plugins shipped with Qt. |
|
1678 |
|
1679 If you are implementing some Qt Script functionality that you want other |
|
1680 Qt application developers to be able to use, \l{Creating QtScript Extensions} |
|
1681 {developing an extension} (e.g. by subclassing QScriptExtensionPlugin) is |
|
1682 worth looking into. |
|
1683 |
|
1684 \section1 Internationalization |
|
1685 |
|
1686 Since Qt 4.5, Qt Script supports internationalization of scripts by building |
|
1687 on the C++ internationalization functionality (see \l{Internationalization |
|
1688 with Qt}). |
|
1689 |
|
1690 \section2 Use qsTr() for All Literal Text |
|
1691 |
|
1692 Wherever your script uses "quoted text" for text that will be presented to |
|
1693 the user, ensure that it is processed by the QCoreApplication::translate() |
|
1694 function. Essentially all that is necessary to achieve this is to use |
|
1695 the qsTr() script function. Example: |
|
1696 |
|
1697 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 82 |
|
1698 |
|
1699 This accounts for 99% of the user-visible strings you're likely to write. |
|
1700 |
|
1701 The qsTr() function uses the basename of the script's filename (see |
|
1702 QFileInfo::baseName()) as the translation context; if the filename is not |
|
1703 unique in your project, you should use the qsTranslate() function and pass a |
|
1704 suitable context as the first argument. Example: |
|
1705 |
|
1706 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 83 |
|
1707 |
|
1708 If you need to have translatable text completely outside a function, there |
|
1709 are two functions to help: QT_TR_NOOP() and QT_TRANSLATE_NOOP(). They merely |
|
1710 mark the text for extraction by the \c lupdate utility described below. At |
|
1711 runtime, these functions simply return the text to translate unmodified. |
|
1712 |
|
1713 Example of QT_TR_NOOP(): |
|
1714 |
|
1715 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 84 |
|
1716 |
|
1717 Example of QT_TRANSLATE_NOOP(): |
|
1718 |
|
1719 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 85 |
|
1720 |
|
1721 \section2 Use String.prototype.arg() for Dynamic Text |
|
1722 |
|
1723 The String.prototype.arg() function (which is modeled after QString::arg()) |
|
1724 offers a simple means for substituting arguments: |
|
1725 |
|
1726 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 86 |
|
1727 |
|
1728 \section2 Produce Translations |
|
1729 |
|
1730 Once you are using qsTr() and/or qsTranslate() throughout your scripts, you |
|
1731 can start producing translations of the user-visible text in your program. |
|
1732 |
|
1733 The \l{Qt Linguist manual} provides further information about |
|
1734 Qt's translation tools, \e{Qt Linguist}, \c lupdate and \c |
|
1735 lrelease. |
|
1736 |
|
1737 Translation of Qt Script scripts is a three-step process: |
|
1738 |
|
1739 \list 1 |
|
1740 |
|
1741 \o Run \c lupdate to extract translatable text from the script source code |
|
1742 of the Qt application, resulting in a message file for translators (a TS |
|
1743 file). The utility recognizes qsTr(), qsTranslate() and the |
|
1744 \c{QT_TR*_NOOP()} functions described above and produces TS files |
|
1745 (usually one per language). |
|
1746 |
|
1747 \o Provide translations for the source texts in the TS file, using |
|
1748 \e{Qt Linguist}. Since TS files are in XML format, you can also |
|
1749 edit them by hand. |
|
1750 |
|
1751 \o Run \c lrelease to obtain a light-weight message file (a QM |
|
1752 file) from the TS file, suitable only for end use. Think of the TS |
|
1753 files as "source files", and QM files as "object files". The |
|
1754 translator edits the TS files, but the users of your application |
|
1755 only need the QM files. Both kinds of files are platform and |
|
1756 locale independent. |
|
1757 |
|
1758 \endlist |
|
1759 |
|
1760 Typically, you will repeat these steps for every release of your |
|
1761 application. The \c lupdate utility does its best to reuse the |
|
1762 translations from previous releases. |
|
1763 |
|
1764 When running \c lupdate, you must specify the location of the script(s), |
|
1765 and the name of the TS file to produce. Examples: |
|
1766 |
|
1767 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 87 |
|
1768 |
|
1769 will extract translatable text from \c myscript.qs and create the |
|
1770 translation file \c myscript_la.qs. |
|
1771 |
|
1772 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 88 |
|
1773 |
|
1774 will extract translatable text from all files ending with \c{.qs} in the |
|
1775 \c scripts folder and create the translation file \c scripts_la.qs. |
|
1776 |
|
1777 Alternatively, you can create a separate qmake project file that sets up |
|
1778 the \c SOURCES and \c TRANSLATIONS variables appropriately; then run |
|
1779 \c lupdate with the project file as input. |
|
1780 |
|
1781 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 89 |
|
1782 |
|
1783 When running \c lrelease, you must specify the name of the TS input |
|
1784 file; or, if you are using a qmake project file to manage script |
|
1785 translations, you specify the name of that file. \c lrelease will create |
|
1786 \c myscript_la.qm, the binary representation of the translation. |
|
1787 |
|
1788 \section2 Apply Translations |
|
1789 |
|
1790 In your application, you must use QTranslator::load() to load the |
|
1791 translation files appropriate for the user's language, and install them |
|
1792 using QCoreApplication::installTranslator(). Finally, you must call |
|
1793 QScriptEngine::installTranslatorFunctions() to make the script translation |
|
1794 functions (qsTr(), qsTranslate() and \c{QT_TR*_NOOP()}) available to scripts |
|
1795 that are subsequently evaluated by QScriptEngine::evaluate(). For scripts |
|
1796 that are using the qsTr() function, the proper filename must be passed as |
|
1797 second argument to QScriptEngine::evaluate(). |
|
1798 |
|
1799 \c linguist, \c lupdate and \c lrelease are installed in the \c bin |
|
1800 subdirectory of the base directory Qt is installed into. Click Help|Manual |
|
1801 in \e{Qt Linguist} to access the user's manual; it contains a tutorial |
|
1802 to get you started. |
|
1803 |
|
1804 See also the \l{Hello Script Example}. |
|
1805 |
|
1806 \section1 ECMAScript Compatibility |
|
1807 |
|
1808 QtScript implements all the built-in classes and functions defined |
|
1809 in ECMA-262. |
|
1810 |
|
1811 The Date parsing and string conversion functions are implemented using |
|
1812 QDateTime::fromString() and QDateTime::toString(), respectively. |
|
1813 |
|
1814 The RegExp class is a wrapper around QRegExp. The QRegExp semantics |
|
1815 do not precisely match the semantics for regular expressions defined |
|
1816 in ECMA-262. |
|
1817 |
|
1818 \section1 QtScript Extensions to ECMAScript |
|
1819 |
|
1820 \list |
|
1821 \i \c{__proto__} \br |
|
1822 The prototype of an object (QScriptValue::prototype()) |
|
1823 can be accessed through its \c{__proto__} property in script code. |
|
1824 This property has the QScriptValue::Undeletable flag set. |
|
1825 For example: |
|
1826 |
|
1827 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 40 |
|
1828 |
|
1829 \i \c{Object.prototype.__defineGetter__} \br |
|
1830 This function installs a |
|
1831 getter function for a property of an object. The first argument is |
|
1832 the property name, and the second is the function to call to get |
|
1833 the value of that property. When the function is invoked, the |
|
1834 \c this object will be the object whose property is accessed. |
|
1835 For example: |
|
1836 |
|
1837 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 41 |
|
1838 |
|
1839 \i \c{Object.prototype.__defineSetter__} \br |
|
1840 This function installs a |
|
1841 setter function for a property of an object. The first argument is |
|
1842 the property name, and the second is the function to call to set |
|
1843 the value of that property. When the function is invoked, the |
|
1844 \c this object will be the object whose property is accessed. |
|
1845 For example: |
|
1846 |
|
1847 \snippet doc/src/snippets/code/doc_src_qtscript.qdoc 42 |
|
1848 |
|
1849 \i \c{Function.prototype.connect} \br |
|
1850 This function connects |
|
1851 a signal to a slot. Usage of this function is described in |
|
1852 the section \l{Using Signals and Slots}. |
|
1853 |
|
1854 \i \c{Function.prototype.disconnect} \br |
|
1855 This function disconnects |
|
1856 a signal from a slot. Usage of this function is described in |
|
1857 the section \l{Using Signals and Slots}. |
|
1858 |
|
1859 \i \c{QObject.prototype.findChild} \br |
|
1860 This function is semantically equivalent to QObject::findChild(). |
|
1861 |
|
1862 \i \c{QObject.prototype.findChildren} \br |
|
1863 This function is semantically equivalent to QObject::findChildren(). |
|
1864 |
|
1865 \i \c{QObject.prototype.toString} \br |
|
1866 This function returns a default string representation of a QObject. |
|
1867 |
|
1868 \i \c{gc} \br |
|
1869 This function invokes the garbage collector. |
|
1870 |
|
1871 \i \c{Error.prototype.backtrace} \br |
|
1872 This function returns a human-readable backtrace, in the form of |
|
1873 an array of strings. |
|
1874 |
|
1875 \i Error objects have the following additional properties: |
|
1876 \list |
|
1877 \i \c{lineNumber}: The line number where the error occurred. |
|
1878 \i \c{fileName}: The file name where the error occurred (if a file name |
|
1879 was passed to QScriptEngine::evaluate()). |
|
1880 \i \c{stack}: An array of objects describing the stack. Each object has |
|
1881 the following properties: |
|
1882 \list |
|
1883 \i \c{functionName}: The function name, if available. |
|
1884 \i \c{fileName}: The file name, if available. |
|
1885 \i \c{lineNumber}: The line number, if available. |
|
1886 \endlist |
|
1887 \endlist |
|
1888 |
|
1889 \endlist |
|
1890 |
|
1891 */ |