wxJavaScript - Кросс-платформенный скриптинг десктопных приложений. Знакомство

Давно уже хотел написать по поводу wxJavaScript. По-моему сейчас как раз пришло время для этого, т.к. проект уже успел развиться до такого состояния, когда все работает более-менее стабильно.
Итак, что же это за зверь wxJavaScript? Проект начинался как обычный порт wxWidgets на JavaScript, но, со временем, “оброс” библиотеками, которых в wxWidgets отродясь не было. Это модули curl, sqlite, mysql и др. Также проект получил реинкарнацию в виде модуля к Apache, который может использоваться для создания динамических HTML-страниц. Но об этом потом. Сейчас мне бы хотелось рассказать о том, как этим всем можно пользоваться для достижения собственных корыстных целей.

wxJavaScript поставляется в виде исполняемого файла интерпретатора и дополнительных модулей в виде динамических библиотек. Перечень используемых модулей может изменяться в конфигурационном файле. Это значит, что если на вашей машине используются скрипты только для доступа к базам данных, то нет никакой необходимости подключать, например библиотеку для создания графического интерфейса. Это позволяет экономить память, используемую движком wxJavaScript.
Минимальное приложение для wxJS выглядит так:

minimal.js

 

print("Hello World !!!");

wxjs minimal.js

 

Теперь рассмотрим, как создать минимальное приложение с графическим интерфейсом.

 

minimal_gui.js

 

wxTheApp.onInit = init;

function init()
{
  var frame = new wxFrame(null, -1, "Minimal");
  frame.visible = true;
  wxTheApp.topWindow = frame;
  return true;

Для того, чтобы наше приложение запустилось, нам необходимо включить поддержку графического интерфейса в конфигурационном файле:

modules.js

 

...
wxjs.modules.io = new Module("../modules/wxjs_gui.dll");
wxjs.modules.io.load();

wxJavaScript - Минимальное приложение с графическим интерфейсом
В принципе, API очень схож с wxWidgets API для C++, но есть некоторые особенности. Например, обработчики событий от меню навешиваются к объекту меню через массив actions, а не к форме.
Давайте рассмотрим более сложный пример программы с графическим интерфейсом, использующий обработчики событий.

advanced_gui.js

 

// Указываем что при инициализации приложения должна
// вызваться функция init
wxTheApp.onInit = init;

function OnFileNew()
{
  this.textCtrl.value = "";
}

function OnFileOpen()
{
  // Создаем диалог открытия файла
  var fileDialog = new wxFileDialog(this, "Open a file");
  // Устанавливаем стиль диалога
  fileDialog.style = wxFileDialog.OPEN;
  // Если диалог отработал успешно...
  if(fileDialog.showModal() == wxId.OK)
  {
    // Загружаем файл в текстовое поле
    this.textCtrl.loadFile(fileDialog.path);
  }
}

function OnFileSave()
{
  var fileDialog = new wxFileDialog(this, "Save file");
  fileDialog.style = wxFileDialog.SAVE;
  if(fileDialog.showModal() == wxId.OK)
  {
    this.textCtrl.saveFile(fileDialog.path);
  }
}

function OnFileExit()
{
  this.close();
}

function CreateMenuBar(parent)
{
  // Создаем строку меню
  var menuBar = new wxMenuBar(parent);

  // Создаем меню "Файл"
  var fileMenu = new wxMenu;
  // Добавляем в меню элементы
  fileMenu.append(wxId.NEW, "New\tCtrl+N", "Create new file");
  fileMenu.append(wxId.OPEN, "Open\tCtrl+O", "Open existing file");
  fileMenu.appendSeparator();
  fileMenu.append(wxId.SAVE, "Save\tCtrl+S", "Save file");
  fileMenu.appendSeparator();
  fileMenu.append(wxId.EXIT, "Exit\tAlt+F4", "Exit this application");

  // Назначаем обработчики событий
  fileMenu.actions[wxId.NEW] = OnFileNew;
  fileMenu.actions[wxId.OPEN] = OnFileOpen;
  fileMenu.actions[wxId.SAVE] = OnFileSave;
  fileMenu.actions[wxId.EXIT] = OnFileExit;

  // Добавляем меню в строку меню
  menuBar.append(fileMenu, "File");
  return menuBar;
}

// Функция создания главной формы
function CreateFrame()
{
  // Создаем форму
  var frame = new wxFrame(null, -1, "Minimal");
  // Создаем строку меню с помощью функции CreateMenuBar()
  frame.menuBar = CreateMenuBar();
  // Создаем строку состояния с двумя панелями
  frame.createStatusBar(2);

  // Создаем главный сайзер
  var mainSizer = new wxBoxSizer(wxOrientation.VERTICAL);

  // Создаем текстовое поле
  var textCtrl = new wxTextCtrl(frame, wxId.HIGHEST+1, "",
    wxDefaultPosition, wxDefaultSize, wxTextCtrl.MULTILINE);

  // Добавляем текстовое поле в сайзер
  mainSizer.add(textCtrl, 1, wxStretch.EXPAND, 0);

  // Кладем сайзер на форму
  frame.sizer = mainSizer;
  // Устанавливаем значение переменной textCtrl в главной форме
  frame.textCtrl = textCtrl;

  return frame;
}

// Инициализация приложения
function init()
{
  // Создаем форму с помощью функции CreateFrame();
  var frame = CreateFrame();
  // Делаем форму вилимой
  frame.visible = true;
  // Делаем форму главной
  wxTheApp.topWindow = frame;
  return true;
}

...

}

