papagaj — GUI обертка для shell-скриптов. Yet another another *dialog

в 8:46, , рубрики: gnustep, GUI, iup, shell, ненормальное программирование, Оболочки, метки: , , ,

papagaj — GUI обертка для shell скриптов. Yet another another *dialog
Когда я впервые узнал об утилитах dialog, xdialog, zenity я был поражен тем, что буквально из пары строк можно было создать графический интерфейс для скрипта.
Однако, когда я пошел дальше и захотел создать что-то более сложное, чем просто окошко со списком или диалог «Да/нет» — я был слегка разочарован, т.к. не смог найти требуемого. В итоге, мое знакомство с этой областью приостановилось на несколько лет.
Недавно я вспомнил о своем желании и попытался узнать о прогрессе в этом деле. Увы, и сейчас результат оказался не таким как ожидалось — я по-прежнему ничего не находил. По этой причине я и написал программу papagaj. Она позволяет из гов… и палок из xml-файла и пары скриптов построить несложный графический интерфейс для вашего консольного приложения.

Сперва об инструментах необходимых для сборки papagaj. Программа написана на ObjC с использованием библиотеки GNUStep Foundation, поэтому вам нужно иметь в системе установленные пакеты gnustep-base, gnustep-base-dev, gnustep-base-runtime.

Для сборки используется GNUmakefile, для него нужен будет пакет gnustep-make. На случай, если вы не хотите устанавливать gnustep-make я приведу обычный Makefile.

В качестве графической библиотеки я использовал IUP, расположенной по адресу www.tecgraf.puc-rio.br/iup/. В README содержатся инструкции по сборке библиотеки. Имейте в виду, что она требует dev-пакетов для Gtk, т.к. является оберткой для этой библиотеки.

Я не буду описывать установку всех пакетов, у каждого из них есть неплохая документация на этот случай.

После удачной установки перечисленных выше пакетов можно начинать собирать papagaj. Скачайте исходники из git-репозитория, зайдите в директорию и смело набирайте make. В случае невероятного везения вы найдет готовый исполняемый файл papagaj-bin в директории ./obj/. Это и есть программа.

