Давно уже хотел написать по поводу 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(); ...
В принципе, 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; }
Как видно из скриншота, приложение занимает 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 можно почитать на официальном сайте.
Введение Уже долгое время не пишу статьи о разработке, хотя сам процесс написания мне очень…
I can see that there is still a lot of topics at wxWidgets forums related…
I've just published the source code of wxToolBox component and a couple of sample apps at…
Microsoft released their Kinect SDK several days ago. So, for those wxWidgets developers who are…
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to…
Вдохновленнный читаемой нынче книгой My Job Went to India: 52 Ways to Save Your Job…
View Comments
Yet another wxPython? :)
В чем глубинный смысл? какие преимущества? для чего он вообще нужен на десктопе? Тема не раскрыта:(
Вот в вебе возможно интересно, но помнится я смотрел сайт его - и так и не увидел не одного примера использования, расстроился и ушел :)
Ммм? Ну вобще фраза "чем он лучше wxPython" из разряда "Кто сильнее, кит или слон?". Он просто "другой". Мне например нравится синтаксис, и кодинг на wxJS мне кажется более комфортным, но это ИМХО. А примеры использования. Ну то же самое что ты пишешь на C++, только компилить не надо. Плюс ко всему его можно использовать как скриптовый движок для своих приложений. Напишу еще об этом.
Т.е. если например тебе надо срочно наклепать какую-то утилиту "которая что-то делает" для собственных нужд, то для этого незачем иметь на машине компилятор. Я с собой wxJS на флешке таскаю. Он без установки работает
ЗЫ: В дистрибутиве есть гора примеров.
ты сам конкретно что-то полезное для себя уже написал на нем?
"не машине на которой даже нет компилятора" ?:)
тоже самое что и с++ только компилить не надо кажется мне довольно спорным преимуществом - из проекта на с++ может выйти что-то полезно + можно использовать готовые наработки, тоже в принципе и с питоном, а "утилитка которая что-то для себя делает" на джава скрипт, такой и останется, по идеи.
Хотя может для небольших задач скриптов как раз то что надо. Но опять же новый язык учить :)
А вот как скриптовый язык это может быть интересным, но это небось толстый интерпретатор?
Ммм? Вроде все интерпретаторы толстые, wxLua например тоже не маленький.
А по поводу "для себя" чего нормальное делал.. Когда-то делал адресную книгу на wxJS + SQLite, даже вроде пользовался какое-то время, потом не помню куда она делась :) Может исходник еще смогу найти.
Я вроде где-то на wxForum'е видел описание какой-то неплохой фривары на wxJS, оно даже работало.
поискал на форуме, про фривары на этом скрипте не нашел.:(
зато нашел упоминания про http://wxcode.sourceforge.net/components/wxscript/, но как-то ....
вообщем тема скриптов не раскрыта, можно сказать не паханая целина для новых постов:)
Кстати, по сабжу - только виндовс и убунту я так понял, мак отдыхает... еще один минус.
Я думаю поддержка мака не заявлена потому что автору собирать не на чем. Я по этой же причине тоже не делаю самплов под мак, мне другой человек собирает.
ЗЫ: Кстати под Windows 7 GUI модуль вываливается с ошибкой, по крайней мере без админской учетки.