Qt 5.5 中Qt Script翻译 (三)

接着上一章的讲解

枚举值

用Q_ENUMS声明的枚举值不能作为单个封装对象的属性使用,然而,如果他们是QMetaObject封装的对象就可以通过用QScriptEngine::newQMetaObject()创建。

Qt C++类型与脚本类型之间的转换

Qt脚本能执行脚本到C++端的类型转换,例如,当一个C++信号触发一个脚本函数时,当你在脚本中调用一个QObject属性时

当你在C++中调用QScriptEngine::toScriptValue()或者QScriptEngine::fromScriptValue()时, Qt提供了很多内建的类型转换操作,你也能用qScriptRegisterMetaType()为自己的类型注册转换操作。

默认的Qt脚本到C++的转换

下面的表描述了默认的Qt脚本到C++的转换

C++ Type	Default Conversion
bool	    QScriptValue::toBool()
int	        QScriptValue::toInt32()
uint	    QScriptValue::toUInt32()
float	    float(QScriptValue::toNumber())
double	    QScriptValue::toNumber()
short	    short(QScriptValue::toInt32())
ushort	    QScriptValue::toUInt16()
char	    char(QScriptValue::toInt32())
uchar	    unsigned char(QScriptValue::toInt32())
long	    long(QScriptValue::toInteger())
ulong	    ulong(QScriptValue::toInteger())
qlonglong	qlonglong(QScriptValue::toInteger())
qulonglong	qulonglong(QScriptValue::toInteger())
QString	    QScriptValue::toString() 如果QScriptValue 是null或者undefined则字符串是空的;
QDateTime	QScriptValue::toDateTime()
QDate	    QScriptValue::toDateTime().date()
QRegExp	    QScriptValue::toRegExp()
QObject*	QScriptValue::toQObject()
QWidget*	QScriptValue::toQObject()
QVariant	QScriptValue::toVariant()

QChar	    If the QScriptValue is a string, the result is the first character of the string, or a null QChar if the string is empty; otherwise, the result is a QChar constructed from the unicode obtained by converting the QScriptValue to a ushort.
QStringList	If the QScriptValue is an array, the result is a QStringList constructed from the result of QScriptValue::toString() for each array element; otherwise, the result is an empty QStringList.

QVariantList	If the QScriptValue is an array, the result is a QVariantList constructed from the result of QScriptValue::toVariant() for each array element; otherwise, the result is an empty QVariantList.

QVariantMap	If the QScriptValue is an object, the result is a QVariantMap with a (key, value) pair of the form (propertyName, propertyValue.toVariant()) for each property, using QScriptValueIterator to iterate over the object's properties.

QObjectList	If the QScriptValue is an array, the result is a QObjectList constructed from the result of QScriptValue::toQObject() for each array element; otherwise, the result is an empty QObjectList.

QList<int>	If the QScriptValue is an array, the result is a QList<int> constructed from the result of QScriptValue::toInt32() for each array element; otherwise, the result is an empty QList<int>.

另外,Qt脚本也执行下面的操作:

  • 如果QScriptValue是一个QObject,目标类型名称是指针,可以用qobject_cast()转换。
  • 如果QScriptValue是一个QVariant,目标类型名称是指针,QVariant的userType()是目标类型的指针类型,转换结果是一个QVarient数据的指针。
  • 如果QScriptValue是一个QVariant,并且能通过QVariant::canConvert()知道可以进行转换,可以用qvaraint_cast()转换。

默认的从C++到脚本的转换

