Author Topic: Creating custom gui dialogs for shell / bash scripts  (Read 20866 times)

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Creating custom gui dialogs for shell / bash scripts
« on: June 26, 2009, 11:56:57 AM »
This is probably a better topic for the hackmy scripting section, but I'm going to post it here first!

I typically use zenity for GUI dialogs with my bash scripts, but some times it just doesn't do what I want it to do (..a good tutorial on zenity can be found here).  Because of the limited nature of zenity dialogs, I've been trying to figure out how to use gtkDialog / Glade with bash scripts.  There does not seem to be much good documentation of this, but after a bit of trial and error, I have a simple working example to share!

To do this from a standard shell/bash script we need a minimum of two files.. the main script, and a functions file that contains all bash function called by user actions in the dialog (ie. a button press);  To use less than these two files, you must call gtkdialog and not bash or shell as the script type  on the first line of the script. ...see edit below

Here is my working example..  create all files in the same working directory, make the shell script executable, then start it from Konsole:

Code: (test.sh) [Select]
#! /bin/bash

##########################################################################
##########################################################################
##########################################################################
function mk_yesno(){
#USAGE: mk_yesno $"Question text?" "yes-button-icon" "yes-button-function" "no-button-icon" "no-button-function"
export MAIN_DIALOG='
<window title=" - Update-Notifier - " resizable="false" icon-name="computer">
<vbox>
<text use-markup="true" width-chars="40">
<label>"'`echo $1`'"</label>
</text>
<hbox>
<button>
<label>"'`gettext " No "`'"</label>
<input file icon="'`echo $4`'"></input>
<action>'`echo $5`'</action>
<action type="exit">no button clicked</action>
</button>
<button>
<label>"'`gettext " Yes "`'"</label>
<input file icon="'`echo $2`'"></input>
<action>'`echo $3`'</action>
<action type="exit">yes button clicked</action>
</button>
</hbox>
</vbox>
</window>
'
}




# If using glade to create gtk dialogs, call gtkdialog as follows:
## gtkdialog --center --glade-xml=test.glade --program=yes_no --include=test.functions
# Note that --program=<dialog-id> calls the dialog ID as identified in the glade file.
# ..because a glade file can have multiple dialogs defined


mk_yesno $"Would you like update-notifier to give pop-up status notifications?" "help-faq" 'print_this "yes button clicked"' "stop" 'print_this "no button clicked"'
gtkdialog --center --include=test.functions --program=MAIN_DIALOG

mk_yesno $"Would you like to talk about linux?" "irc_section" 'print_this "yes button clicked"' "gtk-quit" 'print_this "no button clicked"'
gtkdialog --center --include=test.functions --program=MAIN_DIALOG


##########################################################################
##########################################################################
##########################################################################

sleep 2
exit


..note that use of the mk_yesno function is not required, the MAIN_DIALOG could be defined independently, but the way I did it allows it to be reused with different text, icons, and functions!  ;D


Code: (test.functions) [Select]
#! /bin/bash
function print_this() {
  echo "print_this function says: $1"
}


..anybody want a gui interface like these for their bash scripts?
 ;D :o 8)



EDIT:
Here is a method of using gtkdialog with bash that does not require the use of a .functions file..  instead the stdout of the gtkdialog is captured and evaluated to bash variables:

Code: [Select]
#! /bin/bash
##! /usr/bin/gtkdialog -e

##########################################################################
##########################################################################
##########################################################################

function mk_yesno(){
#USAGE: mk_yesno $"Question text?" "yes-button-icon" "no-button-icon"
export MAIN_DIALOG='
<window title=" - Update-Notifier - " resizable="false" icon-name="computer">
<vbox>
<text use-markup="true" width-chars="40">
<label>"'`echo $1`'"</label>
</text>
<hbox>
<button>
<label>"'`gettext " No "`'"</label>
<input file icon="'`echo $3`'"></input>
<action type="exit">no button clicked</action>
</button>
<button>
<label>"'`gettext " Yes "`'"</label>
<input file icon="'`echo $2`'"></input>
<action type="exit">yes button clicked</action>
</button>
</hbox>
</vbox>
</window>
'
}


function parse_dialog_stdout() {
I=$IFS; IFS=""
for STATEMENT in  $(gtkdialog --center --program=MAIN_DIALOG); do
eval $STATEMENT
done
IFS=$I
}


mk_yesno $"Would you like to talk about linux?" "irc_section" "gtk-quit"
parse_dialog_stdout

if [ "$EXIT" ]; then  echo -e "\n\nExit action: $EXIT\n"; fi


mk_yesno $"Would you like update-notifier to give pop-up status notifications?" "help-faq" "stop"
parse_dialog_stdout

if [ "$EXIT" ]; then  echo -e "\n\nExit action: $EXIT\n"; fi

##########################################################################
##########################################################################
##########################################################################

sleep 1
exit



Resources:
http://forum.goblinx.com.br/viewtopic.php?p=3436  ..a great introduction!
http://www.murga-linux.com/puppy/viewtopic.php?t=38608
http://www.murga-linux.com/puppy/viewtopic.php?t=40418

