| 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 | */
|
|---|