Lua for Windows (LfW) – интерпретируемый язык программирования, разработанный подразделением Tecgraf Католического университета Рио-де-Жанейро (Computer Graphics Technology Group of Pontifical Catholic University of Rio de Janeiro in Brazil). Разработанный интерпретатор является свободно распространяемым, с открытыми исходными текстами на языке Си.
По возможностям, идеологии и реализации язык ближе всего к JavaScript, однако Lua отличается более мощными и гораздо более гибкими конструкциями. Хотя Lua не содержит понятия класса и объекта в явном виде, механизмы объектно-ориентированного программирования, включая множественное наследование, легко реализуются с использованием метатаблиц, которые также отвечают за перегрузку операций и т. п.. Реализуемая модель объектно-ориентированного программирования – прототипная (как и в JavaScript).
Язык широко используется для создания тиражируемого программного обеспечения – в частности, на нём написан графический интерфейс пакета Adobe Photoshop Lightroom. Также получил известность как язык программирования уровней и расширений во многих играх (например, World of Warcraft) из-за удобства встраивания, скорости исполнения кода и лёгкости обучения.
Lua обычно называют мультипарадигменным языком. Он обеспечивает небольшой набор базовых механизмов, которые могут быть расширены для решения различных задач, а не набор сложных жёстких спецификаций, обеспечивающих программирование в единой парадигме.
Так, в Lua отсутствует явная поддержка наследования, однако оно легко реализуется с помощью метатаблиц.
В этой серии уроков, которую я задумал, будет обсуждаться язык программирования Lua. Я постараюсь сделать изложение как можно более доступным для начинающих, и именно на них буду ориентироваться. То есть, опытные Lua-кодеры, скорее всего, не почерпнут отсюда ничего нового (уверен, тут они найдут только простор для придирок и замечаний, которые, собственно, с их стороны даже приветствуется), но если у вас за плечами нет богатого опыта программирования, то, думаю, кое-что вы вынесете.Вся серия не будет подчиняться какой-то системе. Уроки будут последовательно вводить ряд конструкций языка, чтобы уже к третьему или четвёртому уроку вы уже могли писать свои программы. Моя цель - подтолкнуть вас к самостоятельному изучению языка, помочь ощутить его, а не разъяснить от А до Я - если хотите освоить язык полностью, читайте справочное руководство (которое, хоть и скверно, переведено на русский язык: http://www.lua.ru/doc/). Чем раньше вы перейдёте от уроков "для чайников" в Сети к изучению справочника, тем лучше.
Если что-то непонятно - обязательно задайте вопрос в комментариях, и я и другие участники постараемся вам помочь.
Lua - популярный, несложный для освоения встраиваемый интерпретируемый динамически типизированный язык программирования общего назначения. Нет, вам необязательно понимать и половины слов, сказанных в предыдущем предложении - главное знайте, что он популярный и несложный. Кстати, простотой, а также маленьким размером дистрибутива (около 150 килобайт), он и заслужил свою популярность. Скрипты на Lua поддерживаются большим количеством приложений, в том числе играми. World of Warcraft и S.T.A.L.K.E.R. используют язык Lua. Мой любимый игровой движок, позволит вам с помощью Lua с лёгкостью создавать разнообразные игры. Как видите, Lua открывает вам немалые горизонты!
Прежде чем мы начнём, вам следует обустроить среду для программирования: то есть, найти программу, которая принимала бы написанный вами код на Lua и исполняла его: интерпретатор. Тут есть три варианта:
1. Скачать официальный дистрибутив Lua с одного из сайтов, поставляющих их.
С официального сайта Lua можно скачать только исходные коды интерпретатора. Однако поизучав http://lua.org/download.html в разделе Binaries, вы можете обнаружить ссылки на сайты с исполняемыми файлами для Windows. Один из них: . Загрузите оттуда один из архивов (совпадающий с вашей платформой: Win32 или Win64) и распакуйте его куда-нибудь, желательно в каталог с коротким путём: вроде C:\lua. Отныне я буду полагать, что вы пользуетесь Windows, и ваш интерпретатор лежит именно там.
Пользователям операционных систем на базе Linux в этом смысле проще: им достаточно воспользоваться пакетным менеджером и установить Lua из репозиториев. В Debian и Ubuntu это делается командой apt-get install lua, а в Fedora, Red Hat и производных дистрибутивах - yum install lua. Однако не доверяйте мне слепо и обратитесь к справочнику вашей операционной системы, чтобы узнать, как именно это делается у вас.
2. Использовать онлайн-интерпретатор.
Находится по адресу http://www.lua.org/demo.html . На первых порах его может хватить, однако в дальнейшем, когда мы коснёмся модулей, вы будете вынуждены использовать оффлайн-версию. Пользоваться онлайн-интерпретатором очень просто: введите в окошко с текстом вашу программу и нажмите кнопку Run. Программа будет исполнена, в окошке Output покажется вывод вашей программы, а также отчёты об ошибках, если таковые были вами допущены.
3. Использовать IDE.
Например ZeroBrane Studio: http://studio.zerobrane.com/ . Есть и другие - поищите в Интернете.
В ходу сейчас две несколько различающиеся версии Lua: 5.1 и 5.2. Я буду ориентироваться на самую последнюю версию - версию 5.2, но обязательно укажу на важные различия между ей и 5.1, так как последняя тоже достаточно распространена. Кстати, Lua 5.1 исполняет код в полтора раза быстрее, чем Lua 5.2, чтобы вы знали.
=== Урок №1 ===
Итак, начнём. Создайте в изолированной от посторонних файлов папке файл main.lua и напишите в него:
200?"200px":""+(this.scrollHeight+5)+"px");">
-- main.lua --
print("Hello world!")
После чего запустите в командной строке (не забудьте переместиться в директорию с main.lua с помощью команды cd):
200?"200px":""+(this.scrollHeight+5)+"px");">
> C:\lua\lua.exe main.lua
В ответ интерпретатор Lua выдаст:
200?"200px":""+(this.scrollHeight+5)+"px");">
Hello world!
В принципе, этого следовало ожидать. В программе мы вызвали функцию print. Функция print принимает произвольное число параметров и последовательно выводит их на экран. В данном примере мы передали ей строку (цепочку символов) "Hello world!". С таким же успехом можно передать в качестве параметра:
200?"200px":""+(this.scrollHeight+5)+"px");">
print(8) -- какое-нибудь десятичное число
-- выведет: 8
Print(0xDEADBEEF) -- шестнадцатиричное число
-- выведет: 3735928559
Print("0xDEADBEEF") -- а это строка, не число! Видете кавычки?
-- выведет: 0xDEADBEEF
Print(1.35e-4) -- число с плавающей запятой (дробное число)
-- Выведет 0.000135. 1.35e-4 следует понимать как "1.35, умноженное
-- на десять в минус четвёртой степени", если кто не знает.
Print((198*99)-3*500 + 14/88) -- выражение
-- Выведет значение выражения: 18102.159090909. Неплохая альтернатива
-- настольному калькулятору!
Print(198/7, "fertilizer", 2^9) -- несколько параметров произвольного
-- типа. Будут выведены значения каждого из них, разделённые знаками
-- табуляции:
-- 28.285714285714 fertilizer 512
-- Обратите внимание, что кавычки вокруг fertilizer не выводятся!
Print(1,35) -- два числа, а не десятичная дробь 1,35!
-- Запятая используется для разделения параметров.
-- Выведет:
-- 1 35
Знак "--" - не просто имитация знака тире, которая вставлена для красоты. Знаком "--" в Lua отмечаются комментарии: подсказки для программиста, которые игнорируются интерпретатором, и предназначенные для того, чтобы в коде было легче разобраться. Можете попробовать написать в программе:
200?"200px":""+(this.scrollHeight+5)+"px");">
-- print("nothing")
Интерпретатор подумает, что это комментарий, и не станет выполнять инструкцию.
Хозяйке на заметку: если вы хотите напечатать только одну строку, можно написать вызов print так, без скобок:
200?"200px":""+(this.scrollHeight+5)+"px");">
print "Just one string"
Удобство, безусловно, сомнительное: просто имейте ввиду, что так можно. Вместе с тем, такие вызовы недопустимы:
200?"200px":""+(this.scrollHeight+5)+"px");">
print 2 -- не сработает, 2 - не строка.
print 2*2 + 6 -- тем более не сработает
Str = "string!!" -- присвоили переменной str значение "string!!"
-- о переменных читайте ниже
print str -- тоже не сработает.
В каждом из вышеперечисленных случаев программа просто откажется работать. Таким образом, в "бесскобочном" вызове за названием функции может стоять лишь строковый литерал (то есть, последовательность символов, заключённая в кавычки), и больше ничего. В будущем я расскажу об этой особенности чуть подробнее, но сейчас с вас хватит и этого.
В любом хорошем языке программирования возможно объявлять переменные: маленькие контейнеры, которые могут содержать какие-нибудь данные. В Lua это делается таким образом:
200?"200px":""+(this.scrollHeight+5)+"px");">
<имя_переменной> = <выражение>
Например:
200?"200px":""+(this.scrollHeight+5)+"px");">
star = 8 -- Теперь в переменной star хранится число 8
wars = "owl" -- В переменной wars - строка "owl"
jedi = 42/2 -- В переменной jedi - число 21
luke = star*jedi -- В переменной luke - число 168 (да, 21 умножить на 8)
Значения переменных и выражений с ними также можно вывести на экран:
200?"200px":""+(this.scrollHeight+5)+"px");">
print(star, wars, jedi, jedi-star+luke)
-- Выведет:
-- 8 owl 21 181
Только не пытайтесь сложить переменные star и wars - попытавшись прибавить 8 к "owl", вы ничего хорошего не добьётесь!
Как вы должны были заметить, имя у переменной может быть практически любым: главное, чтобы оно не начиналось с цифры. Серьёзно, вы даже можете объявить переменную с названием print, и тогда функция print перестанет работать, потому что имя print станет ссылаться на вновь объявленную переменную. Но есть группа слов, которые запрещено использовать в качестве названий переменных - это ключевые слова языка, с которыми мы пока не познакомились, но на которые точно стоит посмотреть:
200?"200px":""+(this.scrollHeight+5)+"px");">
and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until while
Создав переменную с одним из этих названий, вы вызовете ошибку в программе, и работать она точно не будет. Обратите внимание: в Lua 5.1 ключевого слова goto нет, и переменную так назвать можно, но вы лучше так не делайте.
Также учтите, что имена переменных чувствительны к регистру. Это означает, что foo, fOo, fOO и FOO - четыре разные переменные, так что если вы написали имя какой-то переменной строчными буквами, а позднее написали его прописными, то, скорее всего, программа не будет работать корректно.
А теперь один важный момент: что будет если вы, случайно или преднамеренно, обратитесь к несуществующей переменной? В большинстве других языков это вызовет ошибку, но в Lua такая ситуация допустима. Она трактуется так, как будто несуществующая переменная на самом деле существует, но её значение равно nil . nil - запомните это слово! - особый тип значения в Lua, который означает "ничто". Не нуль и не пустую строку (строку вида "" - попробуйте её вывести на экран), а просто ничто. Сравните это с такой моделью: есть два человека, у одного из них есть банковский счёт, но на нём нет денег, а у другого банковского счёта нет вообще. В терминах Lua будет считаться, что на счету у первого - 0 долларов, а на счету у второго - nil . И даже не долларов, а просто nil . Надеюсь, я вас не запутал.
Попробуйте, например, запустить такую программу:
200?"200px":""+(this.scrollHeight+5)+"px");">
-- main.lua --
foo = "bar"
print(foo, baz)
-- Выведет:
-- bar nil
Таким образом, у переменной baz, которой нет, но считается, будто она есть, значение nil, и функция print понимает это и выводит его на экран в виде строки "nil". В Lua есть хороший метод проверки существования переменной: если значение переменной не равняется nil, то она по крайней мере объявлена. С другой стороны, можно явно объявить переменную, равную nil:
200?"200px":""+(this.scrollHeight+5)+"px");">
cool_var = nil
Так можно делать, и, хотя это на первый взгляд и кажется глупым, так иногда делают. В последующих уроках вы узнаете, кто и зачем, и наверняка начнёте делать так же. Иногда, конечно же.
Будьте осторожны с nil"ом: напечатать nil можно, но совершать с ним арифметические операции нельзя! То есть, если print(nil) сойдёт вам с рук, то конструкция вроде 99+nil вызовет ошибку, даже если вам бы хотелось, чтобы 99+nil равнялось 99. Поверьте, я тоже огорчился, когда узнал.
Резюме:
1. Мы узнали про функцию print, что она умеет и как правильно вызывать её без скобок.
2. Узнали, как объявлять переменные, как вычислять выражения (правда, совсем немножко), какие могут быть имена у переменных.
3. Узнали про nil, прониклись его мистической загадочностью и обрели уверенность в том, что в будущем многое будем связано с ним.
Для пытливых и желающих укрепить свои познания предлагаю простые упражнения,
которые можно не выполнять, если вы чувствуете себя и без того достаточно компетентным:
1. Напишите программу, которая выводит припев вашей любимой песни.
2. Попробуйте вывести значения следующий выражений. Попытайтесь понять, почему некоторые из них работают, а некоторые - нет. Посмотрите, какие ошибки вызывают несработавшие выражения.
200?"200px":""+(this.scrollHeight+5)+"px");">
2 + "string";
6 + "14";
"box" - "vox";
1 * "11b"
"148" * "1e6";
3. Напишите программу, которая обменивает две переменные значениями. То есть:
200?"200px":""+(this.scrollHeight+5)+"px");">
a = 6502
b = 8086
Сделайте так, чтобы a стала равна 8086, а b - 6502. Для этого создайте третью переменную и совершите нехитрые перестановки. Убедитесь, что задача решена правильно, вызвав print(a,b) до обмена и print(a,b) после.
Это вопрос, который возникает достаточно часто. Что, вообще-то, достаточно удивительно, потому как установка на самом деле, крайне проста и понятна. Можно даже сказать, что там вообще нечего делать. Но, раз уж такие вопросы возникают, давайте немного поговорим об установке .
Установка Луа. Скачиваем
Первое, что нам нужно будет сделать перед установкой, это скачать исходники с её официального сайта: . Для установки, естественно, нам понадобится самая последняя версия, на данный момент это lua 5.1.4. После скачивания, естественно, надо разархивировать исходники lua в отдельную папку.
Установка Луа. Компиляция.
Есть два варианта компиляции , которые, в принципе, ничем не отличаются))) Первый – это компиляция из Visual Studio Command Prompt:
- Запускаем Visual Studio
- Выполняем Tools->Visual Studio Command Prompt
- Переходим в папку с луа, в директорию etc. Вот так: cd D:/mylibs/lua-5.1.4
- запускаем скрипт компиляции луа: etc/luavs.bat
- Мы получили нужны нам файлы lua.exe и luac.exe
Второй способ без запуска Visual Studio:
- В любом файл-мендеже (я лично работаю в ) заходим в папку где_луа/etc/
- Редактируем файл, первой строкой ставим: call “путь_к_вижуалстудио/VC/bin/vcvars32.bat”
- Добавляем вторую строку: cd .. и сохраняем файл
- Запускаем, получаем искомые экзешники
Установка Луа. Доступ
Что бы вы могли запускать луа откуда угодно – вам надо добавить их (путь к ним) в переменную окружения %PATH%. Думаю, Вы сами прекрасно знаете как это сделать. В любом случае, нам не нужны эти файлы, т.к. мы планируем использовать луа внтри наших программ, а не как отдельное приложение. После этого считайте, что сама установка Lua завершена, вам лишь остаётся прописать в Visual Studio пути в получившейся.lib и хидерам луа.
Установка Луа. Статическая линковка.
Меня лично выводит из себя то, что с каждый проектом, использующим луа, приходится таскать и lua.dll , поскольку без неё программы работать не будут. А что бы они работали – надо что бы луа линковалась с нашей программой статически. Делается это тоже совсем не сложно:
- Делаем в Visual Studio новый проект, Win32Project, назовём его “LuaLib”
- Тип проекта указываем “Static Library”, отключаем использование Precompiled Header, нажимаем Finish
- Добавляем в проект все файлы.h и.c, кроме lua.c и luac.c
- Что бы компилятор не выдавал нам варнингов, в настройки проекта (Protec/Propreties/Preprocessor) добавляем;_CRT_SECURE_NO_WARNINGS (не забудьте сделать это и для релиз и для дебаг-версии!!!)
- В настройках линковки (Project/Properties/Librarian/General/OutputFile) указываем какие имена библиотек мы хотим. Я указал lua.lib для релиза и lua-debug.lib для дебага.
- Компилируем дебаг и релиз-версии. Получаем нужные нам либы
- Прописываем пути к ним в Visual Studio
Установка Луа. Проверка.
Проверим, всё ли работает. Создаём новый проект (я сделал консольный проект win32). Дописываем инклюды луа:
и доделываем сам main():
int _tmain(int argc, _TCHAR* argv ) { lua_State * L; L = lua_open() ; //Создаем стэк luaL_openlibs(L) ; //подключить стандартные библиотеки int status = luaL_loadfile(L, "test.lua" ) ; //загрузить файл /* Состояние стtка: [-1]main <--top of the stack */ if (status) { (void ) fprintf (stderr , "file not found\n " ) ; return 1 ; } int result = lua_pcall(L, 0 , LUA_MULTRET, 0 ) ; _getch() ; return 0 ; } |
В настройки линковщика (Project/Properties/Linker/Input/Addition Dependencies) не забываем добавить нашу библиотеку (lua.lib для релиза и lua-debug.lib для дебага). Компилируем. Создаём тестовый файлик с луа-скриптом.
- Расширение (формат) - это символы в конце файла после последней точки.- Компьютер определяет тип файла именно по расширению.
- По умолчанию Windows не показывает расширения имен файлов.
- В имени файла и расширении нельзя использовать некоторые символы.
- Не все форматы имеют отношение к одной и той же программе.
- Ниже находятся все программы с помощью которых можно открыть файл LUA.
Многие пользователи MS Windows давно успели заметить, что стандартный блокнот - это довольно неудобная в своем использовании программа. Заменой ей может стать данный бесплатный редактор текстовых файлов, обеспечивающий поддержку синтаксиса большого количества языков программирования. Программа содержит в себе довольно широкий набор опций и отличается минимальным потреблением ресурсов процессора. Программа делает возможным одновременный просмотр нескольких документов сразу и редактирование их, без закрытия лишних окон. Доступной стала и такая опция, как редактирование одного и того же документа в разных местах, что очень удобно...
Notepad2 – простое приложение, позволяющее печатать и редактировать текст. Она поможет в создании HTML-страниц, программировании на различных языках (CSS, Java, JavaScript, Python, SQL, Perl, PHP) так как способна подсвечивать код. Программа построена по принципу простого блокнота, она маловесна и компактна. Этот текстовый редактор проверяет все скобки на наличие пары, поддерживает авто отступы. Программа Notepad2 не только поддерживает кодировки ASCII и UTF-8, но и умеет их конвертировать. Позволяет откатывать нежелательные операции на много уровней назад. Поддерживает блочное выделение элементов текста и имеет нумерованные ст...
Komodo Edit - удобный редактор кода, поддерживающий широкий спектр различных языков программирования. Программа дает пользователям возможность работать сразу с несколькими файлами, писать код станет более эффективно с использованием функции автозаполнения, подсказок. Приложение позволяет автоматически выделять переменные при их выборе. С помощью редактора можно просматривать файлы на других программных языках. Программа поддерживает окраску синтаксиса, отступы. Может проверять параметры синтаксиса, сниппеты, используемые для хранения кода исходного столбца. Имеет режим простого редактирования и поддерживает перетаскивание элеме...
В интернете очень много программ, позволяющих редактировать исходный код другой программы, файла и др. Однако большинство из подобных программ являются всего лишь текстовым редактором наподобие блокнота. Отличаются они от вышеуказанного редактора лишь тем, что имеют подсветку синтаксиса. Однако в некоторых случаях, такого функционала программы оказывается недостаточно. Программисту бывает необходимо быстро находить различные части документа. И вот, наконец-то, в появилась программа, позволяющая решить эту проблему. Программа называется SynWrite. Её отличительная особенность – наличие навигационной панели с деревом, котор...
За Lua прочно закрепилась слава полуязыка - инструмента, который при случае можно встроить, чтобы заскриптовать приложение, написанное на компилируемом языке вроде С++. Тем не менее Lua является вполне самостоятельным языком, имеющим свой интерпретатор, возможность создания модулей, большое число библиотек, и при этом данный ЯП обладает минимальным размером среди аналогов. Проще говоря у нас есть все, чтобы создавать такие же приложения как на perl, python, и вообще любом другом распространенном языке программирования.
Я могу предложить вам следующие доводы в пользу Lua:
- - приложения будут легко переносимы между Windows и Linux (не факт что код будет работать без изменений, но портирование правда пройдет безболезненно, если не были использованы платформоспецифичные библиотеки)
- - малый оверхед создаваемых программ
- - высокая скорость работы и загрузки приложений
- - возможность оперативно «приклеить» к вашему приложению любую С-библиотеку - лучшего «клея» для библиотек вы не найдете
- - приятный минималистичный синтаксис языка, с возможностью реализации на нем современных парадигм программирования
- - программы на Lua очень легко развертывать
- - малое потребление памяти
Чтобы продемонстрировать возможности Lua, я покажу как с его использованием создать небольшую программу для построения графиков по точкам с возможностью сохранения графика в виде файла изображения.
В качестве графического тулкита будем использовать iup - кроссплатформенную библиотеку, изначально созданную с расчетом использования из Lua.
Установка Lua SDK
В рамках идеи использования Lua как самостоятельного ЯП, была создана сборка Lua for Windows , которая содержит себе библиотеки, необходимые в повседневных задачах, возникающих при программировании под указанную ОС: работы с БД, GUI, парсинг XML и т.д. Пусть вас не смущает, что версия Lua в сборке 5.1, а не 5.2 - особой разницы в нашем случае между ними нет.Скачайте и установите сборку.
Краткое описание концепции iup
Я долго думал, как же расписать процесс создания программы, не вдаваясь подробно в устройство iup. И решил коротко описать его основные принципы:- - iup.dialog является корневым элементом интерфейса программы - в этом контейнере размещаются все элементы
- - позиционирование элементов в контейнере производится при помощи layout-ов: задания правил размещения элемента в контейнере. Iup сам расположит и отрисует элемент согласно правилам. Основные контейнеры - фрейм, вертикальный сайзер, горизонтальный сайзер.
- - обработчики событий задаются в виде функций, прикрепленных к виджету
- - после создания диалога запускается цикл обработки событий
Код программы
Подключение библиотек iup require("iuplua") require("iupluacontrols") require("iuplua_pplot") -- библиотека для работы с Canvas, чтобы сохранять график в файл require("cdlua") require("iupluacd") require("string") -- глобальные переменные для виджетов и настроек программы -- максимальное число графиков plots_number = 5 -- виджеты вкладок, где будут размещаться виджеы ввода данных для каждого графика tabs = {} -- контейнеры для виджетов vboxes = {} -- чекбоксы для выбора того, какие графики строить checkboxes = {} -- здесь храним виджеты с текстом данных о точках coords = {} -- виджеты подписи для каждого графика legends = {} -- виджеты обозначения осей координат global_legend = {} -- к величайшему стыду, в Lua нет стандартной функции split function string:split(sep) local sep, fields = sep or ":", {} local pattern = string.format("([^%s]+)", sep) self:gsub(pattern, function(c) fields[#fields+1] = c end) return fields end -- функция рисует на плоттере график по указаным точкам function draw_plot(pwidget, pnum, data) x = data.value:split(",") y = data.value:split(",") if checkboxes.value == "OFF" then return end if not (#x == #y) or #x == 0 then iup.Message("Ошибка", "Задано неверное число точек для графика " .. pnum) return end iup.PPlotBegin(pwidget, 0) iup.PPlotAdd(pwidget, 0, 0) for i = 1,#x do iup.PPlotAdd(pwidget, x[i], y[i]) end iup.PPlotEnd(pwidget) end -- виджет отвечающий за кнопку построения графика plot_btn = iup.button{ title = "Построить"} -- колбэк для кнопки "построить график" function plot_btn:action() -- создать виджет графопостроителя plot = iup.pplot { expand="YES", TITLE = "Simple Line", MARGINBOTTOM="65", MARGINLEFT="65", AXS_XLABEL = global_legend.value, AXS_YLABEL = global_legend.value, LEGENDSHOW="YES", LEGENDPOS="TOPLEFT", size = "400x300" } -- этот блок для обхода бага - без него подпись к первому графику отображаться не будет iup.PPlotBegin(plot, 0) iup.PPlotAdd(plot,0,0) plot.DS_LEGEND = "" iup.PPlotEnd(plot) -- обходим виджеты с данными for i = 1, plots_number do -- чтобы свеженарисованный графи отобразился с правильной подписью print(legends[i].value) plot.DS_LEGEND = legends[i].value -- рисуем график draw_plot(plot, i, coords[i]) end -- кнопка сохранения графика в картинку на диске save_btn = iup.button{ title = "Сохранить" } -- теперь создаем само окно, где будет отображаться график plot_dg = iup.dialog { iup.vbox -- это вертикальный сайзер, помести в него графопостроитель и кнопку { plot, save_btn }, } -- обработчик кнопки сохранения графика function save_btn:action() -- создаем диалог выбора имени файла ля сохранения -- в связи с ограничениями библиотеки сохранять можно только в EMF fs_dlg = iup.filedlg{DIALOGTYPE = "SAVE", FILTER = "*.emf" } iup.Popup(fs_dlg) -- если файл выбран if tonumber(fs_dlg.STATUS) >= 0 then -- дописать при необходимости нужное расширение pic = fs_dlg.value if not (string.sub(pic, string.len(pic)-3) == ".emf") then pic = pic .. ".emf" end -- создаем псевдо-холст, ассоциированный с файлом tmp_cv = cd.CreateCanvas(cd.EMF, pic .. " 400x300") -- выводим график на холст iup.PPlotPaintTo(plot, tmp_cv) -- сохраняем данные в файл cd.KillCanvas(tmp_cv) end end -- отображаем диалог с графиком plot_dg:showxy(iup.CENTER, iup.CENTER) -- запускаем петлю обработки событий для диалога if (iup.MainLoopLevel()==0) then iup.MainLoop() end end -- в цикле создаем вкладки, в которых мы будем размещать виджеты -- для сбора данных for i=1,plots_number do -- создание текстовых виджетов, куда будут вводиться координаты точек coords[i] = {} for j = 1,2 do coords[i][j] = iup.text { expand="HORIZONTAL", multiline = "YES", VISIBLELINES = 5 } end -- виджет для редактирования подписи к графику legends[i] = iup.text{ expand = "HORIZONTAL" } -- создаем контейнер вкладки и заполняем его элементами vboxes[i] = iup.vbox { iup.hbox { iup.label { title = "Подпись графика:" }, legends[i] }, iup.hbox { iup.label { title="X: ", }, coords[i] }, iup.hbox { iup.label { title="Y: ", }, coords[i] }; expand="YES", } -- меняем заголовк вкладки vboxes[i].tabtitle = "График " .. i -- создаем чекбокс, который будет указывать на то, нужно ли строить -- график по данным из указанной вкладки checkboxes[i] = iup.toggle{ title= "График" .. i, value = "ON" } end -- теперь из заполненных нами контейнеров создаем вкладки tabs = iup.tabs{unpack(vboxes)} -- создаем текстовые виджеты для редактирования подписей осей global_legend = iup.text{} global_legend = iup.text{} -- создаем фрейм для общих настроек графика frame = iup.frame { iup.vbox { iup.label{ title="Использовать данные:", expand="HORIZONTAL" }, iup.vbox { unpack(checkboxes) }, iup.label{}, -- пустую подпись можно использовать как распорку iup.label{title = "Подписи"}, iup.hbox { iup.label{ title = "Ось X "}, global_legend }, iup.hbox { iup.label{ title = "Ось Y "}, global_legend }, iup.label{}, plot_btn }; expand = "VERTICAL", } -- создаем главное окно программы и наносим на него настройки и табы dg = iup.dialog { iup.hbox { frame, tabs }, title="Строим график", size = "HALF" } -- показываем главное окно и запускаем обработку событий dg:showxy(iup.CENTER, iup.CENTER) if (iup.MainLoopLevel()==0) then iup.MainLoop() end
Пара слов о развертывании
Скрипт можно запустить при помощи команды:Lua plotter.exe
В данном случае библиотеки будут подключаться из поддиректории clibs/, которая находится в директории, куда был установлен Lua for Windows. Чтобы максимально компактно упаковать скрипт и библиотеки для переноса на другую машину, достаточно скопировать в одну папку следущие файлы(указаны с относительными путями от директории установки Lua):
Lua.exe lib/lua5.1.dll clibs/cd.dll clibs/cdlua51.dll clibs/iup.dll clibs/iup_pplot.dll clibs/iupcd.dll clibs/iupcontrols.dll clibs/iupgl.dll clibs/iuplua51.dll clibs/iuplua_pplot51.dll clibs/iupluacd51.dll clibs/iupluacontrols51.dll clibs/freetype6.dll
Не забудьте поместить в эту папку и сам скрипт с программой. Теперь вы можете перенести эту папку на другую машину и запустить вашу программы командой, указанной выше. При этом никакие другие действия по установке библиотек и рантайма не нужны.
К сожалению файлы cd.dll, cdluad51.dll и iupcd.dll в данной версии Lua for Windows могут работать некорректно, поэтому рекомендую взять их из архива по ссылке ниже.
Итоги
Архив с рабочей версией , для удобства добавлена пускалка app.bat.Скриншоты:
В результате получили, пусть и неказистую, утилиту, имеющую такой же функционал, как и если бы она была написана на «серьезном» языке программирования. При этом простую в развертывании и суммарным весом менее 2 мб. Потребление памяти - около 7 мб. Исходный код доступен для редактирования, сам Lua интерактивно понятен, что упрощает доработку подобного софта на местах.
На мой взгляд, это отличный выбор для написания учебного софта для школ и институтов, а также для внутреннего использования на предприятиях. Так как слабые машины до сих пор в изобилии присутствуют в подобных местах по всему СНГ, то использование Luа подобным образом целесообразно, особенно в свете постепнного прихода Linux на десктопы. К тому же тенденцию потери исходников самописного софта при жуткой его же забагованности можно приравнять к национальному бедствию.
Теги: Добавить метки