GTKDialog Examples:
http://xpt.sourceforge.net/techdocs/language/gtkdialog/gtkde02-GtkdialogExamples/

GTKDialog Manual:
http://xpt.sourceforge.net/techdocs/language/gtkdialog/gtkde03-GtkdialogUserManual/

Glade tutorials:
http://www.kplug.org/glade_tutorial/glade1_tutorial/gladekplugtut.html ..I also have a pdf tutorial that is too big to post  :-[


..and one more great tutorial to add, from our very own PCLinuxOS magazine (by musonio):
http://pclosmag.com/html/Issues/200910/page21.html
« Last Edit: September 02, 2010, 02:13:52 PM by travisn000 »

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Advanced gtk dialog: more examples
« Reply #1 on: June 28, 2009, 03:44:22 PM »
I will post the code for the update notifier settings dialog and user input processing here when it is completed..

EDIT:  Here it is..

Code: [Select]
#! /bin/bash



export MAIN_DIALOG='
<window title=" - Update-Notifier Settings - " resizable="false" icon-name="package_settings">
<vbox spacing="25">
<frame '`gettext $" Notifications "`'>
<checkbox>
<label>"'`gettext $"Enable pop-up notifications"`'"</label>
<variable>POP_UPS</variable>
</checkbox>
</frame>
<frame '`gettext $" Apt-get Settings "`'>
<checkbox>
<label>"'`gettext $"Disable apt-get verification prompt  (..use apt-get -y) "`'"</label>
<variable>APT_FORCE_YES</variable>
</checkbox>
</frame>
<frame '`gettext $" Frequency of Update Checks "`'>
<hbox>
<pixmap>
<input file>/usr/share/icons/crystalsvg/48x48/apps/help_index.png</input>
</pixmap>
<text use-markup="true">
<label>"'`gettext $"<b>Note:</b>  Time interval is calculated as a sum of days and hours.

If you want update checks on an hourly basis, select zero (0) days. If you only want update checks to run when manually initiated set both hours and days to zero (0). "`'"</label>
</text>
</hbox>
<hbox>
<text>
<label>"'`gettext $"Days: "`'"</label>
</text>
<combobox>
<variable>CHK_DAYS</variable>
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>15</item>
<item>30</item>
</combobox>
</hbox>
<hbox>
<text>
<label>"'`gettext $"Hours: "`'"</label>
</text>
<combobox>
<variable>CHK_HOURS</variable>
<item>0</item>
<item>4</item>
<item>6</item>
<item>8</item>
<item>12</item>
<item>15</item>
<item>18</item>
</combobox>
</hbox>
</frame>
<hbox start="true">
<button>
<label>"'`gettext $" Save "`'"</label>
<input file icon="document-save"></input>
<action type="exit">save</action>
</button>
<button>
<label>"'`gettext $" Cancel "`'"</label>
<input file icon="gtk-delete"></input>
<action type="exit">cancel</action>
</button>
</hbox>
</vbox>
</window>
'
# <hbox fill="true" expand="true">  ..change size of input, text, etc
# <hbox spacing="100" homogeneous="true"> ..change position of buttons, etc
# <combobox case-sensitive="true" value-in-list="true"> ..prevents non-predefined input in combobox

# Values returned by gtkdialog stdout
# POP_UPS="true/false"
# APT_FORCE_YES="true/false"
# CHK_DAYS="0,1,2.."
# CHK_HOURS="0,1,2.."
# EXIT="save/cancel/abort" .."abort" is returned when window is closed

# Eval gtkdialog stdout into bash variables
I=$IFS; IFS=""
for STATEMENT in  $(gtkdialog --center --program=MAIN_DIALOG); do
eval $STATEMENT
done
IFS=$I


CONF_DIR=$HOME/.update-notifier-launcher/SETTINGS
if [ -d $CONF_DIR ];then echo -e $"$CONF_DIR directory found\n\n";
else
if [ ! -d $HOME/.update-notifier-launcher ]; then mkdir $HOME/.update-notifier-launcher; fi
mkdir $CONF_DIR && echo $"Creating directory $CONF_DIR " && if [ -d $CONF_DIR ];then echo $"Done" || echo -e $"$CONF_DIR directory could not be created\n\n"; fi
fi


# Process variables if dialog exit status == save
if [ "$EXIT" == "save" ];then
echo "$POP_UPS" > $CONF_DIR/pop-ups
echo "$APT_FORCE_YES" > $CONF_DIR/apt-force_yes
echo "$CHK_DAYS" > $CONF_DIR/days
echo "$CHK_HOURS" > $CONF_DIR/hours

else
echo "Settings canceled"
fi


[attachment deleted by admin]
« Last Edit: June 29, 2009, 12:48:47 AM by travisn000 »

Offline Neal ManBear

  • Administrator
  • Super Villain
  • *****
  • Posts: 15847
  • LXDE! Coffee, Bacon and Cheesecake!
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #2 on: June 28, 2009, 03:57:45 PM »
Thank you, Travis. :D

