| 1 | /**************************************************************************** | 
|---|
| 2 | ** | 
|---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | 
|---|
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com) | 
|---|
| 5 | ** | 
|---|
| 6 | ** This file is part of the documentation of the Qt Toolkit. | 
|---|
| 7 | ** | 
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
|---|
| 9 | ** Commercial Usage | 
|---|
| 10 | ** Licensees holding valid Qt Commercial licenses may use this file in | 
|---|
| 11 | ** accordance with the Qt Commercial License Agreement provided with the | 
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
|---|
| 13 | ** a written agreement between you and Nokia. | 
|---|
| 14 | ** | 
|---|
| 15 | ** GNU Lesser General Public License Usage | 
|---|
| 16 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
|---|
| 17 | ** General Public License version 2.1 as published by the Free Software | 
|---|
| 18 | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
|---|
| 19 | ** packaging of this file.  Please review the following information to | 
|---|
| 20 | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
|---|
| 21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | 
|---|
| 22 | ** | 
|---|
| 23 | ** In addition, as a special exception, Nokia gives you certain | 
|---|
| 24 | ** additional rights. These rights are described in the Nokia Qt LGPL | 
|---|
| 25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this | 
|---|
| 26 | ** package. | 
|---|
| 27 | ** | 
|---|
| 28 | ** GNU General Public License Usage | 
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU | 
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software | 
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the | 
|---|
| 32 | ** packaging of this file.  Please review the following information to | 
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be | 
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html. | 
|---|
| 35 | ** | 
|---|
| 36 | ** If you are unsure which license is appropriate for your use, please | 
|---|
| 37 | ** contact the sales department at qt-sales@nokia.com. | 
|---|
| 38 | ** $QT_END_LICENSE$ | 
|---|
| 39 | ** | 
|---|
| 40 | ****************************************************************************/ | 
|---|
| 41 |  | 
|---|
| 42 | /*! | 
|---|
| 43 | \title Moving from QSA to Qt Script | 
|---|
| 44 | \page porting-qsa.html | 
|---|
| 45 | \ingroup porting | 
|---|
| 46 |  | 
|---|
| 47 | The purpose of this document is to map the differences between Qt | 
|---|
| 48 | Script for Applications (QSA) and Qt Script, the ECMAScript compatible | 
|---|
| 49 | engine supplied with Qt 4.3. This document is not supposed to be a | 
|---|
| 50 | complete function by function porting guide, but will cover the most | 
|---|
| 51 | obvious aspects. | 
|---|
| 52 |  | 
|---|
| 53 | First of all it is important to realize that Qt Script is only an | 
|---|
| 54 | interpreter, it does not provide an editor, completion or script project | 
|---|
| 55 | management, like QSA does. Qt Script however does provides almost full | 
|---|
| 56 | compliance with the ECMAScript standard and performs significantly | 
|---|
| 57 | better than the script engine provided by QSA. | 
|---|
| 58 |  | 
|---|
| 59 | \tableofcontents | 
|---|
| 60 |  | 
|---|
| 61 | \section1 The Scripting Language | 
|---|
| 62 |  | 
|---|
| 63 | The scripting language used in QSA, from here on referred to as QSA, | 
|---|
| 64 | was derived from ECMAScript 3.0 and 4.0 and is a hybrid of these | 
|---|
| 65 | standards. Most of the run-time logic, such as classes and scoping | 
|---|
| 66 | rules, is based on the ECMAScript 4.0 proposal, while the library | 
|---|
| 67 | implementation is based on the ECMAScript 3.0 standard. | 
|---|
| 68 | Qt Script on the other hand is solely based on the ECMAScript 3.0 | 
|---|
| 69 | standard. Though the languages look identical at first glance, | 
|---|
| 70 | there are a few differences that we'll cover in the sections below. | 
|---|
| 71 |  | 
|---|
| 72 |  | 
|---|
| 73 | \section2 Classes vs. Objects and Properties | 
|---|
| 74 |  | 
|---|
| 75 | QSA implements classes and inheritance much in a familiar way to users | 
|---|
| 76 | of other object oriented languages, like C++ and Java. However, the | 
|---|
| 77 | ECMAScript 3.0 standard defines that everything is an object, and objects | 
|---|
| 78 | can have named properties. For instance to create an point object with | 
|---|
| 79 | the properties x and y one would write the following Qt Script code: | 
|---|
| 80 |  | 
|---|
| 81 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 0 | 
|---|
| 82 |  | 
|---|
| 83 | The object \c point in this case is constructed as a plain object and | 
|---|
| 84 | we assign two properties, \c x and \c y, to it with the values 12 and | 
|---|
| 85 | 35. The \c point object is assigned to the "Global Object" as the | 
|---|
| 86 | named property \c{point}. The global object can be considered the | 
|---|
| 87 | global namespace of the script engine. Similarly, global functions are | 
|---|
| 88 | named properties of the global object; for example: | 
|---|
| 89 |  | 
|---|
| 90 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 1 | 
|---|
| 91 |  | 
|---|
| 92 | An equivalent construction that illustrates that the function is a | 
|---|
| 93 | property of the global object is the following assignment: | 
|---|
| 94 |  | 
|---|
| 95 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 2 | 
|---|
| 96 |  | 
|---|
| 97 | Since functions are objects, they can be assigned to objects as | 
|---|
| 98 | properties, becoming member functions: | 
|---|
| 99 |  | 
|---|
| 100 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 3 | 
|---|
| 101 |  | 
|---|
| 102 | In the code above, we see the first subtle difference between | 
|---|
| 103 | QSA and Qt Script. In QSA one would write the point class like this: | 
|---|
| 104 |  | 
|---|
| 105 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 4 | 
|---|
| 106 |  | 
|---|
| 107 | where in the \c manhattanLength() function we access \c x and \c y | 
|---|
| 108 | directly because, when the function is called, the \c this object is | 
|---|
| 109 | implicitly part of the current scope, as in C++. In Qt Script, | 
|---|
| 110 | however, this is not the case, and we need to explicitly access | 
|---|
| 111 | the \c x and \c y values via \c{this}. | 
|---|
| 112 |  | 
|---|
| 113 | All the code above runs with QSA except the assignment of a function | 
|---|
| 114 | to \c{point.manhattanLength}, which we repeat here for clarity: | 
|---|
| 115 |  | 
|---|
| 116 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 5 | 
|---|
| 117 |  | 
|---|
| 118 | This is because, in QSA, the value of \c this is decided based on | 
|---|
| 119 | the location of the declaration of the function it is used in. In the | 
|---|
| 120 | code above, the function is assigned to an object, but it is declared | 
|---|
| 121 | in the global scope, hence there will be no valid \c this value. | 
|---|
| 122 | In Qt Script, the value of \c this is decided at run-time, | 
|---|
| 123 | hence you could have assigned the \c manhattanLength() function to any | 
|---|
| 124 | object that had \c x and \c y values. | 
|---|
| 125 |  | 
|---|
| 126 |  | 
|---|
| 127 | \section2 Constructors | 
|---|
| 128 |  | 
|---|
| 129 | In the code above, we use a rather awkward method for constructing | 
|---|
| 130 | the objects, by first instantiating them, then manually | 
|---|
| 131 | assigning properties to them. In QSA, the proper way to solve this | 
|---|
| 132 | is to implement a constructor in the class: | 
|---|
| 133 |  | 
|---|
| 134 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 6 | 
|---|
| 135 |  | 
|---|
| 136 | The equivalent in Qt Script is to create a constructor function: | 
|---|
| 137 |  | 
|---|
| 138 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 7 | 
|---|
| 139 |  | 
|---|
| 140 | As we can see, the constructor is just a normal function. What is | 
|---|
| 141 | special with is how we call it, namely prefixed with the \c new | 
|---|
| 142 | keyword. This will create a new object and call the \c Car() | 
|---|
| 143 | function with the newly created object as the \c this pointer. | 
|---|
| 144 | So, in a sense, it is equivalent to: | 
|---|
| 145 |  | 
|---|
| 146 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 8 | 
|---|
| 147 |  | 
|---|
| 148 | This is similar to the manhattenLength() example above. Again, the | 
|---|
| 149 | main difference between QSA and Qt Script is that one has to | 
|---|
| 150 | explicitly use the keyword \c this to access the members and that | 
|---|
| 151 | instead of declaring the variable, \c regNumber, we just extend the | 
|---|
| 152 | \c this object with the property. | 
|---|
| 153 |  | 
|---|
| 154 |  | 
|---|
| 155 | \section2 Member Functions and Prototypes | 
|---|
| 156 |  | 
|---|
| 157 | As we saw above, one way of creating member functions of a Qt Script | 
|---|
| 158 | object is to assign the member function to the object as a property | 
|---|
| 159 | and use the \c this object inside the functions. So, if we add a | 
|---|
| 160 | \c toString function to the \c Car class | 
|---|
| 161 |  | 
|---|
| 162 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 9 | 
|---|
| 163 |  | 
|---|
| 164 | one could write this in Qt Script as: | 
|---|
| 165 |  | 
|---|
| 166 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 10 | 
|---|
| 167 |  | 
|---|
| 168 | In QSA, the member functions were part of the class declaration, | 
|---|
| 169 | and were therefore shared between all instances of a given class. | 
|---|
| 170 | In Qt Script, each instance has a instance member for each function. | 
|---|
| 171 | This means that more memory is used when multiple instances are used. | 
|---|
| 172 | Qt Script uses prototypes to remedy this. | 
|---|
| 173 |  | 
|---|
| 174 | The basic prototype-based inheritance mechanism works as follows. | 
|---|
| 175 | Each Qt Script object has an internal link to another object, its | 
|---|
| 176 | prototype. When a property is looked up in an object, and the object | 
|---|
| 177 | itself does not have the property, the interpreter searches for the | 
|---|
| 178 | property in the prototype object instead; if the prototype has the | 
|---|
| 179 | property then that property is returned. If the prototype object does | 
|---|
| 180 | not have the property, the interpreter searches for the property in | 
|---|
| 181 | the prototype of the prototype object, and so on. | 
|---|
| 182 |  | 
|---|
| 183 | This chain of objects constitutes a prototype chain. The chain of | 
|---|
| 184 | prototype objects is followed until the property is found or the end | 
|---|
| 185 | of the chain is reached. | 
|---|
| 186 |  | 
|---|
| 187 | To make the \c toString() function part of the prototype, we write | 
|---|
| 188 | code like this: | 
|---|
| 189 |  | 
|---|
| 190 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 11 | 
|---|
| 191 |  | 
|---|
| 192 | Here, we made the \c toString() function part of the prototype so | 
|---|
| 193 | that, when we call \c{car.toString()} it will be resolved via the | 
|---|
| 194 | internal prototype object of the car object. Note, however, that the | 
|---|
| 195 | \c this object is still the original object that the function was | 
|---|
| 196 | called on, namely \c{car}. | 
|---|
| 197 |  | 
|---|
| 198 |  | 
|---|
| 199 | \section2 Inheritance | 
|---|
| 200 |  | 
|---|
| 201 | Now that we've seen how to use prototypes to create a "class" members | 
|---|
| 202 | in Qt Script, let's see how we can use prototypes to create | 
|---|
| 203 | polymorphism. In QSA you would write | 
|---|
| 204 |  | 
|---|
| 205 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 12 | 
|---|
| 206 |  | 
|---|
| 207 | With Qt Script, we acheive the same effect by creating a prototype | 
|---|
| 208 | chain. The default prototype of an object is a plain \c Object | 
|---|
| 209 | without any special members, but it is possible to replace this | 
|---|
| 210 | object with another prototype object. | 
|---|
| 211 |  | 
|---|
| 212 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 13 | 
|---|
| 213 |  | 
|---|
| 214 | In the code above, we have a constructor, \c{GasolineCar}, which | 
|---|
| 215 | calls the "base class" implementation of the constructor to | 
|---|
| 216 | initialize the \c this object with the property \c{regNumber}, | 
|---|
| 217 | based on the values passed in the constructor. The interesting line | 
|---|
| 218 | in this case is the line after the constructor where we change the | 
|---|
| 219 | default prototype for \c GasolineCar to be an instance of type | 
|---|
| 220 | \c{Car}. This means that all members available in a \c Car object | 
|---|
| 221 | are now available in all \c GasolineCar objects. In the last line, | 
|---|
| 222 | we replace the \c toString() function in the prototype with our own, | 
|---|
| 223 | thus overriding the \c toString() for all instances of | 
|---|
| 224 | \c{GasolineCar}. | 
|---|
| 225 |  | 
|---|
| 226 |  | 
|---|
| 227 | \section2 Static Members | 
|---|
| 228 |  | 
|---|
| 229 | QSA allowed users to declare static members in classes, and these | 
|---|
| 230 | could be accessed both through instances of the class and through | 
|---|
| 231 | the class itself. For example, the following variable is accessed | 
|---|
| 232 | through the \c Car class: | 
|---|
| 233 |  | 
|---|
| 234 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 14 | 
|---|
| 235 |  | 
|---|
| 236 | The equivalent in Qt Script is to assign variables that should appear | 
|---|
| 237 | as static members as properties of the constructor function. For | 
|---|
| 238 | example: | 
|---|
| 239 |  | 
|---|
| 240 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 15 | 
|---|
| 241 |  | 
|---|
| 242 | Note that in QSA, static member variables were also accessible in | 
|---|
| 243 | instances of the given class. In Qt Script, with the approach | 
|---|
| 244 | illustrated above, the variable is a member of the constructor | 
|---|
| 245 | object only, and thus only accessible through \c{Car.globalCount}. | 
|---|
| 246 |  | 
|---|
| 247 |  | 
|---|
| 248 | \section1 The Built-in Functions and Library | 
|---|
| 249 |  | 
|---|
| 250 | The built-in functions in QSA are based on those defined in the | 
|---|
| 251 | ECMAScript 3.0 standard, the same standard used for Qt Script, but | 
|---|
| 252 | QSA adds some extensions to this, specifically for the \c String | 
|---|
| 253 | and \c RegExp types. QSA also lacked some functions from the | 
|---|
| 254 | standard, most notably the \c Date type. Below we list all the | 
|---|
| 255 | differences. All changes made to Qt Script are to increase | 
|---|
| 256 | compliance with ECMAScript 3.0. | 
|---|
| 257 |  | 
|---|
| 258 | \table | 
|---|
| 259 | \header \o QSA Function \o Notes about Equivalent Qt Script Functions | 
|---|
| 260 | \row \o eval() | 
|---|
| 261 | \o The eval function in QSA opened a new scope for code being | 
|---|
| 262 | executed in the eval function, so locally declared variables were not | 
|---|
| 263 | accessible outside. In Qt Script, the eval() function shares the | 
|---|
| 264 | current scope, making locally declared variables accessible outside | 
|---|
| 265 | the eval() call. | 
|---|
| 266 |  | 
|---|
| 267 | \row \o debug() | 
|---|
| 268 | \o This function is not available in Qt Script. Use print() instead. | 
|---|
| 269 |  | 
|---|
| 270 | \row \o connect() | 
|---|
| 271 | \o QSA had closures, meaning that a member function | 
|---|
| 272 | reference implicitly contained its \c this object. Qt Script does not | 
|---|
| 273 | support this. See the Qt Script documentation for details on using the | 
|---|
| 274 | connect function. | 
|---|
| 275 |  | 
|---|
| 276 | \row \o String.arg() | 
|---|
| 277 | \o This function is not available in Qt Script. Use replace() or concat() instead. | 
|---|
| 278 |  | 
|---|
| 279 | \row \o String.argDec() | 
|---|
| 280 | \o This function is not available in Qt Script. Use replace() or concat() instead. | 
|---|
| 281 |  | 
|---|
| 282 | \row \o String.argInt() | 
|---|
| 283 | \o This function is not available in Qt Script. Use replace() or concat() instead. | 
|---|
| 284 |  | 
|---|
| 285 | \row \o String.argStr() | 
|---|
| 286 | \o This function is not available in Qt Script. Use replace() or concat() instead. | 
|---|
| 287 |  | 
|---|
| 288 | \row \o String.endsWith() | 
|---|
| 289 | \o This function is not available in Qt Script. Use lastIndexOf() instead. | 
|---|
| 290 |  | 
|---|
| 291 | \row \o String.find() | 
|---|
| 292 | \o This function is not available in Qt Script. Use indexOf() instead. | 
|---|
| 293 |  | 
|---|
| 294 | \row \o String.findRev() | 
|---|
| 295 | \o This function is not available in Qt Script. Use lastIndexOf() and length instead. | 
|---|
| 296 |  | 
|---|
| 297 | \row \o String.isEmpty() | 
|---|
| 298 | \o This function is not available in Qt Script. Use length == 0 instead. | 
|---|
| 299 |  | 
|---|
| 300 | \row \o String.left() | 
|---|
| 301 | \o This function is not available in Qt Script. Use substring() instead. | 
|---|
| 302 |  | 
|---|
| 303 | \row \o String.lower() | 
|---|
| 304 | \o This function is not available in Qt Script. Use toLowerCase() instead. | 
|---|
| 305 |  | 
|---|
| 306 | \row \o String.mid() | 
|---|
| 307 | \o This function is not available in Qt Script. Use substring() instead. | 
|---|
| 308 |  | 
|---|
| 309 | \row \o String.right() | 
|---|
| 310 | \o This function is not available in Qt Script. Use substring() instead. | 
|---|
| 311 |  | 
|---|
| 312 | \row \o String.searchRev() | 
|---|
| 313 | \o This function is not available in Qt Script. Use search() / match() instead. | 
|---|
| 314 |  | 
|---|
| 315 | \row \o String.startsWith() | 
|---|
| 316 | \o This function is not available in Qt Script. Use indexOf() == 0 instead. | 
|---|
| 317 |  | 
|---|
| 318 | \row \o String.upper() | 
|---|
| 319 | \o This function is not available in Qt Script. Use toUpperCase() instead. | 
|---|
| 320 |  | 
|---|
| 321 | \row \o RegExp.valid | 
|---|
| 322 | \o This property is not available in Qt Script because it is not | 
|---|
| 323 | required; a \c SyntaxError exception is thrown for bad \c RegExp objects. | 
|---|
| 324 |  | 
|---|
| 325 | \row \o RegExp.empty | 
|---|
| 326 | \o This property is not available in Qt Script. Use \c{toString().length == 0} instead. | 
|---|
| 327 |  | 
|---|
| 328 | \row \o RegExp.matchedLength | 
|---|
| 329 | \o This property is not available in Qt Script. RegExp.exec() returns an | 
|---|
| 330 | array whose size is the matched length. | 
|---|
| 331 |  | 
|---|
| 332 | \row \o RegExp.capturedTexts | 
|---|
| 333 | \o This property is not available in Qt Script. RegExp.exec() returns an | 
|---|
| 334 | array of captured texts. | 
|---|
| 335 |  | 
|---|
| 336 | \row \o RegExp.search() | 
|---|
| 337 | \o This function is not available in Qt Script. Use RegExp.exec() instead. | 
|---|
| 338 |  | 
|---|
| 339 | \row \o RegExp.searchRev() | 
|---|
| 340 | \o This function is not available in Qt Script. Use RegExp.exec() or | 
|---|
| 341 | String.search()/match() instead. | 
|---|
| 342 |  | 
|---|
| 343 | \row \o RegExp.exactMatch() | 
|---|
| 344 | \o This function is not available in Qt Script. Use RegExp.exec() instead. | 
|---|
| 345 |  | 
|---|
| 346 | \row \o RegExp.pos() | 
|---|
| 347 | \o This function is not available in Qt Script. Use String.match() instead. | 
|---|
| 348 |  | 
|---|
| 349 | \row \o RegExp.cap() | 
|---|
| 350 | \o This function is not available in Qt Script. RegExp.exec() returns an | 
|---|
| 351 | array of captured texts. | 
|---|
| 352 | \endtable | 
|---|
| 353 |  | 
|---|
| 354 | QSA also defined some internal Qt API which is not present in Qt | 
|---|
| 355 | Script. The types provided by QSA which are not provided by Qt Script are: | 
|---|
| 356 |  | 
|---|
| 357 | \list | 
|---|
| 358 | \o Rect | 
|---|
| 359 | \o Point | 
|---|
| 360 | \o Size | 
|---|
| 361 | \o Color | 
|---|
| 362 | \o Palette | 
|---|
| 363 | \o ColorGroup | 
|---|
| 364 | \o Font | 
|---|
| 365 | \o Pixmap | 
|---|
| 366 | \o ByteArray | 
|---|
| 367 | \endlist | 
|---|
| 368 |  | 
|---|
| 369 |  | 
|---|
| 370 | \section1 The C++ API of QSA vs Qt Script | 
|---|
| 371 |  | 
|---|
| 372 | QSA is more than just a scripting engine. It provides project | 
|---|
| 373 | management, an editor with completion and a minimalistic IDE to edit | 
|---|
| 374 | scriptable projects. Qt Script on the other hand is just a scripting | 
|---|
| 375 | engine. This means that equivalents to the classes \c QSEditor, | 
|---|
| 376 | \c QSScript, \c QSProject and \c QSWorkbench do not exist in Qt Script. | 
|---|
| 377 | QSA also provides some extension APIs through the \c QSUtilFactory and | 
|---|
| 378 | \c QSInputDialogFactory. There is also no equivalent to these classes | 
|---|
| 379 | in the Qt Script API. | 
|---|
| 380 |  | 
|---|
| 381 |  | 
|---|
| 382 | \section2 Making QObjects Accessible from Scripts | 
|---|
| 383 |  | 
|---|
| 384 | There are two different ways of making \l{QObject}s accessible from | 
|---|
| 385 | scripts in QSA. The first method is via the | 
|---|
| 386 | \c QSInterpreter::addTransientObject() and \c QSProject::addObject() | 
|---|
| 387 | functions. In this case objects are added to the global namespace of | 
|---|
| 388 | the interpreter using their object names as the names of the | 
|---|
| 389 | variables. | 
|---|
| 390 |  | 
|---|
| 391 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 16 | 
|---|
| 392 |  | 
|---|
| 393 | The code above adds the button to the global namespace under the name | 
|---|
| 394 | "button". One obvious limitation here is that there is potential for | 
|---|
| 395 | either unnamed \l{QObject}s or objects whose names conflict. Qt Script | 
|---|
| 396 | provides a more flexible way of adding QObjects to the scripting | 
|---|
| 397 | environment. | 
|---|
| 398 |  | 
|---|
| 399 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 17 | 
|---|
| 400 |  | 
|---|
| 401 | In the code above we create a QPushButton and wrap it in a script | 
|---|
| 402 | value using the function, QScriptEngine::newQObject(). This gives us | 
|---|
| 403 | a script value that we put into the global object using the name | 
|---|
| 404 | "button". The concept of objects and properties discussed above is | 
|---|
| 405 | quite visible here in the public C++ API as well. We have no | 
|---|
| 406 | dependency on the object's name and we can also resolve name conflicts | 
|---|
| 407 | more gracefully. Here, we operate directly on QScriptValue objects. | 
|---|
| 408 | This is the actual object that is being passed around inside | 
|---|
| 409 | the script engine, so we actually have low-level access to the | 
|---|
| 410 | internal script data structures, far beyond that which is possible | 
|---|
| 411 | in QSA. Properties, signals and slots of the QObject are accessible | 
|---|
| 412 | to the scripter in Qt Script, just like in QSA. | 
|---|
| 413 |  | 
|---|
| 414 | The other way to expose \l{QObject}s in QSA was to create a | 
|---|
| 415 | \c QSObjectFactory that made it possible to instantiate QObjects from | 
|---|
| 416 | scripts. | 
|---|
| 417 |  | 
|---|
| 418 | Below is listed some code from the filter example in the QSA | 
|---|
| 419 | package. | 
|---|
| 420 |  | 
|---|
| 421 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 18 | 
|---|
| 422 |  | 
|---|
| 423 | The equivalent in Qt Script is written in much the same way as | 
|---|
| 424 | constructors are written in scripts. We register a callback C++ | 
|---|
| 425 | function under the name "ImageSource" in the global namespace and | 
|---|
| 426 | return the QObject from this function: | 
|---|
| 427 |  | 
|---|
| 428 | \snippet doc/src/snippets/code/doc_src_porting-qsa.qdoc 19 | 
|---|
| 429 |  | 
|---|
| 430 | In the Qt Script case we use the same approach that we use to expose | 
|---|
| 431 | a QObject, namely via QScriptEngine::newQObject(). This function also | 
|---|
| 432 | has the benefit that it is possible to specify if the QObject should | 
|---|
| 433 | expose properties and slots of its base class. It is also possible to | 
|---|
| 434 | specify custom ownership rules. | 
|---|
| 435 |  | 
|---|
| 436 | The reader might question why we don't add the constructor function | 
|---|
| 437 | directly into the namespace, but create a meta-object script value for | 
|---|
| 438 | it in addition. The plain function would certainly be good enough, | 
|---|
| 439 | but by creating a QMetaObject based constructor we get the enums on | 
|---|
| 440 | QPushButton for free in the QPushButton function object. Exposing | 
|---|
| 441 | enums in QSA is rather painful in comparison. | 
|---|
| 442 |  | 
|---|
| 443 | If we want to add more "static" data to the QPushButton type in Qt | 
|---|
| 444 | Script, we're free to add properties, similar to how we did for | 
|---|
| 445 | the script. It is also possible to add custom functions to a Qt Script | 
|---|
| 446 | QPushButton instance by setting more properties on it, such as making | 
|---|
| 447 | the \l{QPushButton::}{setText()} C++ function available. It is also | 
|---|
| 448 | possible to acheive this by installing a custom prototype, and be | 
|---|
| 449 | memory efficient, as discussed in the script example above. | 
|---|
| 450 |  | 
|---|
| 451 |  | 
|---|
| 452 | \section2 Accessing Non-QObjects | 
|---|
| 453 |  | 
|---|
| 454 | In QSA, it was possible to expose non-QObjects to QSA by wrapping them | 
|---|
| 455 | in a QObject and using either \c QSWrapperFactory or \c QSObjectFactory | 
|---|
| 456 | to expose them. Deciding when to use each of these classes could be | 
|---|
| 457 | confusing, as one was used for script based construction and the other | 
|---|
| 458 | for wrapping function parameters and return values, but in essence they | 
|---|
| 459 | did exactly the same thing. | 
|---|
| 460 |  | 
|---|
| 461 | In Qt Script, providing access to QObjects and non-QObjects is done in | 
|---|
| 462 | the same way as shown above, by creating a constructor function, and | 
|---|
| 463 | by adding properties or a custom prototype to the constructed object. | 
|---|
| 464 |  | 
|---|
| 465 |  | 
|---|
| 466 | \section2 Data Mapping | 
|---|
| 467 |  | 
|---|
| 468 | QSA supported a hardcoded set of type mappings which covered most | 
|---|
| 469 | of the QVariant types, QObjects and primitives. For more complex type | 
|---|
| 470 | signatures, such as the template-based tool classes, it had rather | 
|---|
| 471 | limited support. Qt Script is significantly better at type mapping | 
|---|
| 472 | and will convert lists of template types into arrays of the | 
|---|
| 473 | appropriate types, given that all the types are declared to the | 
|---|
| 474 | meta-type system. | 
|---|
| 475 | */ | 
|---|