C++ Type	Default Construction
void	QScriptEngine::undefinedValue()
bool	QScriptValue(engine, value)
int	QScriptValue(engine, value)
uint	QScriptValue(engine, value)
float	QScriptValue(engine, value)
double	QScriptValue(engine, value)
short	QScriptValue(engine, value)
ushort	QScriptValue(engine, value)
char	QScriptValue(engine, value)
uchar	QScriptValue(engine, value)
QString	QScriptValue(engine, value)
long	If the input fits in an int, QScriptValue(engine, int(value)); otherwise, QScriptValue(engine, double(value)). Note that the latter conversion can be lossy.
ulong	If the input fits in a uint, QScriptValue(engine, uint(value)); otherwise, QScriptValue(engine, double(value)). Note that the latter conversion can be lossy.
qlonglong	QScriptValue(engine, qsreal(value)). Note that the conversion may lead to loss of precision, since not all 64-bit integers can be represented using the qsreal type.
qulonglong	QScriptValue(engine, qsreal(value)). Note that the conversion may lead to loss of precision, since not all 64-bit unsigned integers can be represented using the qsreal type.
QChar	QScriptValue(this, value.unicode())
QDateTime	QScriptEngine::newDate(value)
QDate	QScriptEngine::newDate(value)
QRegExp	QScriptEngine::newRegExp(value)
QObject*	QScriptEngine::newQObject(value)
QWidget*	QScriptEngine::newQObject(value)
QVariant	QScriptEngine::newVariant(value)
QStringList	A new script array (created with QScriptEngine::newArray()), whose elements are created using the QScriptValue(QScriptEngine *, QString) constructor for each element of the list.
QVariantList	A new script array (created with QScriptEngine::newArray()), whose elements are created using QScriptEngine::newVariant() for each element of the list.
QVariantMap	A new script object (created with QScriptEngine::newObject()), whose properties are initialized according to the (key, value) pairs of the map.
QObjectList	A new script array (created with QScriptEngine::newArray()), whose elements are created using QScriptEngine::newQObject() for each element of the list.
QList<int>	A new script array (created with QScriptEngine::newArray()), whose elements are created using the QScriptValue(QScriptEngine *, int) constructor for each element of the list.

其他的类型(包括自定义类型)用 QScriptEngine::newVariant()封装,任何类型的空指针用QScriptEngine::nullValue()封装。

如何设计和实现一个应用程序对象

本节解释如何实现应用程序对象,并提供必要的技术背景材料。

在脚本中创建一个C++对象

让C++类和对象在脚本语言中可用是没有意义的,因为脚本语言更具有动态性,并且必须能够在运行时自查对象(查询函数信息,例如函数名、函数签名、属性等)。标准C++没有为此提供特性。

我们可以通过扩展C++来实现我们想要的功能,使用C++自己的功能,所以我们的代码仍然是标准的C++。Qt元对象系统提供必要的附加功能。它允许我们使用扩展的C++语法编写,但是使用一个称为MOC(元对象编译器)的小型实用程序将其转换成标准C++。希望利用元对象工具的类是QObject的子类,或者使用Q_OBJECT宏。QT多年来一直使用这种方法,并且已经证明是可靠的。Qt脚本使用这个元对象技术为脚本提供了对C++类和对象的动态访问。

要完全理解如何使C++对象可以用于QT脚本,对QT元对象系统的一些基本知识是非常有帮助的。我们建议您阅读 Object Model 和 Meta-Object System,这对于理解如何实现应用程序对象很有用。

然而,在最简单的情况下,这种知识并不重要。要使对象在Qt脚本中可用,必须从QObject派生。从QObject派生的所有类都可以自查,并且可以在运行时提供脚本引擎所需的信息;例如,类名、函数、签名。因为我们在运行时动态地获得关于类所需的信息,所以不需要为QObject派生类编写包装器。

c++的成员函数在脚本中可用

元对象系统还使有关信号和槽的信息在运行时动态可用。默认情况下,对于QObject子类,只有信号和插槽自动对脚本可用。这是非常方便的,因为在实践中,我们通常只希望对脚本程序提供指定的函数。创建QObject子类时,请确保要向Qt Script公开的函数是公共插槽。

例如,下面的类定义仅为某些函数启用脚本

class MyObject : public QObject
{
    Q_OBJECT

public:
    MyObject( ... );

    void aNonScriptableFunction();

public slots: // these functions (slots) will be available in Qt Script
    void calculate( ... );
    void setEnabled( bool enabled );
    bool isEnabled() const;

private:
   ....

};

上面的例子,aNonScriptableFunction()函数没有申明为slot,所以它在脚本中是不可用的,其他的三个函数在脚本中是可用的,因为他们被声明为public slots。

如果想任何函数在脚本中可用,必须将函数指定为Q_INVOKABLE。(这样就会将该函数加入到meta-object中

class MyObject : public QObject
{
    Q_OBJECT

    public:
    Q_INVOKABLE void thisMethodIsInvokableInQtScript();
    void thisMethodIsNotInvokableInQtScript();

    ...
};

一旦用Q_INVOKABLE声明,就可以从Qt脚本代码调用该方法,就像它是一个插槽一样。尽管这样的方法不是插槽,但是您仍然可以在脚本代码中将指定为connect()的目标函数;connet()接受本机函数和非本机函数作为目标。

正如默认的从Qt脚本到C++的转换所讨论的,Qt脚本处理许多C++类型的转换。如果函数接受Qt Script不处理转换的参数,则需要提供转换函数。这是使用qScript TrestMyTyType()函数完成的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值