LinuxForum.Fans
Тема

bash (sh) & gtkdialog

Автор: sklimkin 7 сообщений 2725 просмотров
#284545

GUI-диалог для программы scrot
Есть такая "всемирно известная" программа для "фотографирования" экрана или его частей - scrot
Есть и многие другие подобные программы, но это интересна тем, что она:
1. маленькая по размеру и зависимостям
2. присутствует в репозиториях всех маленьких Линуксов
3. имеет достаточное для практики количество ключей
4. легко интегрируется с программами позволяющими реализовать графический интерфейс с пользователем, т.е. окно.

Есть еще одна программа, компактная по коду и зависимостям, также доступная из самых разных репозиториев: gtkdialog
gtkdialog позволяет вызывать его из скриптов bash/sh и иже с ними, и даже из кода написанного на СИ (например gcc & GTK+).

Вот что из этого получилось:
-----------------------------------------
Программа scrot создает файл - снимок экрана в том каталоге, откуда она вызывается.

Включение в код скрипта chooser'а было бы бессмысленным, если бы созданный программой scrot файл не перемещался туда, куда указал пользователь.

Help смотри в конце поста, или еще проще: scrot --help

Но команда перемещения, указанная в help'е scrot вида:
scrot operation.png -e 'mv $f /home/kurt/Desktop/'
работает только из командной строки терминала и не работает из скрипта, если имя файла задает сам scrot.
Поясняю:
1. если задавать имя файла явно, то премещение происходит,
2. если создание имени файла доверить scrot'у, то премещение не происходит,
3. создание имени файла scrot'ом предпочтительно потому, что он включает в него дату и время до секунд - это не создает конфликта имен файлов, если делается более одного снимка за сеанс.

Поэтому процесс создания и перемещения скриншота/скриншотов решается в 2 приема:
scrot "$COMMANDSTRING"
- в этой строке параметры захвата экрана и время задержки снимка
mv `echo *_scrot.png` "$FILE"
- а в этой строке получение имени файла, созданного scrot'ом и адрес, куда переместить этот файл.

Команда нахождения имени файла обязательно берется в обратные (или косые) кавычки - тогда то, что в них интерпретируется именно как КОМАНДА.
Каталог назначения $FILE берется в двойные кавычки на тот случай, если в нем окажется нечто типа <Рабочий стол>, то есть в имени есть пробелы.
Иначе до команды mv дойдет только <стол> и она не сработает.

Таким образом команда mv получает правильное имя файла и правильный каталог назначения.

Нет в компьютерном мире совершенства: если в каталоге со скриптом будут файлы, с окончанием на _scrot.png то перемещения снимка не получится и снимок осядет в этом ТЕКУЩЕМ каталоге.
Значит надо "следить за чистотой рядов".

Если кто-то знает более изящное решение вопроса, с удовольствием поучусь.

text
#!/bin/bash 
## or /bin/sh
funccommand () {
if [ "$COMBOBOX1" == "All" ]; then
COMMAND1="-m"
else COMMAND1="-s"
fi
## !!! Attention: This works in scrot ver. >= 0.8 only !!!
if [ "$COMBOBOX1" == "Window" ]; then
COMMAND1="-u"
fi
COMMAND2="$COMBOBOX2"
COMMANDSTRING="$COMMAND1-b-d $COMMAND2"
##echo "COMMANDSTRING= $COMMANDSTRING"
##echo "COMBOBOX1= $COMBOBOX1"
##echo "COMBOBOX2= $COMBOBOX2"
##echo "FILE= $FILE"
scrot "$COMMANDSTRING"
mv `echo *_scrot.png` "$FILE"
}