wxJavaScript - Более сложный пример приложения с графическим интерфейсом
Как видно из скриншота, приложение занимает 18 МБ памяти. Минимальное приложение занимало приблизительно 12 МБ. Эти 6 мегабайт разницы “съедает” поддержка Common Dialogs при первом обращении, а именно при открытии диалога открытия файла.

Кроме всего прочего, wxJS поддерживает работу с базами данных. Ниже приведен код примера, который выполняет соединение с базой данных SQLite, при необходимости, создает таблицы в базе данных, заполняет их данными и отображает содержимое таблиц.

database.js

 

// Открываем базу данных
var db = new sqlite.Database(script.root + "sample.db");
// Если база была открыта успешно...
if(db.opened)
{
  print("Database opened successfully.\r\n");
  // Хитрая проверка на наличие таблиц с помощью PRAGMA
  var pragmaStmt = db.prepare("PRAGMA user_version");
  var pragma = pragmaStmt.fetchArray();
  if(pragma[0] == 0)
  {
    // Создаем таблицы в базе данных
    print("Creating tables...\r\n");
    print(db.exec("CREATE TABLE sample(id INTEGER PRIMARY KEY, somedata TEXT)"));
    print("Inserting data...\r\n");
    // Заполняем таблицы данными
    print(db.exec("INSERT INTO sample(somedata) VALUES ('test 1')")+"\r\n");
    print(db.exec("INSERT INTO sample(somedata) VALUES ('test 2')")+"\r\n");
    // Устанавливаем флаг наличия таблиц
    db.exec("PRAGMA user_version = 1");
  }
  // Получаем данные из таблицы
  print("Fetching data...\r\n");
  var stmt = db.prepare("SELECT * FROM sample");
  // если получилось вытянуть данные...
  if(stmt != null)
  {
    var row;
    // Выводим все записи в консоль
    while(row = stmt.fetchObject())
    {
      print(row.id + ": " + row.somedata + "\r\n");
    }
  }
  else
  {
   print("Unable to fetch data.\r\n");
  }
}
else
{
  print("Error opening database.");
}

Ну вот, пока на этом все. Более подробно об API wxJavaScript можно почитать на официальном сайте.
 
Источник: http://wxwidgets.info/

 

 



Опубликовал admin
3 Июн, Среда 2009г.



Программирование для чайников.