The biggest hurdle for a gtkdialog newbe, or at least so it was for me, was getting handle on how to structure the code, where to find documentation and how to use it, where to find examples and how to add comments to the code or comment out blocks of code without braking scripts.
In this article I go over these topics in some detail. It seems necessary to consider the basics before launching into more ambitious topics.
This is the next article in a series of articles on gtkdialog, “gtkdialog Exploration – articles and examples”, which can be found at https://blogs.czapski.id.au/2017/04/gtkdialog-exploration.
Creadits:
Gtkdialog – A small utility for fast and easy GUI building.
2003-2007 László Pere <pipas@linux.pte.hu>
2011-2012 Thunor thunorsif@hotmail.com
Project site: https://code.google.com/archive/p/gtkdialog/
Original documentation: http://linux.pte.hu/~pipas/gtkdialog/
Most recent documentation (not very recent) http://xpt.sourceforge.net/techdocs/language/gtkdialog/gtkde03-GtkdialogUserManual/.
The project home page contains links to other resources which are worth looking at.
Pre-Requisites
This article assumes that the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image is available but it is expected that pretty much any Linux environment will do just as well so long as it supports yad and gtkdialog.
For convenience I posted the export of the VirtualBox image which would have been built if the reader followed all the articles in the series “Build a Linux-based Infrastructure Solution Demonstration Series” to date, that is to the 8th of March 2017. The link to the main article is https://blogs.czapski.id.au/2017/04/virtualbox-image-with-content-as-built-so-far.
gtkdialog application structure and basic interaction with the environment
A gtkdialog application UI is, in effect, a window with content. Perhaps the simplest reasonable gtkdialog application with gtkdialog GUI definition is shown below:
touch /tmp/ex01.sh chmod ug+x /tmp/ex01.sh cat <<-'EOSCRIPT' > /tmp/ex01.sh #!/bin/bash MAIN_DIALOG_FILE=/tmp/ex01.gtkd cat <<-'EOUIDFEINITION' > ${MAIN_DIALOG_FILE} <window> <vbox> <text> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/ex01.sh
This application’s UI looks like this:
Note that the standard window controls, close, maximise, minimise and window menu are provided, as is the title bar with some title even though we specified neither in the UI definition.
The application has a text box with literal text we provided and a button with the label we provided. Clicking the button will cause the UI to exit with the following text emitted to stdout.
EXIT="OK"
The gtkdialog application consists of a GUI definition, expressed as gtkdialog-specific XML structure, provided to a gtkdialog executable as a file or as a shell variable.
The GUI definition specifies all the visual components, event handlers, actions, etc.. More on the event handlers, actions and similar in a later article. For now we will keep things simple.
Common GUI definition convention
In a typical gtkdialog example online, and in the examples found under ~/gtkdialog-0.8.3/examples/ you will see the following idiom for defining and using gtkdialog UIs:
touch /tmp/ex02.sh chmod ug+x /tmp/ex02.sh cat <<-'EOSCRIPT' > /tmp/ex02.sh #!/bin/bash MAIN_DIALOG=' <window> <vbox> <text> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> ' export MAIN_DIALOG case ${1} in -d | --dump) echo ${MAIN_DIALOG} ;; *) gtkdialog --center ${MAIN_DIALOG} ;; esac EOSCRIPT /tmp/ex02.sh
Here the GUI definition is explicitly assigned to a shell variable with “hard” quotes surrounding it. I don’t like this idiom and I don’t use this idiom. The reason is that shell quoting becomes quite tricky and error-prone as soon as the GUI definition becomes more complex and GUI components invoke external commands or shell functions with parameters, etc..
Instead, I use the ‘”here document” piped to a file’ idiom, like in the ex01.sh example above. This is the idiom I will continue to use so you will need to “translate” examples I use to examples provided with gtkdialog and seen online, or translate them to my way of doing things, whichever you prefer.
How can gtkdialog application interact with the environment (basic)
It was briefly mentioned in the text following ex01.sh that when the OK button is clicked the GUI is closed and gtkdialog emits to the stdout
EXIT="OK"
If there were other buttons and other variables defined and populated in the GUI their names and values would similarly be emitted to the stdout.
Let’s try the following example to demonstrate this:
touch /tmp/ex03.sh chmod ug+x /tmp/ex03.sh cat <<-'EOSCRIPT' > /tmp/ex03.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-'EOUIDFEINITION' > ${MAIN_DIALOG_FILE} <window> <vbox> <text> <label>I am a window.</label> <variable>vLabelVariable</variable> </text> <button ok></button> <button cancel></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/ex03.sh
When the Cancel button is pressed the following is emitted to the stdout
vLabelVariable="I am a window." EXIT="Cancel"
When the OK button is pressed the following is emitted to the stdout
vLabelVariable="I am a window." EXIT="OK"
A script can intercept the value of the variables, for example the EXIT variable, and alter subsequent processing as required.
Let’s modify the script so that it recognises the value of the EXIT variable.
cat <<-'EOSCRIPT' > /tmp/ex03.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-'EOUIDFEINITION' > ${MAIN_DIALOG_FILE} <window> <vbox> <text> <label>I am a window.</label> <variable>vLabelVariable</variable> </text> <button ok></button> <button cancel></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) RESULTS=$(gtkdialog --center --file=${MAIN_DIALOG_FILE}) ;; esac I=$IFS; IFS="" for STATEMENTS in "${RESULTS}"; do echo 'STATEMENTS:-->>'"${STATEMENTS}"'<<--' eval $STATEMENTS done IFS=$I if [[ "$EXIT" = "OK" ]]; then echo "You clicked OK with vLabelVariable containing '${vLabelVariable}'" else echo "You pressed the Cancel button." fi rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/ex03.sh
Executing this script produces:
STATEMENTS:-->>vLabelVariable="I am a window." EXIT="OK"<<-- You clicked OK with vLabelVariable containing 'I am a window.'
A shell scripter will undoubtedly come up with alternate ways of getting at the variable names and values.
Note that the content of the vLabelVariable is also emitted. This may or may not be useful. It is possible to prevent the variable being emitted by providing the export=”false” attribute when defining the variable in the GUI. The script variant below illustrates this.
cat <<-'EOSCRIPT' > /tmp/ex03.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-'EOUIDFEINITION' > ${MAIN_DIALOG_FILE} <window> <vbox> <text> <label>I am a window.</label> <variable export="false">vLabelVariable</variable> </text> <button ok></button> <button cancel></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) RESULTS=$(gtkdialog --center --file=${MAIN_DIALOG_FILE}) ;; esac I=$IFS; IFS="" for STATEMENTS in "${RESULTS}"; do echo 'STATEMENTS:-->>'"${STATEMENTS}"'<<--' eval $STATEMENTS done IFS=$I if [[ "$EXIT" = "OK" ]]; then echo "You clicked OK with vLabelVariable containing '${vLabelVariable}'" else echo "You pressed the Cancel button." fi rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/ex03.sh
Executing the modified script produces the following:
STATEMENTS:-->>EXIT="OK"<<-- You clicked OK with vLabelVariable containing ''
The variable vLabelVariable was not exported and its value is not available.
I am jumping ahead a bit here by making a reference to a forward topic. The topic of bash functions used as callbacks and action logic will be dealt with later. For now one needs to know that whether to use export=”false” is a reasonably important decision because any variable defined with export=”false” will not be visible in the shell environment of the callback/action functions so will either be inaccessible or will have to be passed as an argument to a callback/action function. I don’t see harm in not specifying export=”false”. Perhaps there is a performance benefit is so doing.
More on the topic of callbacks and actions in a later article.
Explore examples
I confess that without the examples provided with the gtkdialog source distribution and also available online at https://github.com/01micko/gtkdialog/tree/master/examples I would have given up on gtkdialog. The reference documentation is just that – reference – a place to go to look up a specific piece of information knowing that such information can be looked up in the reference.
A newbie needs to understand the broad capabilities, concepts and functionality, and needs some elaboration. This sort of documentation is missing. True, there are a few tutorials but they are hard to find and are pretty limited in the coverage and scope, so examples are the best means of finding out what can be done and how, unless a comprehensive tutorial becomes available.
Until it does, spend time looking at examples to see what the various tags and attributes exist and what they accomplish. For this set of articles I installed examples locally to ~/gtkdialog-0.8.3/examples. There is no index so explore each on its own, or use the indexed and accessible source at the github URL quoted above.
The simplest way is to invoke each example as a shells script, which is what most of them are, and see what is shown, and then look at the script source to see how it does it.
For example:
~/gtkdialog-0.8.3/examples/window/window
Then see what the GUI definition looks like
~/gtkdialog-0.8.3/examples/window/window --dump
<window> <vbox> <frame Description> <text> <label>This is an example window.</label> </text> </frame> <hbox> <button ok></button> <button cancel></button> </hbox> </vbox> </window>
And finally, look at the source:
geany ~/gtkdialog-0.8.3/examples/window/window &
#!/bin/sh GTKDIALOG=gtkdialog MAIN_DIALOG=' <window> <vbox> <frame Description> <text> <label>This is an example window.</label> </text> </frame> <hbox> <button ok></button> <button cancel></button> </hbox> </vbox> </window> ' export MAIN_DIALOG case $1 in -d | --dump) echo "$MAIN_DIALOG" ;; *) $GTKDIALOG --program=MAIN_DIALOG ;; esac
Reference Documentation
Reference documentation is available in a number of places, and is more or less useful, depending on a bunch of factors.
In the demo image it is available at ~/gtkdialog-0.8.3/doc/reference/. Again, there is no index so pick the first HTML document that comes to hand and view it in a web browser. Internal links will allow you to navigate from object to object so this is not much of a drama. An index is available online at http://01micko.com/reference/. So, locally:
firefox ~/gtkdialog-0.8.3/doc/reference/button.html &
For a newbie the first glance at this is somewhat off-putting. Still, note the following:
- At the bottom of the page, and all other pages, is a list of hyperlinks to the various gtkdialog objects so you can navigate form button to text to window and so on
- The definition lists all the valid tags and discusses the various attributes, signals, functions, etc. – more on these topics in subsequent articles
- The tag attributes section lists all attributes specific to this tag, BUT it does not list these attributes which can be applied to the tag but which are inherited from the parent objects in the object hierarchy
- In this case the innocuous sentence “See the GtkButton widget and ancestor class properties.” hints that there may be other properties that can be applied to the button and links to the page which contains more on the topic. Note that this is an external link so an Internet connection will be needed to access it.
- The external source for GtkButton contains, amongst other things, the object hierarchy of which the button object is a child as well as a list of properties defined for that object. The hierarchy is navigable and inherited parent properties can be discovered by following the links.
- Not all defined properties, signals and functions are mapped by, and visible to, gtkdialog or useable from it. For example, the border-width property of the GtkContainer, which is a grandparent of the GtkButton, is useable from the GtkButton but the other two properties are not visible or useable
- One has to exercise one’s mind a bit to translate data types to what can/should be specified as the attribute value for a particular attribute/property, for example one would specify ‘<window border-width=”6″ …’.
As I practice it, gtkdialog is pretty easy to work with to try various things. Exploration of what the various attributes do to a GUI is pretty painless, particularly once one knows how to effectively comment out blocks of gtkdialog GUI definition XML for various experiments.
The following are links to material that I found useful when dealing with specific topics in my work with gtkdialog so far. They are collected here for ease of reference.
gtkdialog Refrences and Examples
- https://github.com/oshazard/gtkdialog/ – gtkdlialog distribution at github
- http://01micko.com/reference/ – Index of reference pages for all gtkdialog objects
- http://www.murga-linux.com/puppy/viewtopic.php?t=69188&start=2 – gtkdialog development discussion – by my light the most useful I found so far
- http://www.murga-linux.com/puppy/viewtopic.php?p=544704#544704 – another gtkdialog development discussion
- https://github.com/01micko/gtkdialog/tree/master/examples – gtkdialog online examples – also distributed in the source package
- https://developer.gnome.org/gtk2/stable/ – Gnome GTK 2 developer documentation in general – what sits under the covers
- https://developer.gnome.org/gtk2/2.24/gtk2-Standard-Enumerations.html#GtkWindowPosition – Various GTK Enumerations
- http://www.orford.org/gtk – fonts, gtkrc files, engines
- https://developer.gnome.org/gtk2/stable/gtk2-Resource-Files.html#gtk2-Resource-Files.description – Specific section on GTK resource files
- http://www.murga-linux.com/puppy/viewtopic.php?t=40418 – gtkdialog markup text editor/wizard
- http://www.murga-linux.com/puppy/viewtopic.php?t=69282 – Index of programs using gtkdialog
Themes and Styles
- https://en.wikibooks.org/wiki/GTK%2B_By_Example/Theming – GTK Theming – to do with applying styles to GTKK applicaiton objects
- http://www.cc.gatech.edu/data_files/public/doc/gtk/tutorial/gtk_tut-19.html – specific discussion of styles
- https://git.enlightenment.org/themes/detourious.git/plain/gtk/detourious/gtk-2.0/gtkrc – a huge set of property specs
- https://wiki.gnome.org/Attic/GnomeArt/Tutorials/GtkThemes – tutorial on all manner of GTK appearance including styles
- https://wiki.gnome.org/Attic/GnomeArt/Tutorials/GtkEngines/MistEngine – Mist GTK theme engine
- https://wiki.gnome.org/Attic/GnomeArt/Tutorials/GtkEngines/PixmapEngine – Pixmap GTK theme engine
- https://wiki.gnome.org/Attic/GnomeArt/Tutorials/GtkThemes#Priority – Priority of style merging
- https://wiki.gnome.org/Attic/GnomeArt/Tutorials/GtkThemes/SymbolicColors – Discussion on colours
- https://www.cs.tut.fi/lintula/manual/gtk/gtk/gtk-resource-files.html – Discussion in “Pathnames and patterns”
Object Hierarchy – Window
- https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy – GtkWindow Object hierarchy
- https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.properties – GtkWindow Object Properties
Commenting out blocks of XML
One of the reasons I use ‘”here documents” piped to a file’ for persisting gtkdialog GUI definitions is because I can easily comment out blocks of XML without breaking gtkdialog at runtime.
Let’s consider what a person familiar with XML would try first:
touch /tmp/ex04.sh chmod ug+x /tmp/ex04.sh cat <<-'EOSCRIPT' > /tmp/ex04.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-'EOUIDFEINITION' > ${MAIN_DIALOG_FILE} <window> <vbox> <!-- <text> <label>I am a window.</label> </text> --> <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/ex04.sh
Executing this script produces the following:
** ERROR **: gtkdialog: Error in line 4, near token 'string': syntax error aborting... /tmp/ex04.sh: line 18: 5569 Aborted (core dumped) gtkdialog --center --file=${MAIN_DIALOG_FILE}
Opps – no banana. Not only that, but the message is pretty cryptic, the line number reference is to a line number in XML GUI definition and the error may not actually be in the line being referenced. With large GUI definitions debugging could be a headache.
One way to try to zoom in on the line number in the XML is to do the following, bearing in mind that the line number in the error message may not be the line number where the error is caused, and that some breakages prevent XML being generated so this may not work at all:
/tmp/ex04.sh --dump | cat -n | more 1 <window> 2 <vbox> 3 <!-- 4 <text> 5 <label>I am a window.</label> 6 </text> 7 --> 8 <button ok></button> 9 </vbox> 10 </window>
Note, too, that the script’s error line number is useless – it is the number of the line where gtkdialog command is invoked. This will be particularly useless when we start working with bash functions and errors will be reported with respect to the line numbers inside the functions. But I am getting ahead of myself.
Clearly, standard XML <!– commented out –> syntax does not work.
Let’s try a combination of shell techniques to do the job. Consider this script:
scriptName=ex05 touch /tmp/${scriptName}.sh chmod ug+x /tmp/${scriptName}.sh cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE} <window> <vbox> $(:<<-'COMMENT--------------------' <text> <label>I am a window.</label> </text> COMMENT-------------------- ) <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/${scriptName}.sh --dump
This produces the following:
<window> <vbox> <button ok></button> </vbox> </window>
Notice that the entire section of XML between and including <text>…</text> tags has gone missing.
Let’s analyse what is happening.
- Inner “Here document” syntax “
cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE}
” is different from the outer “Here document” syntax “cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh
“. Note the hard quotes around the here document delimiter ‘EOSCRIPT’. Quoting the document delimiter prevents bash from expanding commands and shell variables at the time the document is created. Let’s see what the document looks like after it is created:cat /tmp/${scriptName}.sh
#!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE} <window> <vbox> $(:<<-'COMMENT--------------------' <text> <label>I am a window.</label> </text> COMMENT-------------------- ) <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} |
Note that the variables which would be expanded if the here document delimiter was not hard quoted are not expanded.
- At runtime, when this script is executed, the inner “here document” will be created. This time the here document delimiter is not quoted so commands and variables will be expanded by the shell, resulting in the $() construct being executed. This construct is a “execute in a subshell” construct, causing bash to create a subshell and execute whatever is inside $() as a stream of commands right there and then, when the here document is being created, so that whatever output is produced by the subshell, if any, will get incorporated into the here document in its place.
See, for example, http://unix.stackexchange.com/questions/147420/what-is-in-a-command for a discussion - The command ‘:’ is a no-operation, or a null command for bash so there is no command to execute. Everything following ‘:’ will be ignored except for variable substitution and interpretation of shell-special characters. See http://stackoverflow.com/questions/3224878/what-is-the-purpose-of-the-colon-gnu-bash-builtin for a discussion.
- “
<<-'COMMENT--------------------'
” and everything following it until “COMMENT--------------------
” is a “here document” which is ignored since ‘:’ causes it to be ignored. Hard-quoting the delimiter “COMMENT--------------------
” prevents any $xxxx present in the text form being expanded by the shell and any shell-special characters, like <>|{}, etc. from being interpreted, causing errors
In essence the entire $(….) disappears when the script executes and does not get embedded in the xml document which gtkdialog executes. Great way to comment out large chunks of XML when exploring with alternatives.
Short comments inside gtkdialog XML
Two other techniques can be used to provide comments inside the gtkdialog GUI XML.
I am again running ahead a bit but this is in a good cause 🙂 Each object in gtkdialog except “frame” can be decorated with a bunch of object-specific attributes. Gtkdialog parser is very forgiving of attribute names which it does not recognise so a sneaky way takes advantage of that fact is making it possible to invent a tag name and have its value contain some comment text. Consider the following script:
scriptName=ex06 touch /tmp/${scriptName}.sh chmod ug+x /tmp/${scriptName}.sh cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE} <window xx-window-comment="this is a comment on the window tag"> <vbox> <text xx-text-comment="I am using an unrecognised attribute to provide a comment"> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/${scriptName}.sh
The script happily executed because unknown attributes were ignored yet the comment text is in the XML as can be readily seen:
/tmp/${scriptName}.sh --dump
<window xx-window-comment="this is a comment on the window tag"> <vbox> <text xx-text-comment="I am using an unrecognised attribute to provide a comment"> <label>I am a window.</label> </text> <button ok></button> </vbox> </window>
Note that if a future version of gtkdialog tightens up parsing and rejects unknown attribute names then scripts which use this technique will break.
The second method is a variation on the $(:…) technique, discussed above.
Consider the following script
scriptName=ex07 touch /tmp/${scriptName}.sh chmod ug+x /tmp/${scriptName}.sh cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE} <window> <vbox> $(: this is a single line comment - to continue it over multiple lines \ one must provide line continuation to shell, \, and carry on. \ The $() construct must be closed with the ) <text> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/${scriptName}.sh
Again, everything inside $() disappeared.
/tmp/${scriptName}.sh --dump <window> <vbox> <text> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> |
Note that everything inside $() is expanded by the shell and special characters are acted upon. Including < >, for example, will cause breakage – try it. Consider the following script
scriptName=ex08 touch /tmp/${scriptName}.sh chmod ug+x /tmp/${scriptName}.sh cat <<-'EOSCRIPT' > /tmp/${scriptName}.sh #!/bin/bash MAIN_DIALOG_FILE=${0}.gtkd cat <<-EOUIDFEINITION > ${MAIN_DIALOG_FILE} <window> <vbox> $(: this is a single line comment - to continue it over multiple lines \ one must provide line continuation to shell, \, and carry on. \ The $() construct < > must be closed with the ) <text> <label>I am a window.</label> </text> <button ok></button> </vbox> </window> EOUIDFEINITION case ${1} in -d | --dump) cat ${MAIN_DIALOG_FILE} ;; *) gtkdialog --center --file=${MAIN_DIALOG_FILE} ;; esac rm -f ${MAIN_DIALOG_FILE} EOSCRIPT /tmp/${scriptName}.sh
/tmp/ex08.sh: command substitution: line 6: syntax error near unexpected token `>' /tmp/ex08.sh: command substitution: line 6: `: this is a single line comment - to continue it over multiple lines one must provide line continuation to shell, \, and carry on. The $() construct < > must be closed with the )' ** ERROR **: Error opening file '/tmp/ex08.sh.gtkd': No such file or directory aborting... /tmp/ex08.sh: line 19: 6225 Aborted (core dumped) gtkdialog --center --file=${MAIN_DIALOG_FILE} |
If you use these kinds of comments watch out for shell-special characters. Clearly this kind of comments is not suitable for commenting out chunks of XML. While one can use these kinds comments it seems to me safer to use undefined attributes for short comments and $(:<<-‘….’…) comments for large comments and for commenting out blocks of XML in the gtkdialog GUI definitions.
gtkdialog – Exploring the Window object attributes and actions by example
In this article I explore the gtkdialog Window object, its attributes and actions. In passing. other gtkdialog objects will be used without much elaboration, that elaboration intended to follow in subsequent articles.
This is the next article in a series of articles on gtkdialog, “gtkdialog Exploration – articles and examples”, which can be found at https://blogs.czapski.id.au/2017/04/gtkdialog-exploration.
It appears that gtkdialog, based as it seems to be on the GTK object model, leverages the GTK object hierarchy. Consider the reference for the Window object at http://01micko.com/reference/window.html.
The very first link points to a GtkWindow – http://developer.gnome.org/gtk2/2.24/GtkWindow.html.
In the GTK object hierarchy, https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy, the Window object is several levels below the GObject, the topmost object.
As briefly discussed in the previous article the GtkWindow, and consequently the gtkdialog Window, object inherit, as I understand it, from the objects higher up in the hierarchy. This will come into play when we explore attributes that can be set for a Window, and actions that can be configured for a Window.
Pre-Requisites
This article assumes that the Virtual Box Machine Image created in accordance with the instructions in the blog article to be found at https://blogs.czapski.id.au/2016/10/configure-virtual-box-virtual-machine-and-install-centos-6-8-base-image is available but it is expected that pretty much any Linux environment will do just as well so long as it supports yad and gtkdialog. For convenience I posted the export of the VirtualBox image which would have been built if the reader followed all the articles in the series “Build a Linux-based Infrastructure Solution Demonstration Series” to date, that is to the 8th of March 2017. The link to the main article is https://blogs.czapski.id.au/2017/04/virtualbox-image-with-content-as-built-so-far.
It also assumes that yad and gtkdialog are installed, as discussed in the article “Install yad and gtkdialog” (https://blogs.czapski.id.au/2017/04/gtkdialog-for-rapid-prototyping-of-linux-applications-install-gtkialog-and-yad)
Window Object Attributes
The gtkdialog Window object is the outermost visible object in the hierarchy of gtkdialog objects.
We explored the window object to an extent in the previous article, while setting the context and discussing comments and similar matters. Let’s now explore the Window object attributes more.
Reference documentation for the gtkdialog Window object, http://01micko.com/reference/window.html, provides a table of attributes specific to this gtkdialog object and makes a reference to ancestor class properties.
Attributes that can be configured for the window widget are defined in the widget’s reference page see https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.object-hierarchy, section Properties – https://developer.gnome.org/gtk2/2.24/GtkWindow.html#GtkWindow.properties
Some of them are useful and some of them are not, as far as I am concerned or can empirically determine. Changing values of some of them do not have visible consequences.
Not all attributes/properties are recognised and acted upon by gtkdialog. Some of the properties are inherited from the parent objects, like GtkContainer and GtkWidget. For example, border-width, which defines the amount of space between the window frame and the window content, is inherited from the GtkContainer.
Similarly, sensitive property is inherited from the GtkWidget and when set to true effectively disables everything inside the window, except for the window decorations like minimise, maximise and close. An “interesting” side effect of this is that setting sensitive to false and decorated to false will take away the means of closing the window except by killing the process which created the window 🙂
Properties like window-position take one of the pre-defined enumeration values.
For window-position see https://developer.gnome.org/gtk2/2.24/gtk2-Standard-Enumerations.html#GtkWindowPosition or http://gtk.php.net/manual/en/html/gtk/gtk.enum.windowposition.html (which is not directly related to gtkdialog as I use it but seems a good enough source of enumerations which GTK defines and supports.
By the way, tooltip-markup causes warnings to be emitted to the console, which, apart from being ugly, appear benign.
See the reference page: file:///home/demo/gtkdialog-0.8.3/doc/reference/window.html
To work out what attributes are actually supported, in this case by the window widget, we need to do some exploration. Discussion below goes into this to an extent and I provided most of the useful attributes that can be set, both from GtkWindow itself and inherited from GtkContainer and GtkWidget.
Let me reproduce the table and expand it to include inherited attributes which empirical observation leads me to believe have a visual impact on the window object.
The table below summarised Window attributes/properties and indicates which work with the gtkdialog and which do not as far as I can tell. “Do not” may well be a function of me not seeing any visible difference with the property set to different values. Some ancestor attributes/properties which are not really useable from gtkdialog are omitted.
I could not figure out what this does for a Window object.
I am not quite sure what this does for a Window object. See reference for where this comes from. Perhaps you will get it. http://www.murga-linux.com/puppy/viewtopic.php?p=544704#544704
If a file is specified as the value of the window’s <input file>xxxx</input> directive, and this property is set to true, and the content of the file changes then the signal of type “file-changed” will be emitted. If an <action signal=”file-changed”>xxx</action> or its variant is defined then the action will be executed.
If a file is specified as the value of the window’s <input file>xxxx</input> directive, and this property is set to true, and the content of the file changes then the window’s title bar text will automatically display the content of the file (or some reasonable leading part of it). If this property is false then the input file change will not be reflected in the title bar.
The value of this attribute overrides the height-request value if one is specified.
The value of this attribute overrides the width-request value if one is specified.
GTK_WIN_POS_NONE=0
GTK_WIN_POS_CENTER=1
GTK_WIN_POS_MOUSE=2
This does not seem to have any effect when applied to a Window object
This does not seem to have any effect when applied to a Window object
This does not seem to have any effect when applied to a Window object
This does not seem to have any effect when applied to a Window object
Disables tooltip display if tooltip is defined for the Window
Has not effect of default-height is specified.
Does not seem to have any effect when applied to the Window object
Nothing visible happens when this attribute is provided with a value.
I don’t know what that is supposed to accomplish. Nothing visible happens regardless of the property value.
FALSE disables all components contained in the window.
Simple markup can be used to call out parts of tooltip text in.
See http://www.murga-linux.com/puppy/viewtopic.php?t=40418 for a markup explorer tool.
Ineffective if tooltip-disabled is TRUE.
Ineffective if tooltip-disabled is TRUE.
It is somewhat self-defeating to make a window invisible on creation unless it is a “subsidiary” window and can be made visible form some other piece of logic.
Has not effect if default-width is specified.
The following example includes just about every attribute that can be defined for a Window object. Experiment with the various settings to see what you can see.
See https://github.com/GNOME/gtk/blob/master/gdk/gdktypes.h for enumerations.
Window Object Directives
Note that the window defines a bunch of window specific child objects, which the reference calls directives – label, variable, input, etc.. These must be specified after all the other window child objects else gtkdialog will throw a hissy fit.
The label directive provides window title if title attribute is not set. If it is set the label directive is ignored. Consider:
Consider a variant where the title attribute to the Window object is not provided.
The sensitive directive does the same thing as the sensitive attribute to the window tag – enables or disables window content. Consider:
The variable directive names the variable which can be used elsewhere to reference the window and act upon it, for example disable or enable, activate or deactivate, show or hide, refresh or clear, or set title. The example below provides a variable name vWindow to allow the button’s action directive to trigger the refresh action on the window. When the refresh action signal is processed the function fnEchoDateTime will be executed and its output will be provided to the Window object which will use it to set the window title. Consider the following example. Click the Refresh button a few times with at least 1 second between clicks and see what happens to the window title.
The input directive can invoke logic which can return a string to which the window title will be set when triggered by refresh of the variable named as the window variable. See example above. This function, as all such functions invoked by the gtkdialog, is expected to write to the stdout whatever text is supposed to be the input to the object – in this case the window title.
The output file directive will cause the “value” of this object to be written to the named file if the save action is triggered. In the case of the window object the title will be written to the file. Consider:
The action directive provides a mechanism for invoking logic when certain kinds of events affecting the window object occur. The example above used the ‘
<action function="save">…</action>
‘ markup to add an action to a button object, to be invoked when the button is pressed. Another example would be invoking the close window logic when ESC key is pressed. In the example above, the key-press-event signal is intercepted in the action directive and if the raw key code was (0x9), the Escape key, the gtkdialog calls the exit logic and the window is closed.Exploring the action directive
Let’s consider the following signals, defined in the Window object reference:
In ex13, above, we used the “action function” and “action signal”, to save the window title to a file and to exit the application respectively. Note that the reference does not include the “action function” variant but it is supported and works, as the example illustrates.
Explore the reference for the Window object, http://01micko.com/reference/window.html, to see the signals and the functions defined in that document.
The “action condition” construct is perhaps worth exploring as it is explained what the “_is_true”/
_is_false” is supposed to return. To cut to the chase, the command or the function is supposed to return the literal text “true” or “false”. The example below extends the example above by making the save action conditional on the file not already existing. This is contrived but makes the point.
Consider:
Exploring “action signal” directive
Let’s explore the “action signal” directive to see what sort of signals the Window object receives.
From the reference:
From examples, additional events:
Consider the following example, which is based on the /home/demo/gtkdialog-0.8.3/examples/miscellaneous/signals example.
Each if the events gives rise to an opportunity to hook in logic to be executed when the event is triggered.
In examples ex15, the following stanza illustrates the handling of the key-press-event in such a way that the exit function is called conditionally if the key which was pressed was the Escape key (0x9).
<action signal="key-press-event" condition="command_is_true( [[ \$KEY_RAW = 0x9 ]] && echo true )">EXIT:exit</action>
Exploring “action function” directive
From the reference (http://01micko.com/reference/window.html):
The following functions can be performed upon this widget by any widget capable of emitting signals:
We used the “save” function in example ex15. Now we will consider disable, enable, hide and show functions.
Let’s consider the following example:
In the script above we are not hiding/showing and enabling/disabling the window, as we might, because as soon as we hide the window it will disappear and as soon as we disable it we will not be able to do anything to it except close it using the close “button” in the title bar. We are, instead, jumping ahead a bit, hiding and showing the text object and enabling and disabling the text object. This example also demonstrates how a “toggle” button can be implemented, in this case by alternately hiding and showing two different buttons (hide and show, disable/enable). The end-user impression will be that a single button changes the label and the button function on click (hide/how, disable/enable).
To see how to hide/show and disable/enable the window object consider the following, not particularly useful in practice, example:
In the script above we are jumping ahead a bit and using timers to trigger events that will show the hidden window and enable the disabled content after an interval.
Perhaps provision of a bit of context is in order at this point for no other reason than to make the basic action processing explicit.
Consider the two actions defined for the Hide button.
<action function="hide" condition="visible_is_true(vWindow)">vWindow</action>
<action function="enable" condition="sensitive_is_false(tmr0)">tmr0</action>
The first action will hide the window. The condition “
visible_is_true(vWindow)
” is superfluous in this case because the button will only be visible if the window is visible but it is there as an example of a conditional action.The second action will enable a timer which will trigger its own action to reverse the effect of the button press on the Window object after an interval of up to 5 seconds.
Unless told otherwise, of which in a later article, the button press will cause the two actions to be executed one after the other. There are some circumstances in which execution of an action in the action list will prevent actions defined after it being executed but these are rare circumstances, which will be discussed in a subsequent article. One can have several actions which a button press will trigger. Other active objects can have actions as well, as can be seen with the timer objects and will be also seen in subsequent articles in which other objects are discussed and used.
For the time being one can assume that all actions defined for an object, like a window or a button, will get evaluated sequentially and will be executed if appropriate (like for example if the condition is met).
The style attribute does nothing visible. It is quite likely that I don’t know how to define a style. There is an alternative way to “style” objects which works in some instances and can be used as appropriate.
Consider the following example:
Here we define and use GTK styles to change foreground and/or background colours of the various objects.
Here is how the application window looks.
This is just a brief teaser. How to apply styles to objects, what works and what does not, etc., may be covered in a future article.
Exploring Window examples
In /home/demo/gtkdialog-0.8.3/examples/window there are 3 examples. Review the window GUI definitions and run the examples