Russian Qt Forum
Декабрь 18, 2024, 19:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Иммитация include в QtScript [решено]  (Прочитано 7052 раз)
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());
    }
}
« Последнее редактирование: Февраль 20, 2011, 02:46 от dd » Записан
dd
Гость
« Ответ #1 : Февраль 21, 2011, 15:23 »

В данном решении есть один нюанс.
Так и не понял в чем дело.
Если в одно файле я описываю функцию так:

Код:
function MyFunc ()
{
}

то в другом файле после инклюда она не видна.
А видна только если описать ее так:

Код:
MyFunc = function  ()
{
}

Старнное поведение. Лечится это, если использовать встроенную в 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;
}
Записан
Kotofay
Гость
« Ответ #2 : Февраль 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();


В скриптовом отладчике можно будет видеть в каком файле скрипта есть ошибки, и появится возможность расставить брейкпойнты.
« Последнее редактирование: Февраль 21, 2011, 22:12 от Kotofay » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.278 секунд. Запросов: 20.