QScriptEngine Class
The QScriptEngine class provides an environment for evaluating Qt Script code. More...
| Header: | #include <QScriptEngine> |
| qmake: | QT += script |
| Since: | Qt 4.3 |
| Inherits: | QObject |
This class was introduced in Qt 4.3.
Note: All functions in this class are reentrant.
Public Types
| typedef | FunctionSignature |
| typedef | FunctionWithArgSignature |
| enum | QObjectWrapOption { ExcludeChildObjects, ExcludeSuperClassMethods, ExcludeSuperClassProperties, ExcludeSuperClassContents, ExcludeDeleteLater, …, SkipMethodsInEnumeration } |
| enum | ValueOwnership { QtOwnership, ScriptOwnership, AutoOwnership } |
Macros
| Q_SCRIPT_DECLARE_QMETAOBJECT(QMetaObject, ArgType) |
Detailed Description
See the Qt Script documentation for information about the Qt Script language, and how to get started with scripting your C++ application.
Evaluating Scripts
Use evaluate() to evaluate script code; this is the C++ equivalent of the built-in script function eval().
QScriptEngine myEngine; QScriptValue three = myEngine.evaluate("1 + 2");
evaluate() returns a QScriptValue that holds the result of the evaluation. The QScriptValue class provides functions for converting the result to various C++ types (e.g. QScriptValue::toString() and QScriptValue::toNumber()).
The following code snippet shows how a script function can be defined and then invoked from C++ using QScriptValue::call():
QScriptValue fun = myEngine.evaluate("(function(a, b) { return a + b; })"); QScriptValueList args; args << 1 << 2; QScriptValue threeAgain = fun.call(QScriptValue(), args);
As can be seen from the above snippets, a script is provided to the engine in the form of a string. One common way of loading scripts is by reading the contents of a file and passing it to evaluate():
QString fileName = "helloworld.qs"; QFile scriptFile(fileName); if (!scriptFile.open(QIODevice::ReadOnly)) // handle error QTextStream stream(&scriptFile); QString contents = stream.readAll(); scriptFile.close(); myEngine.evaluate(contents, fileName);
Here we pass the name of the file as the second argument to evaluate(). This does not affect evaluation in any way; the second argument is a general-purpose string that is used to identify the script for debugging purposes (for example, our filename will now show up in any uncaughtExceptionBacktrace() involving the script).
Engine Configuration
The globalObject() function returns the Global Object associated with the script engine. Properties of the Global Object are accessible from any script code (i.e. they are global variables). Typically, before evaluating "user" scripts, you will want to configure a script engine by adding one or more properties to the Global Object:
myEngine.globalObject().setProperty("myNumber", 123); ... QScriptValue myNumberPlusOne = myEngine.evaluate("myNumber + 1");
Adding custom properties to the scripting environment is one of the standard means of providing a scripting API that is specific to your application. Usually these custom properties are objects created by the newQObject() or newObject() functions, or constructor functions created by newFunction().
Script Exceptions
evaluate() can throw a script exception (e.g. due to a syntax error); in that case, the return value is the value that was thrown (typically an Error object). You can check whether the evaluation caused an exception by calling hasUncaughtException(). In that case, you can call toString() on the error object to obtain an error message. The current uncaught exception is also available through uncaughtException(). Calling clearExceptions() will cause any uncaught exceptions to be cleared.
QScriptValue result = myEngine.evaluate(...); if (myEngine.hasUncaughtException()) { int line = myEngine.uncaughtExceptionLineNumber(); qDebug() << "uncaught exception at line" << line << ":" << result.toString(); }
The checkSyntax() function can be used to determine whether code can be usefully passed to evaluate().
Script Object Creation
Use newObject() to create a standard Qt Script object; this is the C++ equivalent of the script statement new Object(). You can use the object-specific functionality in QScriptValue to manipulate the script object (e.g. QScriptValue::setProperty()). Similarly, use newArray() to create a Qt Script array object. Use newDate() to create a Date object, and newRegExp() to create a RegExp object.
QObject Integration
Use newQObject() to wrap a QObject (or subclass) pointer. newQObject() returns a proxy script object; properties, children, and signals and slots of the QObject are available as properties of the proxy object. No binding code is needed because it is done dynamically using the Qt meta object system.
QPushButton button; QScriptValue scriptButton = myEngine.newQObject(&button); myEngine.globalObject().setProperty("button", scriptButton); myEngine.evaluate("button.checkable = true"); qDebug() << scriptButton.property("checkable").toBoolean(); scriptButton.property("show").call(); // call the show() slot
Use qScriptConnect() to connect a C++ signal to a script function; this is the Qt Script equivalent of QObject::connect(). When a script function is invoked in response to a C++ signal, it can cause a script exception; you can connect to the signalHandlerException() signal to catch such an exception.
Use newQMetaObject() to wrap a QMetaObject; this gives you a "script representation" of a QObject-based class. newQMetaObject() returns a proxy script object; enum values of the class are available as properties of the proxy object. You can also specify a function that will be used to construct objects of the class (e.g. when the constructor is invoked from a script). For classes that have a "standard" Qt constructor, Qt Script can provide a default script constructor for you; see scriptValueFromQMetaObject().
See Making Applications Scriptable for more information on the QObject integration.
Support for Custom C++ Types
Use newVariant() to wrap a QVariant. This can be used to store values of custom (non-QObject) C++ types that have been registered with the Qt meta-type system. To make such types scriptable, you typically associate a prototype (delegate) object with the C++ type by calling setDefaultPrototype(); the prototype object defines the scripting API for the C++ type. Unlike the QObject integration, there is no automatic binding possible here; i.e. you have to create the scripting API yourself, for example by using the QScriptable class.
Use fromScriptValue() to cast from a QScriptValue to another type, and toScriptValue() to create a QScriptValue from another value. You can specify how the conversion of C++ types is to be performed with qScriptRegisterMetaType() and qScriptRegisterSequenceMetaType(). By default, Qt Script will use QVariant to store values of custom types.
Importing Extensions
Use importExtension() to import plugin-based extensions into the engine. Call availableExtensions() to obtain a list naming all the available extensions, and importedExtensions() to obtain a list naming only those extensions that have been imported.
Call pushContext() to open up a new variable scope, and popContext() to close the current scope. This is useful if you are implementing an extension that evaluates script code containing temporary variable definitions (e.g. var foo = 123;) that are safe to discard when evaluation has completed.
Native Functions
Use newFunction() to wrap native (C++) functions, including constructors for your own custom types, so that these can be invoked from script code. Such functions must have the signature QScriptEngine::FunctionSignature. You may then pass the function as argument to newFunction(). Here is an example of a function that returns the sum of its first two arguments:
QScriptValue myAdd(QScriptContext *context, QScriptEngine *engine) { QScriptValue a = context->argument(0); QScriptValue b = context->argument(1); return a.toNumber() + b.toNumber(); }
To expose this function to script code, you can set it as a property of the Global Object:
QScriptValue fun = myEngine.newFunction(myAdd); myEngine.globalObject().setProperty("myAdd", fun);
Once this is done, script code can call your function in the exact same manner as a "normal" script function:
QScriptValue result = myEngine.evaluate("myAdd(myNumber, 1)");
Long-running Scripts
If you need to evaluate possibly long-running scripts from the main (GUI) thread, you should first call setProcessEventsInterval() to make sure that the GUI stays responsive. You can abort a currently running script by calling abortEvaluation(). You can determine whether an engine is currently running a script by calling isEvaluating().
Garbage Collection
Qt Script objects may be garbage collected when they are no longer referenced. There is no guarantee as to when automatic garbage collection will take place.
The collectGarbage() function can be called to explicitly request garbage collection.
The reportAdditionalMemoryCost() function can be called to indicate that a Qt Script object occupies memory that isn't managed by the scripting environment. Reporting the additional cost makes it more likely that the garbage collector will be triggered. This can be useful, for example, when many custom, native Qt Script objects are allocated.
Core Debugging/Tracing Facilities
Since Qt 4.4, you can be notified of events pertaining to script execution (e.g. script function calls and statement execution) through the QScriptEngineAgent interface; see the setAgent() function. This can be used to implement debugging and profiling of a QScriptEngine.
See also QScriptValue, QScriptContext, and QScriptEngineAgent.
Member Type Documentation
typedef QScriptEngine::FunctionSignature
The function signature QScriptValue f(QScriptContext *, QScriptEngine *).
A function with such a signature can be passed to QScriptEngine::newFunction() to wrap the function.
typedef QScriptEngine::FunctionWithArgSignature
The function signature QScriptValue f(QScriptContext *, QScriptEngine *, void *).
A function with such a signature can be passed to QScriptEngine::newFunction() to wrap the function.
enum QScriptEngine::QObjectWrapOption
These flags specify options when wrapping a QObject pointer with newQObject().
| Constant | Value | Description |
|---|---|---|
QScriptEngine::ExcludeChildObjects | 0x0001 | The script object will not expose child objects as properties. |
QScriptEngine::ExcludeSuperClassMethods | 0x0002 | The script object will not expose signals and slots inherited from the superclass. |
QScriptEngine::ExcludeSuperClassProperties | 0x0004 | The script object will not expose properties inherited from the superclass. |
QScriptEngine::ExcludeSuperClassContents | 0x0006 | Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties |
QScriptEngine::ExcludeDeleteLater | 0x0010 | The script object will not expose the QObject::deleteLater() slot. |
QScriptEngine::ExcludeSlots | 0x0020 | The script object will not expose the QObject's slots. |
QScriptEngine::AutoCreateDynamicProperties | 0x0100 | Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object. |
QScriptEngine::PreferExistingWrapperObject | 0x0200 | If a wrapper object with the requested configuration already exists, return that object. |
QScriptEngine::SkipMethodsInEnumeration | 0x0008 | Don't include methods (signals and slots) when enumerating the object's properties. |
enum QScriptEngine::ValueOwnership
This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject().
| Constant | Value | Description |
|---|---|---|
QScriptEngine::QtOwnership | 0 | The standard Qt ownership rules apply, i.e. the associated object will never be explicitly deleted by the script engine. This is the default. (QObject ownership is explained in Object Trees & Ownership.) |
QScriptEngine::ScriptOwnership | 1 | The value is owned by the script environment. The associated data will be deleted when appropriate (i.e. after the garbage collector has discovered that there are no more live references to the value). |
QScriptEngine::AutoOwnership | 2 | If the associated object has a parent, the Qt ownership rules apply (QtOwnership); otherwise, the object is owned by the script environment (ScriptOwnership). |
Macro Documentation
Q_SCRIPT_DECLARE_QMETAOBJECT(QMetaObject, ArgType)
Declares the given QMetaObject. Used in combination with QScriptEngine::scriptValueFromQMetaObject() to make enums and instantiation of QMetaObject available to script code. The constructor generated by this macro takes a single argument of type ArgType; typically the argument is the parent type of the new instance, in which case ArgType is QWidget* or QObject*. Objects created by the constructor will have QScriptEngine::AutoOwnership ownership.
This function was introduced in Qt 4.3.