the myObject line is from the Documentation.
in my case it is a QTextEdit (inherited by Console) created in the GUI thread and registered in the scriptEngine (which is in the script thread).
Mainwindow.cpp:
console = new Console(this);
script = new ScriptThread(this);
script->attachConsole(console);
console = new Console(this);
script = new ScriptThread(this);
script->attachConsole(console);
To copy to clipboard, switch view to plain text mode
console.h:
#ifndef CONSOLE_H
#define CONSOLE_H
#include <QWidget>
#include <QTextEdit>
{
Q_OBJECT
public:
explicit Console
(QWidget *parent
= 0);
signals:
public slots:
void clr();
};
#endif // CONSOLE_H
#ifndef CONSOLE_H
#define CONSOLE_H
#include <QWidget>
#include <QTextEdit>
Q_DECLARE_METATYPE(QTextCursor)
Q_DECLARE_METATYPE(QTextCharFormat)
class Console : public QTextEdit
{
Q_OBJECT
public:
explicit Console(QWidget *parent = 0);
signals:
public slots:
void write(QString string);
void write(QString string, QString color);
void clr();
};
#endif // CONSOLE_H
To copy to clipboard, switch view to plain text mode
scriptthread.h:
#ifndef SCRIPTTHREAD_H
#define SCRIPTTHREAD_H
#include <QThread>
#include <QtScript/QScriptEngine>
#include <QPushButton>
#include "console.h"
class ScriptThread
: public QThread{
Q_OBJECT
public:
explicit ScriptThread
(QObject *parent
= 0);
void run() Q_DECL_OVERRIDE;
void attachConsole(Console* console);
signals:
void scriptFinished();
public slots:
private:
QScriptEngine* scriptEngine;
Console* m_console;
QScriptContext* ctx;
};
#endif // SCRIPTTHREAD_H
#ifndef SCRIPTTHREAD_H
#define SCRIPTTHREAD_H
#include <QThread>
#include <QtScript/QScriptEngine>
#include <QPushButton>
#include "console.h"
class ScriptThread : public QThread
{
Q_OBJECT
public:
explicit ScriptThread(QObject *parent = 0);
void run() Q_DECL_OVERRIDE;
void addScriptableObject(QString name, QObject* obj);
void attachConsole(Console* console);
signals:
void set(QString name, QVariant value);
void scriptFinished();
public slots:
private:
QScriptEngine* scriptEngine;
QString code;
Console* m_console;
QScriptContext* ctx;
};
#endif // SCRIPTTHREAD_H
To copy to clipboard, switch view to plain text mode
console.cpp:
Console
::Console(QWidget *parent
) :{
qRegisterMetaType<QTextCursor>("QTextCursor");
qRegisterMetaType<QTextCharFormat>("QTextCharFormat");
setReadOnly(true);
setFontFamily("monospace");
setStyleSheet("QTextEdit { background-color: 'black'; }");
setTextColor
(QColor("white"));
}
void Console
::write(QString string
) {
setTextColor
(QColor("White"));
append(string);
//QMetaObject::invokeMethod(this,"setTextColor",Qt::QueuedConnection,Q_ARG(QColor,QColor("white")));
//QMetaObject::invokeMethod(this,"append",Qt::QueuedConnection,Q_ARG(QString, string));
}
{
append(string);
//QMetaObject::invokeMethod(this,"setTextColor",Qt::QueuedConnection,Q_ARG(QColor,QColor(color)));
//QMetaObject::invokeMethod(this,"append",Qt::QueuedConnection,Q_ARG(QString, string));
}
void Console::clr()
{
//textEdit->clear();
QMetaObject::invokeMethod(this,
"clear",Qt
::QueuedConnection);
}
Console::Console(QWidget *parent) :
QTextEdit(parent)
{
qRegisterMetaType<QTextCursor>("QTextCursor");
qRegisterMetaType<QTextCharFormat>("QTextCharFormat");
setReadOnly(true);
setFontFamily("monospace");
setStyleSheet("QTextEdit { background-color: 'black'; }");
setTextColor(QColor("white"));
}
void Console::write(QString string)
{
setTextColor(QColor("White"));
append(string);
//QMetaObject::invokeMethod(this,"setTextColor",Qt::QueuedConnection,Q_ARG(QColor,QColor("white")));
//QMetaObject::invokeMethod(this,"append",Qt::QueuedConnection,Q_ARG(QString, string));
}
void Console::write(QString string, QString color)
{
setTextColor(QColor(color));
append(string);
//QMetaObject::invokeMethod(this,"setTextColor",Qt::QueuedConnection,Q_ARG(QColor,QColor(color)));
//QMetaObject::invokeMethod(this,"append",Qt::QueuedConnection,Q_ARG(QString, string));
}
void Console::clr()
{
//textEdit->clear();
QMetaObject::invokeMethod(this,"clear",Qt::QueuedConnection);
}
To copy to clipboard, switch view to plain text mode
script.cpp:
ScriptThread
::ScriptThread(QObject *parent
) :{
code = "console.write(\"testing console color capabilities\");\n"
"button.text = \"This is a scriptable Button!\";\n"
"button.show();\n"
"for(i=0;i<100;i++){\n"
"time.sleep_ms(20);console.write(i+\"%\")}\n"
"console.write(\"OK\",\"red\");\n"
"time.sleep_ms(1000);\n"
"//console.clr();\n"
"button.hide();"
"console.write(\"exiting\");\n";
scriptEngine = new QScriptEngine();
ctx = scriptEngine->pushContext();
}
void ScriptThread::run()
{
if (m_console != NULL)
{
if (scriptEngine->canEvaluate(code))
{
m_console->write("Script seems to be ok, starting...\n");
scriptEngine->evaluate(code);
if (scriptEngine->hasUncaughtException())
{
m_console->write("Error at: " + scriptEngine->uncaughtException().toString());
}
} else {
m_console->write("Script contains errors!\n");
}
scriptEngine->popContext();
scriptEngine->collectGarbage();
}
}
{
ctx->activationObject().setProperty(name, scriptEngine->newQObject(obj));
}
void ScriptThread::attachConsole(Console *console)
{
m_console = console;
ctx->activationObject().setProperty("console",scriptEngine->newQObject(m_console));
}
ScriptThread::ScriptThread(QObject *parent) :
QThread(parent)
{
code = "console.write(\"testing console color capabilities\");\n"
"button.text = \"This is a scriptable Button!\";\n"
"button.show();\n"
"for(i=0;i<100;i++){\n"
"time.sleep_ms(20);console.write(i+\"%\")}\n"
"console.write(\"OK\",\"red\");\n"
"time.sleep_ms(1000);\n"
"//console.clr();\n"
"button.hide();"
"console.write(\"exiting\");\n";
scriptEngine = new QScriptEngine();
ctx = scriptEngine->pushContext();
}
void ScriptThread::run()
{
if (m_console != NULL)
{
if (scriptEngine->canEvaluate(code))
{
m_console->write("Script seems to be ok, starting...\n");
scriptEngine->evaluate(code);
if (scriptEngine->hasUncaughtException())
{
m_console->write("Error at: " + scriptEngine->uncaughtException().toString());
}
} else {
m_console->write("Script contains errors!\n");
}
scriptEngine->popContext();
scriptEngine->collectGarbage();
}
}
void ScriptThread::addScriptableObject(QString name, QObject *obj)
{
ctx->activationObject().setProperty(name, scriptEngine->newQObject(obj));
}
void ScriptThread::attachConsole(Console *console)
{
m_console = console;
ctx->activationObject().setProperty("console",scriptEngine->newQObject(m_console));
}
To copy to clipboard, switch view to plain text mode
In the console.cpp I set breakpoints inside the Console::write() slot. As far as I understood slots are directly called from the script as mentioned in the documentation, there is no "emit" command in javascript.
As a workaround I changed the thread on which the slot is called by manually invoking the slot with:
QMetaObject::invokeMethod(this,"setTextColor",Qt::QueuedConnection,Q_ARG(QColor,QColor("white")));
To copy to clipboard, switch view to plain text mode
which works as expected. But i would assume that methods declared as slots are automatically invoked by the scriptengine instead of being called directly, especially since there is no emit function! Did i understand something wrong about the idea of the scriptengine?
Thanks, Lukas
Bookmarks