export MAIN_DIALOG=" <window> <vbox> <text> <label>SCReenshOT screen-grabber</label> </text> <frame Command button EXIT> <hbox> <button cancel></button> </hbox> </frame> <frame User-settings> <hbox> <vbox> <text> <label>Select grab-mode</label> </text> <combobox> <variable>COMBOBOX1</variable> <item>All</item> <item>Window</item> <item>Area</item> <action>save:COMBOBOX1</action> </combobox> </vbox> <vbox> <text> <label>Time-delay-sec</label> </text> <combobox> <variable>COMBOBOX2</variable> <item>0</item> <item>1</item> <item>2</item> <item>3</item> <item>5</item> <item>10</item> <item>20</item> <action>save:COMBOBOX2</action> </combobox> </vbox> <button> <label>ACCEPT</label> <action>$0 func</action> </button> </hbox> </frame> <frame Select DIR for save screenshot> <chooser> <height>200</height> <width>200</width> <variable>FILE</variable> <default>/home/</default> <action>save:FILE</action> <action>$2= $FILE</action> </chooser> </frame> </vbox> </window> "

case $1 in func) funccommand $2 ;; *) gtkdialog --program=MAIN_DIALOG ;; esac

Ссылки по теме:
http://ru.wikibooks.org/wiki/UNIX
http://en.wikipedia.org/wiki/Scrot
http://linuxandfriends.com/2008/10/25/take-screenshots-in-linux-with-scrot/
http://www.itnewb.com/tutorial/Using-Scrot-the-Screen-Shot-Command-Line-Utility-for-Linux

P.S. Закомментированные строки вида: ##echo ... ...
были нужны только для отладки, их можно смело удалить.
В строке mv `echo *_scrot.png` "$FILE" обязательно заключается в одинарные обратные (или косые) кавычки echo *_scrot.png.
Это буква Ё - но в латинской раскладке
обратите на это внимание, то есть: ОБРАТНАЯ_КАВЫЧКАecho *_scrot.pngОБРАТНАЯ_КАВЫЧКА

#284550

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

text
funccommand () {
if [ "$COMBOBOX1" == "All" ]; then
COMMAND1="-m"
else COMMAND1="-s"
fi
## !!! Attention: This works in scrot ver. >= 0.8 only !!!
if [ "$COMBOBOX1" == "Window" ]; then
COMMAND1="-u"
fi
COMMAND2="$COMBOBOX2"
COMMANDSTRING="$COMMAND1-b-d $COMMAND2"
cd "$FILE"
scrot "$COMMANDSTRING"
} 

Варианты того же самого на СИ смотри:
http://linuxforum.ru/viewtopic.php?pid=308495#p308495

#284581
"sklimkin" написал:
Если кто-то знает более изящное решение вопроса, с удовольствием поучусь.

Можно самому задавать имя файла.

PS. А что программа должна делать то? GUI для scrot?

#284621

Можно самому задавать имя файла.

scrot по умолчанию вставляет в имя файла дату и время до секунд - это удобно.
Если делать больше 2-х снимков подряд, то не возникает конфликта имен.
Можно и самому задавать, много чего можно...

text
А что программа должна делать то? GUI для scrot?

Да.

#284622
"sklimkin" написал:
scrot по умолчанию вставляет в имя файла дату и время до секунд - это удобно.

Можно формировать имя с помощью date.

#285743

Вот пример, в котором bash+gtkdialog открывают из одного окна другое, из другого третье.
Это всего-лишь этюд. И я пока не нашел правильного способа закрывать одно окно из другого или из него самого.

text
#! /bin/bash