При желании можете переместить ее в /usr/*/bin или создать ссылку оттуда на исполняемый файл.

Makefile:

CC=gcc
CFLAGS=-O2 -W -Wall
IUP=-liup  
GNUSTEP=-lgnustep-base 
CONFIG= `pkg-config --cflags --libs gtk+-2.0` `gnustep-config --objc-flags`
INCLUD=-I/usr/include/iup
LIBS=$(GNUSTEP) $(IUP)
COMPLETE=$(CONFIG) $(INCLUD) $(IUP) $(GNUSTEP)


all: main.m
	$(CC) main.m -o papagaj-bin $(COMPLETE)


.PHONY: clean

clean:
	rm papagaj-bin
	rm *.d
	clear
Использование программы:

papagaj-bin interface-file [onstart-script], где
papagaj-bin — имя программы;
interface-file — файл с описанием интерфейса
onstart-script — файл с shell-скриптом, выполняемым при запуске программы.

Пример:

  • Файл интерфейса:
    				<application name="#app-name">
    					<dialog name="#dlg1" attributes='TITLE="sup, habr"' other="index">
    						<vbox name="#vbox1" attributes="EXPAND=YES, SIZE=100x100, MARGIN=15x15">
    							<button name="#btn1" attributes='TITLE="Click Me!",EXPAND=YES' callback="SHOW #dlg2 :"></button>
    						</vbox>
    					</dialog>
    					<dialog name="#dlg2" attributes='TITLE="SURPRISE!"'>
    						<vbox name="#vbox2" attributes="EXPAND=YES, MARGIN=15x15">
    							<label name="#lbl1" attributes='EXPAND=YES,TITLE="Sup, Хабр",FONT="Comic Sans MS, 50"' ></label>
    						</vbox>
    					</dialog>
    				</application>
    			

  • Результат:
    papagaj-bin index.xml # index.xml - файл интерфейса. см выше

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

Структура файла интерфейса.

Файлы интерфейса представляют собой обычные xml-файлы, содержащие описание вложенности виджетов.

Формат описания:

<widget-type name="#widget-name" attributes="<>" callback="<>" other=""></widget-type>

  • widget-type
  • name
    Имя виджета является обязательным, оно используется в обратных вызовах и позволяет обращаться к определнному виджету и изменять его настройки, например цвет, шрифт.
  • attributes
    Кроме того, на внешний вид приложения могут влиять значения атрибутов виджетов. Атрибуты могут принимать значения в нескольких форматах — логические, строчные, числа и размер/координаты.

    • Логические используются в тех случаях, когда значение атрибута виджета может принимать только два значения. Например, виджет может быть активен или нет, соответсвенно и значения могут быть YES или NO.
    • Строчные используются, если значение атрибута — набор символов, например заголовок диалога или содержимое текстового виджета.
    • Числа используются в случаях, когда надо указать какое-то конкретно значение, например значение положения ползунка. Используются довольно редко и с успехом заменяются строчными ( 90 == «90» и т.д.).
    • Размеры используются только в случае задания размера по ширинеи высоте одновременно.(100x50, 25x25).

    Список общих атрибутов для большинства виджетов:

    • ACTIVE — статус виджета (YES/NO).
    • BGCOLOR — цвет подложки в формате RGB («120 120 120»).
    • FGCOLOR — аналогично BGCOLOR, но только для содержимого («10 155 66»).
    • FONT — шрифт (FONT=«Comic Sans MS, 50»).
    • VISIBLE — видимость, в отличии от ACTIVE виджет невидим (YES/NO).
    • EXPAND — вомножность изменения размеров виджета (YES/NO/HORIZNOTAL/VERTICAL).
    • SIZE — размер виджета в пикселах в формате HEIGHTxWIDTH («100x100»).
    • TIP — текст, показываемый во всплывающей подсказке. Отображается при наведении курсора на виджет («wazzup!»).
    • TITLE — текст в заголовке виджета («some title»).
    • VALUE — значение элемента виджета, в некторых случаях аналогичен TITLE («some value»).

  • callback
    Обратный вызов.
    Для некоторых виджетов можно (и даже нужно) указать то, как они будут реагировать на различные действия пользователя.

    • Для кнопок, переключателей (toggle) — нажатие кнопки мыши.
    • Для списков — выбор элемента списка, двойной клик по элементу.
    • Для поля ввода — нажатие на клавишу Enter.

    Далее в статье будут показаны возможности обратных вызовов.

  • other
    Этот пункт важен только для типов dialog и list. При значении «index» диалог становится основным и при запуске программы именно он показывается первым. Для list other содержит обратный вызов на двойной клик.

Описание отдельных виджетов и их атрибутов.

  • hbox
    Располагает вложенные виджеты горизонтально, слево направо.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты:

    • ALIGMENT — вертикальное выравнивание виджетов.
      Возможные значения:

      • ATOP — по верхнему краю
      • ACENTER — по центру
      • ABOTTOM — по нижнему краю.

      По-умолчанию — ATOP.

    • GAP — расстояние между вложеными виджетами.
      По-умолчанию — 0.
    • MARGIN — расстояние отступа от края элемента. Получает значение в формате «ШИРИНАxВЫСОТА». Похож на свойство margin для css.
      По-умолчанию 0x0.
    • NORMALIZESIZE — приводит размеры вложенных виджетов к наибольшему среди них.
      Возможные значения:

      • NO — не изменяет размеры.
      • HORIZONTAL — приводит к ширине наибольшей среди вложенных виджетов.
      • VERTICAL — приводит к высоте наибольшей среди вложенных виджетов.
      • BOTH — изменяет и ширины и высоту.

      По-умолчанию — NO.

  • vbox
    Располагает вложенные виджеты вертикально, сверху вниз.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog
    Имеет те же атрибуты, что и hbox.

  • radio
    Контейнер для логического представления radio button (переключателя). Не выполняет какой-либо вертикальной либо горизонтальной компоновки.
    Если во вложенном контейнере (vbox/hbox) находятся виджеты типа toggle (checkbox) — превращает флажки в переключатели. Может принимать только один контейнер с элементами.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты:

    • VALUE — имя выбранного элемента.

    Пример использования:

    <radio name="#rd1" attributes="" callback="" other="">
    				<vbox name="#vbox1" attributes="" callback="" other="">
    					<toggle name="#n1" attributes='TITLE="Один"' callback="" other=""></toggle>
    					<toggle name="#n2" attributes='TITLE="Два"' callback="" other=""></toggle>
    					<toggle name="#n3" attributes='TITLE="Три"' callback="" other=""></toggle>
    				</vbox>
    			</radio>

  • frame
    Окружает вложенные виджеты рамкой с подписью.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

  • tabs
    Вкладки. Для каждого вложенного контейнера создает отдельную вкладку.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты:

    • COUNT — количество вкладок. Число или строка.
    • PADDING — задает внутренние отступы для каждой вкладки. Принимает значение в виде «ШИРИНАхВЫСОТА».
      По-умолчанию — 0х0.
    • TABTITLEn — задает заголовок для вкладки n, где n — номер вкладки, отсчет начинается с 0. Чтобы создать мнемоническую команду (Alt+SOME_KEY) для выбора вкладки, перед выбранным символом должен находиться символы "__".

  • label
    Элемент с текстовой строкой.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog
    Атрибуты:

    • ALIGNMENT — задает вертикальное и горизонтальное выравнивание текста в формате «HORIZONTAL:VERTICAL».
      Возможные значения:

      • Горизонтальное выравнивание:
        ALEFT — по левому краю.
        ACENTER — по центру.
        ARIGHT — по правому краю.
      • Вертикальное выравнивание:
        ATOP — по верхнему краю.
        ACENTER — по центру.
        ABOTTOM — по нижнему краю.

      По-умолчанию — ALEFT:ACENTER.

    • PADDING — устанавливает отступы от границ виджета в формате ШИРИНАхВЫСОТА.
      По-умолчанию — 0х0.
    • SEPARATOR — позволяет превратить ярыл в вертикальный или горизонтальный разделитель.
      Возможные значения:

      • HORIZONTAL — горизонтальный разделитель.
      • VERTICAL — вертикальный разделитель.

  • button
    Кнопка с подписью. При нажатии активирует обратный вызов, записанный в атрибуте callback.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты аналогичны атрибутам элемента label.

  • list
    Список с несколькими элементами. Список элементов задается в атрибутах.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    1="Один"

    — заголовок первого элемента — «Один»

    2="Два"

    — второго — «Два»

    3="Три"

    — третьего — «Три»

    n="Какой-нибудь"

    — n-го — «Какой-нибудь»

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты:

    • APPENDITEM — используется в обратных вызовах для добавления новго элемента в список.
    • AUTOHIDE — Скрытие полосы прокрутки (YES/NO).
      По-умолчанию — YES.
    • COUNT — количество элементов в списке.
    • DROPDOWN — создание выпадающего списка (YES/NO).
      По-умолчанию — NO.
    • MULTIPLE — возможность выбора нескольких элементов одновременно (YES/NO).
      По-умолчанию — NO.
    • VALUE — возвращает выбранные элементы. Существует несколько вариантов возвращаемого значения:
      • Возвращает номер выбранного элемента, при условии что следующие атрибуты заданы DROPDOWN=YES или MULTIPLE=NO.
      • Возвращает последовательность символов "+" и "-" для выбранного и невыбранного элемента соответственно, если список позволяет выбирать несколько элементов одновременно.

    Пример использования:

    <vbox name="#vbox0" attributes="GAP=10">
    				<list name="#lst1" attributes='1="1",2=2,3=3,4=4,EXPAND=YES' callback="" other=""></list>
    		</vbox>

  • oneline
    Однострочное поле ввода.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

    Атрибуты:

    • APPEND — добавляет текст к уже существующему.
    • INSERT — вставляет текст в начале текущей позиции курсора, если при этом в поле ввода выделен какой-либо текст — замещает выделенное.
    • PADDING — устанавливает отступы от границ виджета в формате ШИРИНАхВЫСОТА.
      По-умолчанию — 0х0.
    • READONLY — запрещает возможность редактирования данных (YES/NO).
      По-умолчанию — NO.
    • APPEND — добавляет новый текст в конец.

  • multiline
    Многострочный текстовый виджет. Основные атрибуты те же, что и у oneline.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

  • progressbar
    Индикатор прогресса чего-нибудь.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog
    Атрибуты:

    • MIN — минимальное значение.
    • MAX — максимальное значение.
    • VALUE — текущее значение.

  • toggle
    Флажок или переключатель (см.radio). По атрибутам и обратным вызовам сходен с button.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog

  • vscale/hscale
    Вертикальный/горизонтальный ползунок.

    papagaj — GUI обертка для shell скриптов. Yet another another *dialog
    Атрибуты:

    • MIN — минимальное значение.
    • MAX — максимальное значение.
    • VALUE — текущее значение.

Для более подробного описания всех атрибутов виджетов обратитесь к документации по библиотеке IUP, расположенной в www.tecgraf.puc-rio.br/iup/

Описание возможностей обратного вызова.

Формат команд для обратного вызова:

<word1> <word2> ... <wordN> :

Правила:

  1. Все слова длолжны быть разделены между собой символом пробела, табуляции или новой строки.
  2. Символ двоеточия сообщает обработчику обратного вызова об окончании текущей команды. После этого начнется непосредственное выполнение полученной команды.

Команды обратного вызова размещаются в атрибутах callback (и other для элемента list).

Значения атрибутов виджетов, переменные в приложении.

  • Атрибуты виджетов.
    Если вы просматривали небольшие примеры, приведенные выше, вы наверняка заметили, что имена всех виджетов начинались с символа решетки (#).
    Это, конечно, не случайно. Дело в том, что # используется для обозначения виджета в обратных вызовах и позволяет обращаться к атрибутам виджета, получая значения или, наоборот, меняя их. Теперь кратко: имя виджета должно начинаться с символа решетки и не содержать каких-либо пробельных символов.
    Пример:
    #widget-name WIDGET-ATTRIBUTE
  • Переменные приложения.
    Переменные приложения хранят ранее сохраненные в них данные. Переменные доступны по всему приложению, т.е. созданная в результате обратного вызова одного виджета, доступна для обработки в обратном вызове другого виджета. Если переменная ранее не определялась, при подстановке она возвращает пустое значение. И самое главное, имя переменной ДОЛЖНО начинаться с символа нижнего подчеркивания и не должно содержать пробельных символов.
    Пример:
    _some-variableName
  • Присвоение значений атрибутам виджета и переменным.
    Чтобы присвоить новое значение атрибуту виджета необходимо указать имя виджета, атрибут,"=" и новое значение. Не забывайте о пробелах между словами.
    Пример:
    #dlg1 TITLE = "Hello world" :
    Аналогично присваивается новое значение и переменной — название переменной,"=", новое значение.
    _some-variable = "hello world" :
    Обратите внимание на пробелы между словами и двоеточие, как символ окончания команды.

    Пример.

    		<application name="#app">
    			<dialog name="#dlg" attributes='SIZE=150x150, TITLE="Неизмененное значение"' other="index">
    				<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15">
    					<button name="#b1" attributes='TITLE="Нажми меня",EXPAND=YES' callback='#dlg TITLE = "Измененное значение" :'/>
    				</vbox>
    			</dialog>
    		</application>
    	

    При нажатии на кнопку, заголовок окна будет изменен.

  • Подстановка значений.
    В обратных вызовах также возможна подстановка значений атрибутов виджетов и переменных. Общий формат:
    #widget-name ATTRIBUTE = #widget-name2 ATTRIBUTE: — производится подстановка значения атрибута ATTRIBUTE виджета #wdiget-name2.
    #widget-name ATTRIBUTE = _variable: — производится подстановка значения переменной _variable.
    _variable = #widget-name ATTRIBUTE: — производится подстановка значения атрибута ATTRIBUTE виджета #wdiget-name2.

    Рассмотрим на примере:

    				<application name="#app">
    					<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index">
    						<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15">
    							<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/>
    							<label name="#lbl2" attributes='TITLE="Мир",EXPAND=YES'/>
    							<button name="#b1" attributes='TITLE="Swap!",EXPAND=YES' callback='_swap = #lbl1 TITLE : #lbl1 TITLE = #lbl2 TITLE : #lbl2 TITLE = _swap :'/>
    						</vbox>
    					</dialog>
    				</application>
    			

    Создан файл интерфейса с двумя ярлыками и одной кнопкой, при нажатии на кнопку подписи в ярлыках меняются местами. Разберем обратный вызов кнопки подробнее:

    _swap = #lbl1 TITLE :

    — создается переменная _swap, с содержимым подписи первого ярлыка.

    #lbl1 TITLE = #lbl2 TITLE :

    — задается значение #lbl1 TITLE равным #lbl2 TITLE.

    #lbl2 TITLE = _swap :

    — присваивает значение переменной _swap атрибуту TITLE виджета #lbl2.

  • Удаление, добавление, вставка виджетов.
    Изменения интерфейса могут быть более глобальными нежели просто измение цвета/размера заголовка ярлыка — можно изменять количество виджетов в контейнерах, удаляя из одних, добавляя к другим и вставляя к третьим.

    • Удаление виджетов
      Чтобы удалить какой-либо виджет из родительского контейнера используется команда DETACH:
      DETACH #widget-name :

      					<application name="#app">
      						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index">
      							<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15">
      								<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/>
      								<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback='DETACH #lbl1 :'/>
      							</vbox>
      						</dialog>
      					</application>
      				

      При нажатии на кнопку удаляется виджет #lbl1.

    • Добавление виджета в контейнер.
      Для добавление виджета используется команда APPEND.
      APPEND #widget-parent #widget-child,
      где #widget-parent — новый родитель для #widget-child

      					<application name="#app">
      						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index">
      							<vbox name="#main" attributes="EXPAND=YES">
      								<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15">
      									<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/>
      									<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback='DETACH #lbl1 :'/>
      								</vbox>
      								<vbox name="#vbox2" attributes="EXPAND=YES,MARGIN=15x15">
      									<button name="#b2" attributes='TITLE="append",EXPAND=YES' callback='APPEND #vbox2 #lbl1 : '/>
      								</vbox>
      							</vbox>
      						</dialog>
      					</application>
      				

      При нажатии на кнопку detach, виджет #lbl1 будет удален из контейнера #vbox1. При нажатии на кнопку append, #lbl1 будет присоединен к контейнеру #vbox2. Обратите внимание на то, что добавляемый виджет сперва должен быть удален из предыдущего контейнера.

    • Добавление виджета в определенную позицию.
      При использовании команды APPEND виджет будет добавлен в конец контейнера. Существует возможность вставки виджета в опреденную позицию в контейнере, для этого используется команда INSERT.
      INSERT #new-parent-container #ref-widget #new-widget,
      где #new-parent-container — контейнер, куда будет добавлен виджет,
      #ref-widget — виджет, ПЕРЕД которым будет вставлен новый виджет
      #new-widget — новый виджет

      					<application name="#app">
      						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index">
      							<vbox name="#main" attributes="EXPAND=YES">
      								<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15">
      									<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/>
      									<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback=''/>
      								</vbox>
      								<vbox name="#vbox2" attributes="EXPAND=YES,MARGIN=15x15">
      									<button name="#b2" attributes='TITLE="insert",EXPAND=YES' callback='DETACH #lbl1 : INSERT #vbox2 #b2 #lbl1 : '/>
      								</vbox>
      							</vbox>
      						</dialog>
      					</application>
      				

  • Отображение диалогов.
    Кроме основного диалога, который отображается при старрте программы можут быть и другие.
    Они определяются на том же уровне вложенности, что и основной диалог, но остаются скрытыми. Чтобы отобразить их используется команда SHOW.
    SHOW #some-dialog :,
    где #some-dialog — имя диалога

    Пример:

    			<application name="#app">
    				<dialog name="#dlg" attributes='TITLE=""' other="index">
    					<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
    						<button name="#b1" attributes='TITLE="SHOW",EXPAND=YES' callback='SHOW #dlg2 :'/>
    					</vbox>
    				</dialog>
    				<dialog name="#dlg2" attributes='TITLE="привет",SIZE=50x50'>
    					<vbox name="#vbox" attributes="EXPAND=YES, MARGIN=15x15">
    						<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/>
    					</vbox>
    				</dialog>
    			</application>
    		

    При нажатии на кнопку SHOW отобразится диалог #dlg2

  • Кроме размещения скрытых диалогов на первом уровне вложенности могут находиться и другие виджеты, которые могут понадобиться позднее. Их можно присоединить командой APPEND или INSERT.
    	
    			<application name="#app">
    				<dialog name="#dlg" attributes='TITLE=""' other="index">
    					<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
    						<button name="#b1" attributes='TITLE="APPEND",EXPAND=YES' callback='APPEND #main #vbox2 :'/>
    					</vbox>
    				</dialog>
    				<vbox name="#vbox2" attributes='EXPAND=YES, MARGIN=15x15, FGCOLOR="100 50 250"'>
    					<label name="#some-label" attributes='TITLE="SOME LABEL"' />
    				</vbox>
    			</application>
    		

Несколько слов об исполнении shell-скриптов и других внешних программ.

Обратным вызовом может быть выполнение и внешних прорамм, таких как shell-скрипты, команды оболочки и т.п.

Если программа не может разобрать обратный вызов виджета, она предполагает, что он является внешней командой и обращается к оболочке для исполнения команды.
Пример:

	<application name="#app">
		<dialog name="#dlg" attributes='TITLE=""' other="index">
			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
				<multiline name="#content" attributes="EXPAND=YES" />
				<button name="#b1" attributes='TITLE="List",EXPAND=YES' callback='ls -l' />
			</vbox>
		</dialog>
	</application>

При нажатии на кнопку List будет выполнена команда оболочки ls -l.

Однако, какой смысл в выполнении команды, если нет возможности увидеть результат? Так как программы зачастую выводят множество информации, которая нам не нужна есть ее следует отфильтровать и только затем вернуть в основную программу.
Пример:
ls -a | awk '{printf(" #content APPEND = "%s" : ", $0);}'

Но даже сейчас вывод команды никак не воздействует на основную программу. Чтобы вернуть информацию в вызывающую программу сперва должен идти маркер о начале приема информации — !BEGIN. Маркер !END сообщает об окончании приема. Т.е. весь вывод находящийся между этими двумя маркерами будет считаться валидными командами для программы и она будет стремиться их выполнить.

Поместим ls -a | awk '{printf(" #content APPEND = "%s" : ", $0);}' в файл ls.sh и добавим маркеры для получения результата.
ls.sh:

	echo "!BEGIN "
	ls -a | awk '{printf(" #content APPEND = "%s" : ", $0);}'
	echo " !END"

Файл с описанием интерфейса:

	<application name="#app">
		<dialog name="#dlg" attributes='TITLE=""' other="index">
			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
				<multiline name="#content" attributes="EXPAND=YES" />
				<button name="#b1" attributes='TITLE="List",EXPAND=YES' callback='bash ./ls.sh :'/>
			</vbox>
		</dialog>
	</application>

Теперь при нажатии на кнопку List в текстовый виджет #content будет добавлен результат выполнения скрипта ls.sh.

Стоит заметить, что подстановка значений атрибутов или переменных происходит и в командах для выполнения в оболочке.
Следующая программа возвращает список файлов в директории указанной в #addr.

	echo "!BEGIN "
	ls -a $1 | awk '{printf(" #content APPEND = "%s" : ", $0);}'
	echo " !END"

	<application name="#app">
		<dialog name="#dlg" attributes='TITLE=""' other="index">
			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
				<oneline name="#addr" attributes="EXPAND=HORIZONTAL" />
				<multiline name="#content" attributes="EXPAND=YES" />
				<button name="#b1" attributes='TITLE="APPEND",EXPAND=YES' callback='#content VALUE = "" : bash ./ls.sh #addr VALUE :'/>
			</vbox>
		</dialog>
	</application>

Скрипты, выполняемые при запуске.

Кроме файла интерфейса, параметром для papagaj-bin может быть еще файл скрипта, выполняемый при запуске программы. Это должен быть просто shell-скрипт, похожий на используемый нами ранее ls.sh. Дальше, в примерах, показывается как использовать скрипты при запуске и зачем они вообще нужны.

В завершение несколько простых примеров:

Ползунок и индикатор прогресса:

<application name="#app">
	<dialog name="#dlg" attributes='TITLE=""' other="index">
		<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
			<progressbar name="#bar" attributes='EXPAND=YES,MIN=0,MAX=100,VALUE=50' />
			<hscale name="#scale" attributes='EXPAND=YES,MIN=0,MAX=100,VALUE=-50' callback="#bar VALUE = #scale VALUE :"/>
		</vbox>
	</dialog>
</application>

papagaj — GUI обертка для shell скриптов. Yet another another *dialog

Список и поле ввода

<application name="#app">
	<dialog name="#dlg" attributes='TITLE=""' other="index">
		<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
			<oneline name="#addr" attributes="EXPAND=HORIZONTAL" callback="#lst APPENDITEM = #addr VALUE :"/>
			<list name="#lst" attributes="EXPAND=YES" />
		</vbox>
	</dialog>
</application>

papagaj — GUI обертка для shell скриптов. Yet another another *dialog
Небольшая графическая обертка для команды ls -a
Файл интерфейса:

<application name="#app">
		<dialog name="#dlg1" attributes='EXPAND=YES,TITLE="YAFM",SIZE=500x200' other="index">
			<vbox name="#main" attributes="NGAP=10,EXPAND=YES">
				<hbox name="#top-fill" attributes="MARGIN=5x5"></hbox>
				<hbox name="#list-panel" attributes="EXPAND=YES,MARGIN=5x5" >
					<vbox name="#lst-cont" attributes="EXPAND=YES,NGAP=5" >
						<hbox name="#up-cont" attributes="MARGIN=0x0" >
							<oneline name="#curr-pos" attributes='EXPAND=HORIZONTAL'></oneline>
							<button name="#btn-go-lst" attributes='TITLE="Go/Refresh",EXPAND=NO' callback='bash ./change_dir.sh #curr-pos VALUE :'></button>
						</hbox>
						<list name="#lst" attributes='EXPAND=YES,MULTIPLE=NO,EDITBOX=YES' callback='_active = "#lst1" : ' />
					</vbox>
				</hbox>
			</vbox>
		</dialog>
</application>

Скрипт исполняемый при загрузке:
onstart.sh

pwd_now=$PWD
echo " !BEGIN "
echo " #curr-pos VALUE = "$pwd_now" : "
bash get_filelist.sh $pwd_now
echo " !END"

Пара вспомогательных скриптов:
change_dir.sh

echo " !BEGIN "
echo " #lst REMOVEITEM = ALL : "
bash ./get_filelist.sh $1
echo " !END "

get_filelist.sh

# взял из http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

SAVEIFS=$IFS
IFS=$(echo -en "nb")
cd $1
some_files=$(ls -a)
for x in  $some_files; 
do 
	if [ -d $x ]; 
		then 
			echo " #lst APPENDITEM = "[$x]" : "; 
		else 
			echo " #lst APPENDITEM = "$x" : "; 
	fi; 
done
IFS=$SAVEIFS

papagaj — GUI обертка для shell скриптов. Yet another another *dialog

Использование papagaj совместно с zenity

<application name="#app">
        <dialog name="#dlg" attributes='TITLE=""' other="index">
            <vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">
                <oneline name="#content" attributes="EXPAND=YES,READONLY=YES" />
                <button name="#b1" attributes='TITLE="My name is ...",EXPAND=YES' callback='echo "!BEGIN #content VALUE = ""; zenity --entry ; echo "" : !END " :' />
            </vbox>
        </dialog>
</application>

papagaj — GUI обертка для shell скриптов. Yet another another *dialog

Несколько ссылок:

git-репозиторий papagaj
GNUStep.org
Страница проекта IUP на сайте Tecgraf/PUC-Rio

С радостью отвечу на вопросы.
p.s. если заметите опечатку или что-то подобное — сообщите в личку, буду очень благодарен.

Автор: rikardoac

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js