Название: Иммитация include в QtScript [решено]
Отправлено: dd от Февраль 20, 2011, 02:19
В моей программе долучился достаточно длинный скрипт, писать в одном файле стало очень неудобно. Возникла необходимость разбить один скрипт на файлы. Изменил текст сообщения, дабы не смущать других.Работает так (код скрипта): CEngine.doScript("my_file1.js") CEngine.doScript("my_file2.js") CEngine.doScript("my_file3.js")
CEngine - это объект из программы (главный синглтон), переданный в движок скрипта функцией: pEngine->globalObject().setProperty("CEngine", pEngine->newQObject(CEngine::Get())); и который просто вызывает QScriptEngine::evaluate() с новым файлом. Вот ко функции doScript (код C++): void CEngine::doScript(QString fileName) { if(!m_pScriptEngineMain) return;
QFile scriptFile(QDir::currentPath() + "/files/" + fileName); scriptFile.open(QIODevice::ReadOnly); if(scriptFile.isOpen()) { m_pScriptEngineMain->evaluate(scriptFile.readAll()); } }
Название: Re: Иммитация include в QtScript [решено]
Отправлено: dd от Февраль 21, 2011, 15:23
В данном решении есть один нюанс. Так и не понял в чем дело. Если в одно файле я описываю функцию так: то в другом файле после инклюда она не видна. А видна только если описать ее так: Старнное поведение. Лечится это, если использовать встроенную в ECMAScript функцию eval. Новый вариант инклюда (код скрипта): eval(CEngine.getScriptBody("globals.js")); eval(CEngine.getScriptBody("main.js"));
CEngine.getScriptBody("main.js") - это функция синглтона моего приложения, которая имеет вид (код С++): QString CEngine::getScriptBody(QString fileName) { QString scriptBody;
QFile scriptFile(QDir::currentPath() + "/files/" + fileName); scriptFile.open(QIODevice::ReadOnly); if(scriptFile.isOpen()) { scriptBody = scriptFile.readAll(); }
return scriptBody; }
Название: Re: Иммитация include в QtScript [решено]
Отправлено: Kotofay от Февраль 21, 2011, 22:06
Есть ещё одно решение. static QScriptValue includeScript ( QScriptContext *context, QScriptEngine *engine ) { QScriptValue ret ( false ); if ( engine == 0 ) return ret; QString fileName = context->argument ( 0 ).toString(); QFile file ( fileName ); if ( file.open ( QFile::ReadOnly ) ) { QByteArray line = file.readAll(); file.close(); QString contents = QString::fromUtf8 ( line ); // ударим в бубны ! engine->currentContext()->setActivationObject ( engine->currentContext()->parentContext()->activationObject() ); ret = engine->evaluate ( contents, fileName ); } return ret; };
После чего при инициализации engine: ... _engine->globalObject().setProperty ( "include", _engine->newFunction ( includeScript ) ); ...
Записываем скрипт "ac.qs", для примера взят код AnalogClock. function AnalogClock(parent) { QWidget.call(this, parent);
var timer = new QTimer(this); timer.timeout.connect(this, "update()"); timer.start(50);
this.setWindowTitle("Analog Clock"); this.resize(400, 400); }
AnalogClock.prototype = new QWidget();
AnalogClock.prototype.paintEvent = function() { var side = Math.min(this.width, this.height); var time = new Date();
var painter = new QPainter(); painter.begin(this); painter.setRenderHint(QPainter.Antialiasing); painter.translate(this.width / 2, this.height / 2); painter.scale(side / 200.0, side / 200.0);
painter.setPen(new QPen(Qt.NoPen)); painter.setBrush(new QBrush(AnalogClock.hourColor));
painter.save(); painter.rotate(30.0 * (time.getHours() + time.getMinutes() / 60.0)); painter.drawConvexPolygon(AnalogClock.hourHand); painter.drawLine(0, 0, 100, 100); painter.restore();
painter.setPen(AnalogClock.hourColor);
for (var i = 0; i < 12; ++i) { painter.drawLine(88, 0, 96, 0); painter.rotate(30.0); }
painter.setPen(new QPen(Qt.NoPen)); painter.setBrush(new QBrush(AnalogClock.minuteColor));
painter.save(); painter.rotate(6.0 * ( time.getMinutes() + time.getSeconds() / 60.0 + time.getMilliseconds() / 60000.0 ) ); painter.drawConvexPolygon(AnalogClock.minuteHand); painter.restore();
painter.setPen(AnalogClock.secondColor); painter.setBrush(new QBrush(AnalogClock.secondColor));
painter.save(); painter.rotate(6.0 * (time.getSeconds() + time.getMilliseconds() / 1000.0)); painter.drawConvexPolygon(AnalogClock.secondHand); painter.restore();
painter.setPen(AnalogClock.minuteColor); for (var j = 0; j < 60; ++j) { if ((j % 5) != 0) painter.drawLine(92, 0, 96, 0); painter.rotate(6.0); } painter.end(); };
AnalogClock.hourColor = new QColor(127, 0, 127);
AnalogClock.minuteColor = new QColor(0, 127, 127, 191);
AnalogClock.secondColor = new QColor(0, 127, 127, 32);
AnalogClock.hourHand = new QPolygon([new QPoint(7, 8), new QPoint(-7, 8), new QPoint(0, -40)]); AnalogClock.minuteHand = new QPolygon([new QPoint(4, 10), new QPoint(-4, 10), new QPoint(0, -70)]); AnalogClock.secondHand = new QPolygon([new QPoint(1, 20), new QPoint(-1, 20), new QPoint(0, -97)]);
И собственно вызов в коде qs: include("./ac.qs");
// вызов функций и создание объектов описанных в скрипте var clock = new AnalogClock(); clock.show();
QCoreApplication.exec();
В скриптовом отладчике можно будет видеть в каком файле скрипта есть ошибки, и появится возможность расставить брейкпойнты.
|