| | 216 | |
| | 217 | === Value Conversion === |
| | 218 | |
| | 219 | When interacting with Qt/C++ objects in JS, it will often be necessary to perform value conversion between the two worlds. For reading properties, QMetaProperty::read() returns a QVariant; this value must be converted to a JS value of a suitable type. For writing properties, QMetaProperty::write() takes a QVariant as argument; hence, the value passed from JS must first be converted to a QVariant of a suitable type. For calling slots, we may have to perform conversion both ways; converting arguments from JS to C++, and converting the slot's return value back to JS. |
| | 220 | |
| | 221 | The two "top-level" Qt/C++ <--> JS conversion functions are: |
| | 222 | |
| | 223 | * '''qtVariantToJS(QVariant) : JSValue''': Converts a QVariant to a JS value. |
| | 224 | * '''qtVariantFromJS(JSValue) : QVariant''': Converts a JSValue to a QVariant. |
| | 225 | |
| | 226 | A QVariant can contain a value of any type known to the Qt meta-type system; this includes both QMetaType's built-in types (bool, int, QString, etc.) and custom (user) types. |
| | 227 | |
| | 228 | A QVariant's meta-type can be obtained from QVariant::userType(). A void pointer to the value can be obtained from QVariant::constData(). For example, if the type is QMetaType::Double, it's safe to cast the data pointer to double*; if the type is QMetaType::QString, it's safe to cast the data pointer to QString*; and so on. |
| | 229 | |
| | 230 | Given a meta-type, storage for a value of that type can be allocated using the QMetaType(int type, const void *data) constructor. |
| | 231 | |
| | 232 | We introduce two helper functions to convert between (userType, data*) pairs and JS values: |
| | 233 | |
| | 234 | * '''qtMetaTypeToJS(int, void*) : JSValue''': Converts a meta-type to a JS value. |
| | 235 | * '''qtMetaTypeFromJS(JSValue, int, void*) : bool''': Converts a JSValue to a meta-type. |
| | 236 | |
| | 237 | These functions are essentially huge switches on the type argument, that cast the data pointer and get/set the value accordingly. |
| | 238 | |
| | 239 | Some non-primitive types have special handling: |
| | 240 | |
| | 241 | * QDateTime: Converted from/to JS Date object. |
| | 242 | * QRegExp: Converted from/to JS RegExp object. |
| | 243 | * QStringList: Converted from/to JS Array object. |
| | 244 | * QVariantList: Converted from/to JS Array object. |
| | 245 | * QVariantMap: Converted from/to JS Object object. |
| | 246 | |
| | 247 | In many cases there is no "good" conversion between a C++ type and JS. For example, there's no obvious way to convert a QPixmap to a JS object. For types where no "standard" (read: automagic) conversion makes sense, including user types, QtScript falls back to creating a JS wrapper object that contains the QVariant. |
| | 248 | |
| | 249 | It's possible to override QtScript's conversion of any type by registering a pair of conversion functions for the type using qScriptRegisterMetaType(). |