Создание пользовательских приложений в Engee
Интерактивные элементы интерфейса в Genie
В этом разделе вы познакомитесь с созданием некоторых часто используемых элементов интерфейса в Genie, таких как заголовки, флажки, раскрывающиеся списки, текстовые поля, ячейки, ползунки и кнопки.
Какое приложение мы будем создавать
Мы изучим эти элементы интерфейса на примере приложения, рассчитывающего ускорение свободного падения на различных небесных телах. Приложение будет работать в одном из двух режимов:
- Пользователь выбирает небесное тело из списка (Солнце, Меркурий, Венера, Земля, Луна, Марс, Юпитер, Сатурн, Уран, Нептун, Плутон), после чего приложение выводит на экран взятое из справочника значение для выбранного небесного тела.
- Пользователь задает параметры , и небесного тела, после чего производится расчет по формуле
где – гравитационная постоянная, – средняя плотность небесного тела, – его радиус, – высота над поверхностью небесного тела.
Вывод на экран значения будет осуществляться при нажатии пользователем кнопки Расчет.
✏️Задание 1
Начните создание приложения:
- В папке данного курса создайте скрипт
app2.jl. - Добавьте в скрипт следующий код, создающий «пустое» приложение:
using GenieFramework, Stipple
@app begin
end
function ui()
end
@page("/", ui)
Создание заголовка приложения
Genie позволяет создавать заголовки с текстом различного размера с помощью команд h1(), h2(), h3() и т.д. Чем меньше номер, тем больше размер шрифта. Здесь мы будем использовать заголовок с пятым номером шрифта. В качестве аргумента в двойных кавычках записывается текст заголовка.
✏️Задание 2
В интерфейсную часть кода (function ui()) добавьте команду, создающую заголовок приложения:
h5("Расчет ускорения свободного падения на различных небесных телах"),
Элементы интерфейса перечисляются через запятую, поэтому в конце строки должна стоять запятая.
Решение
using GenieFramework, Stipple
@app begin
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
end
@page("/", ui)
Флажок
Флажок в Genie задается с помощью команды ckeckbox().
Он может находиться в одном из двух состояний: включенном или выключенном. Он управляет некоторой логической переменной, которая будет переключать режимы работы нашего приложения: выбор небесного тела из списка или расчет по формуле. Логическую переменную, отвечающую за выбор режима работы, назовем Checkbox_checked. Если она принимает значение true, то пользователь будет выбирать небесное тело из списка; если false – то g будет вычисляться по формуле.
✏️Задание 3
Добавьте в приложение флажок:
- В интерфейсную часть кода добавьте команду
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
Здесь первый аргумент – надпись, которая будет располагаться рядом с флажком; второй аргумент – логическая переменная Checkbox_checked, описывающая состояние флажка.
- В модель данных (
@app) добавьте описание входной переменнойCheckbox_checked, принимающей начальное значениеtrue:
@in Checkbox_checked = true
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
end
@page("/", ui)
Раскрывающийся список
Раскрывающийся список в Genie задается с помощью команды select().
Он нам понадобится для того, чтобы пользователь мог выбрать небесное тело из заданного множества. Нам понадобятся две входные переменные:
body– переменная строкового типа, определяющая, какое небесное тело выбрано пользователем;body_list– вектор элементов строкового типа, задающий список небесных тел.
✏️Задание 4
Добавьте в приложение раскрывающийся список:
- В интерфейсную часть кода добавьте команду
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
Здесь body – переменная, определяющая сделанный выбор, options = :body_list задает переменную, в которой содержится список опций, label – заголовок списка. Последний аргумент задает ширину списка (в данном случае она равна 400 пикселей).
- В модель данных добавьте описание входной переменной
body(пусть ее начальное значение будет "Земля") и внешней (передаваемой в интерфейс) переменнойbody_list:
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
end
@page("/", ui)
Текстовое поле
С текстовым полем мы уже встречались в предыдущем разделе. Оно задается с помощью команды textfield().
Текстовые поля могут использоваться как для ввода, так и для вывода данных. Добавим в приложение два текстовых поля для ввода двух переменных: средней плотности rho и радиуса небесного тела r.
✏️Задание 5
Добавьте в приложение два текстовых поля:
- В интерфейсную часть кода добавьте команду:
textfield("Средняя плотность небесного тела, кг/м^3:", :rho, style="width:400px"),
Здесь первый аргумент – заголовок текстового поля, располагающийся над ним, rho – вводимая пользователем переменная. Последний аргумент задает ширину текстового поля, равную 400 пикселей.
- В модель данных добавьте описание входной переменной
rho, принимающей начальное значение5515.3(плотность Земли):
@in rho = 5515.3
- В интерфейсную часть кода добавьте команду:
textfield("Радиус небесного тела, км:", :r, style="width:400px"),
Здесь первый аргумент – заголовок текстового поля, r – вводимая пользователем переменная. Ширину текстового поля также задайте равной 400 пикселей.
- В модель данных добавьте описание входной переменной
r, принимающей начальное значение6371.0км (радиус Земли):
@in r = 6371.0
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
@in rho = 5515.3
@in r = 6371.0
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
textfield("Средняя плотность небесного тела, кг/м^3:", :rho, style="width:400px"),
textfield("Радиус небесного тела, км:", :r, style="width:400px"),
end
@page("/", ui)
Структурный блок и ползунок
Структурный блок в Genie используется для объединения нескольких элементов интерфейса. Структурный блок рассматривается как единый элемент, к которому можно применить общее для всех составляющих форматирование. Структурный блок задается командой cell([...]). Внутри квадратных скобок через запятую перечисляются элементы интерфейса, входящие в структурный блок.
Создадим структурный блок, содержащий два элемента: надпись "Высота над поверхностью, км:" и ползунок для ввода пользователем переменной h – высоты над поверхностью небесного тела. Ползунок задается с помощью команды slider().
✏️Задание 6
Добавьте в приложение структурный блок, состоящий из надписи и ползунка:
- В интерфейсную часть кода добавьте команду:
cell([p("Высота над поверхностью, км:"), slider(0:1:100, :h, label="", style="width:364px")]),
Первый элемент структурного блока p("Высота над поверхностью, км:") – надпись, располагающаяся над ползунком, а второй элемент slider(0:1:100, :h, label="", style="width:364px") – ползунок. Здесь 0:1:100 – диапазон изменения вводимой переменой (от 0 до 100 км с шагом 1 км), h – вводимая пользователем переменная. Последний аргумент задает ширину ползунка, равную 364 пикселя.
- В модель данных добавьте описание входной переменной
h, принимающей начальное значение0.0км:
@in h = 0.0
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
@in rho = 5515.3
@in r = 6371.0
@in h = 0.0
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
textfield("Средняя плотность небесного тела, кг/м^3:", :rho, style="width:400px"),
textfield("Радиус небесного тела, км:", :r, style="width:400px"),
cell([p("Высота над поверхностью, км:"), slider(0:1:100, :h, label="", style="width:364px")]),
end
@page("/", ui)
Кнопка
Все входные данные заданы. Теперь нужно произвести расчет и вывести результат на экран. Расчет ускорения свободного падения будет выполняться при нажатии пользователем кнопки Расчет. Кнопка в Genie задается командой btn().
Нам также потребуется макрос @onbutton (обработчик нажатия кнопки), в котором будет содержаться алгоритм расчета.
✏️Задание 7
Добавьте в приложение кнопку и обработчик ее нажатия:
- В интерфейсную часть кода добавьте команду:
btn("Расчет", @click(:Button_process), color = "primary"),
Здесь "Расчет" – текст, отображаемый на кнопке. Макрос @click определяет логическую переменную Button_process, связанную с нажатием кнопки: значение этой переменной равно true, если кнопка нажата, и false в противном случае. Третий аргумент задает цвет кнопки (белая надпись на темном фоне).
- В модель данных добавьте описание входной переменной
Button_process:
@in Button_process = false
Ее начальное значение равно false, т.е. при запуске приложения кнопка не нажата.
- С помощью макроса
@onbuttonдобавьте реактивную логику работы приложения и разместите ее в модели данных после описания реактивных переменных. Опишите, что должно происходить при нажатии кнопкиРасчет:
@onbutton Button_process begin
if Checkbox_checked == true
if body == ["Солнце"]
g = 273.1
elseif body == ["Меркурий"]
g = 3.70
elseif body == ["Венера"]
g = 8.88
elseif body == ["Земля"]
g = 9.81
elseif body == ["Луна"]
g = 1.62
elseif body == ["Марс"]
g = 3.86
elseif body == ["Юпитер"]
g = 24.79
elseif body == ["Сатурн"]
g = 10.44
elseif body == ["Уран"]
g = 8.86
elseif body == ["Нептун"]
g = 11.09
elseif body == ["Плутон"]
g = 0.617
end
else
G = 6.67e-11
g = 4/3*pi*G*rho*(r*1000)^3/((r+h)*1000)^2
end
end
Здесь проверяется условие: если флажок включен (if Checkbox_checked == true), то в соответствии с тем, какое небесное тело выбрал пользователь, переменной g присваивается значение, взятое из справочника. Если флажок выключен (else), то значение ускорения свободного падения рассчитывается по формуле. Множители 1000 в формуле связаны с переводом значений r и h из километров в метры. Значение g получается в .
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
@in rho = 5515.3
@in r = 6371.0
@in h = 0.0
@in Button_process = false
@onbutton Button_process begin
if Checkbox_checked == true
if body == ["Солнце"]
g = 273.1
elseif body == ["Меркурий"]
g = 3.70
elseif body == ["Венера"]
g = 8.88
elseif body == ["Земля"]
g = 9.81
elseif body == ["Луна"]
g = 1.62
elseif body == ["Марс"]
g = 3.86
elseif body == ["Юпитер"]
g = 24.79
elseif body == ["Сатурн"]
g = 10.44
elseif body == ["Уран"]
g = 8.86
elseif body == ["Нептун"]
g = 11.09
elseif body == ["Плутон"]
g = 0.617
end
else
G = 6.67e-11
g = 4/3*pi*G*rho*(r*1000)^3/((r+h)*1000)^2
end
end
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
textfield("Средняя плотность небесного тела, кг/м^3:", :rho, style="width:400px"),
textfield("Радиус небесного тела, км:", :r, style="width:400px"),
cell([p("Высота над поверхностью, км:"), slider(0:1:100, :h, label="", style="width:364px")]),
btn("Расчет", @click(:Button_process), color = "primary"),
end
@page("/", ui)
Вывод результатов на экран
Приложение почти готово. Осталось вывести результат расчета на экран. Для этого нужно описать выходную переменную g в модели данных и создать текстовое поле для вывода значения этой переменной.
✏️Задание 8
Завершите построение приложения:
- В модель данных добавьте описание выходной переменной
g:
@out g = 0.0
- В интерфейсную часть кода добавьте команду:
textfield("Ускорение свободного падения, м/с^2:", :g, style="width:400px")
Здесь аргументы задаются аналогично тому, как вы это делали для других текстовых полей. Обратите внимание на то, что в конце запятая не нужна, т.к. это последний элемент интерфейса в данном приложении.
Решение
using GenieFramework, Stipple
@app begin
@in Checkbox_checked = true
@in body = ["Земля"]
@out body_list = ["Солнце", "Меркурий", "Венера", "Земля", "Луна", "Марс", "Юпитер", "Сатурн", "Уран", "Нептун", "Плутон"]
@in rho = 5515.3
@in r = 6371.0
@in h = 0.0
@in Button_process = false
@out g = 0.0
@onbutton Button_process begin
if Checkbox_checked == true
if body == ["Солнце"]
g = 273.1
elseif body == ["Меркурий"]
g = 3.70
elseif body == ["Венера"]
g = 8.88
elseif body == ["Земля"]
g = 9.81
elseif body == ["Луна"]
g = 1.62
elseif body == ["Марс"]
g = 3.86
elseif body == ["Юпитер"]
g = 24.79
elseif body == ["Сатурн"]
g = 10.44
elseif body == ["Уран"]
g = 8.86
elseif body == ["Нептун"]
g = 11.09
elseif body == ["Плутон"]
g = 0.617
end
else
G = 6.67e-11
g = 4/3*pi*G*rho*(r*1000)^3/((r+h)*1000)^2
end
end
end
function ui()
h5("Расчет ускорения свободного падения на различных небесных телах"),
checkbox("Выбрать небесное тело из списка", :Checkbox_checked),
select(:body, options = :body_list, label = "Выберите небесное тело:", style = "width:400px"),
textfield("Средняя плотность небесного тела, кг/м^3:", :rho, style="width:400px"),
textfield("Радиус небесного тела, км:", :r, style="width:400px"),
cell([p("Высота над поверхностью, км:"), slider(0:1:100, :h, label="", style="width:364px")]),
btn("Расчет", @click(:Button_process), color = "primary"),
textfield("Ускорение свободного падения, м/с^2:", :g, style="width:400px")
end
@page("/", ui)
Запуск приложения
✏️Задание 9
Запустите приложение:
- Находясь в папке данного курса, выполните в командной строке следующую команду:
engee.genie.start("app2.jl")
- Перейдите по ссылке, появившейся в ячейке вывода. Приложение откроется в новой вкладке браузера.
- Проверьте работу приложения в каждом из двух режимов при различных значениях входных данных.
Решение
Окно приложения:
✏️Задание 10
Пользуясь созданным приложением, рассчитайте ускорение свободного падения на поверхности карликовой планеты Эрида. Ее радиус равен 1163 км, а средняя плотность – 2520 .
Решение
Окно приложения:
В этом разделе мы рассмотрели лишь некоторые часто используемые элементы интерфейса Genie. Более полную информацию вы можете найти в документации Engee (описание библиотеки Stipple.jl) и на официальном сайте фреймворка Genie (страница "Component Gallery").