funccommand () { if [ "$COMBOBOX1" == "All" ]; then COMMAND1="-m" else COMMAND1="-s" fi ## !!! Attention: This works in scrot ver. >= 0.8 only !!! if [ "$COMBOBOX1" == "Window" ]; then COMMAND1="-u" fi COMMAND2="$COMBOBOX2" COMMANDSTRING="$COMMAND1-b-d $COMMAND2" ##cd "$FILE" _dir=`dirname "$FILE"` cd "${_dir}" echo FILE= "${_dir}" scrot "$COMMANDSTRING" }; export -f funccommand

export CHOOSER2=' <window width-request="240" title="Select target DIR" decorated="true"> <vbox> <hbox> <text> <variable>FILE</variable> <label>Pick any file in target DIR</label> </text> <button> <input file stock="gtk-open"></input> <action>Fileselect:FILE</action> <action>echo return_value: $?</action> <action>echo FILE= $FILE</action> </button> </hbox> </vbox> </window>'

export CHOOSER=' <window title="Chooser"> <frame Select DIR for save screenshot> <chooser> <width>320</width> <height>250</height> <variable>FILE</variable> <default>/home/</default> <action>save:FILE</action> <action>echo FILE= $FILE</action> </chooser> </frame> </window> '

export DIALOG1=' <window title="Dialog1" width-request="320"> <vbox> <text> <label>Select options in combo-boxes</label> </text> <frame Widgets> <hbox spacing="5"> <combobox width-request="90"> <width>10</width> <variable>COMBOBOX1</variable> <item>All</item> <item>Window</item> <item>Area</item> <action>save:COMBOBOX1</action> </combobox> <combobox width-request="60"> <width>10</width> <variable>COMBOBOX2</variable> <item>0</item> <item>1</item> <item>2</item> <item>3</item> <item>5</item> <item>10</item> <item>20</item> <action>save:COMBOBOX2</action> </combobox> <button> <label>ACCEPT</label> <action>funccommand</action> </button> </hbox> </frame> <hbox> <button> <label>Select DIR</label> <action>Launch:CHOOSER</action> </button> <button> <label>Select DIR2</label> <action>Launch:CHOOSER2</action> </button> <button> <label>Main Dialog</label> <action>Launch:MAIN_DIALOG</action> </button> <button> <label>Close</label>

<action>Closewindow:DIALOG1</action>

</button> </hbox> </vbox> </window> '

export MAIN_DIALOG=' <window title="SCROT gtkdialog" width-request="280" height-request="260"> <vbox> <frame Widgets> <checkbox> <label>This is a checkbox</label> <variable>CHECKBOX</variable> </checkbox> <entry> <input>date</input> <variable>ENTRY</variable> </entry> </frame> <frame Button actions> <hbox> <button> <label>launch DIALOG1</label> <action>Launch:DIALOG1</action> </button> <button> <label>close window ONLY</label>

<action>Closewindow:MAIN_DIALOG</action>

</button> </hbox> <hbox homogeneous="true"> <button> <label>enable</label> <action type="enable">ENTRY</action> <action type="enable">CHECKBOX</action> </button> <button> <label>disable</label> <action type="disable">ENTRY</action> <action type="disable">CHECKBOX</action> </button> </hbox> <hbox homogeneous="true" spacing="5"> <button> <label>refresh</label> <action type="refresh">ENTRY</action> </button> <button> <label>clear</label> <action type="clear">ENTRY</action> </button> <button> <label>fileselect</label> <action>Fileselect:ENTRY</action> </button> </hbox> </frame> <hbox> <button cancel></button> </hbox> </vbox> </window> '

case $1 in func) funccommand $2 ;; *) gtkdialog --program=MAIN_DIALOG ;; esac

Здесь показаны также 2 разных способа вызова окна file-chooser:
CHOOSER и CHOOSER2

#287937

3 новых варианта на bash скриншотера scrotdlg
http://www.mediafire.com/?mzill1xlng47g31

bash и gtkdialog позволяют создать окно, содержащее вверху панель-меню
и одновременно поместить на это окно некоторые виджеты.

Это пример-этюд. В скрипте 3 диалога: MAIN_DIALOG, CHOOSER, ABOUT и 1 ф-ция funccommand()
которые дают представление о чем-то большем, чем стандартные примеры с 1-2 кнопками.
Если у Вас есть abiword, gnumeric, gimp, то они открываются из меню "Run Programs".
Из меню "Help" в окно терминала выводятся некоторые man-страницы.
В меню "About" краткий текст "О программе" и "Выход".
Есть еще StatusBar, но до его "наполнения" я пока не добрался.
Дальше можно перекраивать/наполнять этот этюд под свои задачи (на то он и этюд).

Показать
text
#!/bin/bash

GTKDIALOG=gtkdialog

IMAGEFILE=( $(find /usr/share/icons -maxdepth 4 -type f | head -3) )