Offline gseaman

  • PCLinuxOS Tester
  • Hero Member
  • *******
  • Posts: 3798
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #3 on: June 28, 2009, 05:08:57 PM »
Thanks for the info. I may use it.

Galen

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #4 on: June 28, 2009, 06:43:46 PM »
I hope you both find it useful!

I've added another example to the first post that instead of calling a function from a .functions file upon a button is press, just parses the stdout of gtkdialog to catch the state of the widgets (buttons in this case)..   in the above example that variable is then echo'd to the bash scripts stdout to show that it reads gtkdialog's output.

Next step for me is to create and parse a more complicated GUI..  I'll post the result when its working.  ;D

Offline gseaman

  • PCLinuxOS Tester
  • Hero Member
  • *******
  • Posts: 3798
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #5 on: June 28, 2009, 06:52:22 PM »
This is great. I tried the new code and it worked perfectly.

Galen

Offline Neal ManBear

  • Administrator
  • Super Villain
  • *****
  • Posts: 15847
  • LXDE! Coffee, Bacon and Cheesecake!
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #6 on: June 28, 2009, 08:23:02 PM »
LOL I'm already in over my head. I dove "in at the deep end."
Learn to swim or drown, that's me. LOL

One day I may find an easier way to learn, but will I recognize it? ;D

Offline pupthai

  • Hero Member
  • *****
  • Posts: 1426
  • PCLinuxOS 2011 2 - KDE4
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #7 on: June 28, 2009, 09:00:07 PM »
If you want real basic and simple to use, I have used Kdialog.  In just a few minutes you can be making dialog for scripts.
PCLinuxOS 2011 2 - KDE4
Intel 2 core duo @3.22gig, Asus P5G41/M, DDR2/1066 4gig, ENGT220 DDR3/1gig, 2x Seagate 250gig.

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #8 on: June 28, 2009, 09:54:47 PM »
..just a teaser from my project:  ;D



[attachment deleted by admin]

Offline siamer

  • Sr. Member
  • ****
  • Posts: 284
    • ZEN-mini
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #9 on: June 30, 2009, 04:34:11 AM »
Hello :)

travisn000 zenity is really cool! Maybe not so easy as i was thinking but anyway cool :)

Thanks ;)
Every man dies, but not every man really lives... !!

   

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #10 on: June 30, 2009, 09:13:36 AM »
Zenity is a great tool, but when using it you are limited to a set of pre-defined dialog types.  Most of my scripts in the past have used zenity, or a combination of zenity and kdialog, but for my most recent project (update notifier settings) I wanted to avoid a long string of dialogs..  gtkdialog seemed to be the right tool for the job.

gtkdialog, although more complex at first investigation, is much more flexible..   If you can imagine it you can create it.  If you don't like writing the dialogs using gtkdialog's xml format, you can also create dialogs with Glade (Glade is a graphical gui designer) and load them using gtkdialog.

As a side note, a commonly cited short-comming of zenity when compared to kdialog, is the lack of a yes/no dialog in zenity.  It annoys me that when I ask the user a yes/no question the only reply the user can give with zenity is OK or Cancel..   ..hence the need for the first two examples I posted above; re-usable functions to create a yes/no dialogs that are generally more portable than using kdialog (kdialog won't work on gnome, xfce, lxde, etc, but all PCLinuxOS desktop environments have the GTK basics included and will support zenity / gtkdialog).


Linuxera

  • Guest
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #11 on: June 30, 2009, 08:57:23 PM »
I can't wait for this one to be finished, finished, finished!!!   ::)

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #12 on: June 30, 2009, 10:33:34 PM »
I can't wait for this one to be finished, finished, finished!!!   ::)


If you're up for renaming and copying two files to /usr/bin you are more than welcome to help with testing!

http://www.pclinuxos.com/index.php?option=com_smf&Itemid=58&topic=56896.msg475678#msg475678

 ;D ;D

DrDOS

  • Guest
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #13 on: July 02, 2009, 05:34:28 PM »
This is very good. I was able to get a progress bar operating in jig time in a situation where I wasn't able to to it at all with Xdialog or zenity. Here's how it worked.
Code: [Select]

<input>echo "Starting process one";(process one code here);echo 20;echo "Starting process two";(process two code here);echo "Done";sleep 1;echo 100;</input>

This is assuming that process one takes 20% of the time and process two the rest.  To make the box close just echo 100.

And that's it. Things you need to know, you can't navigate while in the box but you can refer to other directories. Also, everything has to be on one line with the processes separated by semicolons.

This is still not exactly what I'm looking for, or may it is and I just don't know it yet. What I want is something that opens as a separate process that can be updated from time to time and closed when done.

Offline travisN000

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1758
Re: Creating custom gui dialogs for shell / bash scripts
« Reply #14 on: July 03, 2009, 11:31:53 AM »
The way I usually accomplish a zenity progress dialog for multiple processes is to put all the processes into a bash function and then pass the function call to zenity:

Code: [Select]
my_bash_function | zenity --progress --title="$TITLE" --text=$"Doing something.." --pulsate --width=400 --auto-close
..I haven't tried it, but you may be able to echo or return the percentages from the function in place of --pusate