[Qt-interest] Fail to disconnect a signal/slot in QtScript
Laurent Gomila
laurent.gom at gmail.com
Wed Jun 23 09:37:18 CEST 2010
Hi
I found a situation where disconnecting a signal in a script doesn't
succeed, although I think the code is perfectly valid. This happens
when the slot belongs to a QObject which is returned by a property of
another QObject.
Here is a complete and minimal code demonstrating the issue:
----------------------------------------------------------------------------------------------------------
#include <QCoreApplication>
#include <QTimer>
#include <QScriptEngine>
#include <QScriptValue>
#include <QtDebug>
class MyObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* subObject READ subObject);
public:
MyObject(QObject* subObject) : m_subObject(subObject) {}
QObject* subObject() const {return m_subObject;}
private:
QObject* m_subObject;
};
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
QTimer timer;
MyObject object(&app);
QScriptEngine engine;
engine.globalObject().setProperty("timer", engine.newQObject(&timer));
engine.globalObject().setProperty("object", engine.newQObject(&object));
engine.evaluate("timer.timeout.connect(object.subObject.quit);"
"timer.timeout.disconnect(object.subObject.quit);");
if (engine.hasUncaughtException())
qDebug() << engine.uncaughtException().toString();
return app.exec();
}
----------------------------------------------------------------------------------------------------------
Here is the console output:
"Error: Function.prototype.disconnect: failed to disconnect from
QTimer::timeout()"
I found that the failure happens in qscriptobject.cpp, line 2282. The
expression "if (c.hasTarget(receiver, slot))" returns false, and
hasTarget fails on "s == slot".
So I tried to somehow make it work by wrapping my slot in a single
script variable, and indeed it doesn't fail anymore
----------------------------------------------------------------------------------------------------------
engine.evaluate("var slot = object.subObject.quit;"
"timer.timeout.connect(slot);"
"timer.timeout.disconnect(slot);");
----------------------------------------------------------------------------------------------------------
Wrapping the object works too:
----------------------------------------------------------------------------------------------------------
engine.evaluate("var subObject = object.subObject;"
"timer.timeout.connect(subObject.quit);"
"timer.timeout.disconnect(subObject.quit);");
----------------------------------------------------------------------------------------------------------
So I think this may be a bug. I'm using Qt 4.6.3 on Windows with
Visual C++ 2008.
More information about the Qt-interest-old
mailing list