funccommand () { if [ "$COMBOBOX1" == "All" ]; then COMMAND1="-m" else COMMAND1="-s" fi ## !!! Attention: This works in scrot ver. >= 0.8 only !!! if [ "$COMBOBOX1" == "Window" ]; then COMMAND1="-u" fi COMMAND2="$COMBOBOX2" COMMANDSTRING="$COMMAND1-b-d $COMMAND2" _dir=`dirname "$FILE"` cd "${_dir}" echo FILE= "${_dir}" scrot "$COMMANDSTRING" }; export -f funccommand

export ABOUT=' <window title="About"> <text> <variable>PROGRAM</variable> <label>This program is only demonstration of some possibilities of sharing of the program gtkdialog and bash-script. Here are specially used menubar and a main window with widgets. Also as well as various methods of a call of functions. See FileChooser in menubar & DIR-icon in main-window. It is only demo.</label> </text> <action>echo PROGRAM= $PROGRAM</action> </window> '

export CHOOSER=' <window title="Chooser"> <frame DubleClick any file in Selected DIR for save screenshot> <chooser> <width>360</width> <height>250</height> <variable>FILE</variable> <default>/home/</default> <action>save:FILE</action> <action>echo FILE= $FILE</action>

</chooser> </frame> </window> '

export MAIN_DIALOG=' <window title="MenuBar" resizable="false" width-request="300" height-request="120" border-width="1"> <vbox spacing="1"> <vbox> <menubar> <menu label="About"> <menuitem stock-id="gtk-about"> <action>Launch:ABOUT</action> </menuitem>

<menuitem stock-id="gtk-add"></menuitem> <menuitem stock-id="gtk-file"></menuitem> <menuitemseparator></menuitemseparator> <menuitem stock-id="gtk-quit" accel-key="0x51" accel-mods="4"> <action>exit:Quit</action> </menuitem> </menu>

<menu> <menuitem icon-name="abiword" label="AbiWord"> <action>abiword</action> </menuitem> <menuitem icon-name="gnumeric" label="Gnumeric 32px"> <height>32</height> <action>gnumeric</action> </menuitem> <menuitem icon-name="gimp" label="_Gimp 48px" use-underline="true"> <height>48</height> <action>gimp</action> </menuitem>

<menuitem label="FileChooser"> <action>Launch:CHOOSER</action> </menuitem>

<label>"Run Programs"</label> </menu>

<menu label="Help"> <menuitem label="Help"> <action>help</action> </menuitem> <menuitem label="help export"> <action>'"help export"'</action> </menuitem> <menuitem label="help cd"> <action>'"help cd"'</action> </menuitem> <menuitem label="help set"> <action>'"help set"'</action> </menuitem> </menu> </menubar>

<hbox> <text> <variable>FILE</variable> <label>Pick any file in target DIR</label> </text> <button> <input file stock="gtk-open"></input> <action>Fileselect:FILE</action> <action>echo FILE= $FILE</action> <action type="$FILE">"$StatBar"</action> <action>echo StatBar= "$StatBar"</action> </button> <button cancel></button> </hbox>

<hbox> <combobox width-request="90"> <width>10</width> <variable>COMBOBOX1</variable> <item>All</item> <item>Window</item> <item>Area</item> <action>save:COMBOBOX1</action> </combobox> <combobox width-request="60"> <width>10</width> <variable>COMBOBOX2</variable> <item>0</item> <item>1</item> <item>2</item> <item>3</item> <item>5</item> <item>10</item> <item>20</item> <action>save:COMBOBOX2</action> </combobox> <button> <label>ACCEPT</label> <action>funccommand</action> </button> </hbox>

<statusbar has-resize-grip="false"> <variable>StatBar</variable> <label>StatBar: Message from an input commande</label> <default>StatBar: Message from an input command</default> <input>echo StatBar: Message from an input command</input> <input file>inputfile</input> <sensitive>true</sensitive> <output file>outputfile</output> </statusbar> </vbox> </vbox> </window> '

case $1 in -d | --dump) echo "$MAIN_DIALOG" ;; *) $GTKDIALOG --program=MAIN_DIALOG ;; esac

Войдите или зарегистрируйтесь, чтобы ответить.