Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, July 2007
QtScript bug calling C++ functions with QVariant arguments


Message 1 in thread

Given these 2 C++ slots within a QObject made available to QtScript:

public Q_SLOTS:
  void foo(const QVariant& a1);
  void bar(const QVariant& a1, int a2 = 1);



These calls in QtScript will both fail with the message "incorrect number or
type of arguments in call to ...":

obj.foo(1);
obj.bar(1);



However this call will work without error:

obj.bar(1, 1);


Can anybody confirm?
Any workaround of patch available?


Thanks,
  Seneca


--
 [ signature omitted ] 

Message 2 in thread

Yet another bug where converting from QVariant fails:

The method in C++ QObject:

  public Q_SLOTS:
    QVariant foo() const { return QVariant(1); }


The QtScript code:

  print(obj.foo()); // prints: "undefined" instead of "1"


This leaves QVariant completely unusable as arguments or return values of
C++ methods in the current Qt 4.3.0 release.

--
 [ signature omitted ] 

Message 3 in thread

Seneca wrote:
> Yet another bug where converting from QVariant fails:
>
> The method in C++ QObject:
>
>   public Q_SLOTS:
>     QVariant foo() const { return QVariant(1); }
>
>
> The QtScript code:
>
>   print(obj.foo()); // prints: "undefined" instead of "1"
>
>
> This leaves QVariant completely unusable as arguments or return values of
> C++ methods in the current Qt 4.3.0 release.
>   
Hi Seneca,
This is fixed for 4.3.1. The work-around for 4.3.0 is to do

Q_DECLARE_METATYPE(QVariant)

and then

qMetaTypeId<QVariant>();

somewhere in your application.

Regards,
Kent

--
 [ signature omitted ] 

Message 4 in thread

Thanks very much Kent, 

Everything works perfectly now with your workaround!


> This is fixed for 4.3.1. The work-around for 4.3.0 is to do
> 
> Q_DECLARE_METATYPE(QVariant)
> 
> and then
> 
> qMetaTypeId<QVariant>();
> 
> somewhere in your application.

--
 [ signature omitted ] 

Message 5 in thread

Hi!

 > Q_DECLARE_METATYPE(QVariant)
 >
 > and then
 >
 > qMetaTypeId<QVariant>();
 >
 > somewhere in your application.


I had no luck with this... I tried, but for example if I have a String 
in a QVariant I will get something like "variant(QString, )" in the 
script itself (or I did not understand the concept of QVariant in an 
Scripting Envrironment).

Finally I wrote the following function:

QScriptValue workaroundVariant2ScripValue(QScriptEngine *e, QVariant var)
{
	switch(var.type())
	{
	case QVariant::Invalid:
		return e->nullValue();
	case QVariant::Bool:
		return QScriptValue(e, var.toBool());
	case QVariant::Date:
		return e->newDate(var.toDateTime());
	case QVariant::DateTime:
		return e->newDate(var.toDateTime());
	case QVariant::Double:
		return QScriptValue(e, var.toDouble());
	case QVariant::Int:
	case QVariant::LongLong:
		return QScriptValue(e, var.toInt());
	case QVariant::String:
		return QScriptValue(e, var.toString());
	case QVariant::Time:
		return e->newDate(var.toDateTime());
	case QVariant::UInt:
		return QScriptValue(e, var.toUInt());
	}

	if(var.isNull())
		return e->nullValue();

	// bad but better then nothing
	return QScriptValue(e, var.toString());
}

This works... (for me).

Greetings

Niklas

--
 [ signature omitted ] 

Message 6 in thread

> 
> QScriptValue workaroundVariant2ScripValue(QScriptEngine *e, QVariant var)

sorry, made a mistake. This one is ok (isNull() check first):

QScriptValue workaroundVariant2ScriptValue(QScriptEngine *e, QVariant var)
{
	if(var.isNull())
		return e->nullValue();

	switch(var.type())
	{
	case QVariant::Invalid:
		return e->nullValue();
	case QVariant::Bool:
		return QScriptValue(e, var.toBool());
	case QVariant::Date:
		return e->newDate(var.toDateTime());
	case QVariant::DateTime:
		return e->newDate(var.toDateTime());
	case QVariant::Double:
		return QScriptValue(e, var.toDouble());
	case QVariant::Int:
	case QVariant::LongLong:
		return QScriptValue(e, var.toInt());
	case QVariant::String:
		return QScriptValue(e, var.toString());
	case QVariant::Time:
		return e->newDate(var.toDateTime());
	case QVariant::UInt:
		return QScriptValue(e, var.toUInt());
	}

	// bad but better then nothing
	return QScriptValue(e, var.toString());
}

--
 [ signature omitted ]