While I was working on an older Puppy Linux system I came across qtkdialog.
I’m a huge fan of Zenity and Yad for making Bash dialog, but qtkdialog has the advantage in that it allows users to create custom interfaces using an XML-like syntax.
Unfortunately qtkdialog is fairly old, so there isn’t a lot of documentation.
This blog references some of my notes. Some of the key features in qtkdialog include:
- free form layouts
- Custom text fonts, colors and sizing
- Support for frames and tabs
Installation
To install use the following steps:
sudo apt install build-essential
wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/gtkdialog/gtkdialog-0.8.3.tar.gz
tar -zxvf gtkdialog-0.8.3.tar.gz
cd gtkdialog-0.8.3/
./configure
make
sudo make install
If you plan on using a lot of icons, I’d recommend getting an icon browser/viewer. (For this I use yad-icon-browser that is bundled with yad).
A First Example
A first example a dialog with static text and one active button would be:
#!/bin/bash
#
# gtk1.sh - gthdialog example with text and two buttons
#
export MAIN_DIALOG='
<window title="My First Program" icon-name="gtk-about">
<vbox>
<text>
<label>Static Text and one active button</label>
</text>
<button>
<label>Echo the date</label>
<action>echo "$(date)"</action>
</button>
<button ok></button>
</vbox>
</window>
'
# Open the dialog
gtkdialog --program=MAIN_DIALOG --center

For this example (gtk1.sh), a variable, MAIN_DIALOG, is created with all the XML code. This variable is then passed to gtkdialog using the –program option. An alternate approach would be to pass an XML file to the program:
gtkdialog --file=gtk1.xml
Some of the key points in this example are:
- start with <window> and end with </window>
- format the presentation with vertical (vbox) or horizontal (hox) tags (at least 1 is required)
- static labels must be within a <text> </text> block
- buttons can call Bash code using <action> tags
A Diagnostic Example
A more advanced example will use a couple of frames to group together buttons with icons. These buttons will launch a Zenity windows with diagnostic data.

#!/bin/bash
#
# gtk5.sh - create a diagnostic interface
#
GTKDIALOG=gtkdialog
# Pass a custom color file if required
#export GTK2_RC_FILES=gtkrc_mono
export MAIN_DIALOG='
<window
title="Diagnostics"
icon-name="applications-utilities"
name="MyWindowBg" >
<vbox>
<text use-markup="true"><label>"
<span color='"'red'"' font-family='"'Comic'"' weight='"'bold'"' size='"'xx-large'"'>
<i>System Tools</i>
</span>"</label>
</text>
<hbox>
<frame CPU Info>
<hbox>
<button>
<input file icon="view-sort-descending"></input>
<label>TOP - Table Of Processes</label>
<width>30</width>
<action>top -b -n 1 | zenity --text-info --title "TOP"</action>
</button>
</hbox>
<hbox>
<button use-underline="true" tooltip-text="Run VMSTAT Utility">
<input file icon="gnome-dev-memory"></input>
<label>VMSTAT - CPU Stats </label>
<width>55</width>
<action>yad --text="$(sensors)" --title=Sensors</action>
</button>
</hbox>
</frame>
<frame Device Info>
<hbox>
<button>
<input file icon="media-removable-symbolic"></input>
<label>LSUSB - List USB Devices</label>
<width>40</width>
<action>lsusb | zenity --text-info --title "lsusb"</action>
</button>
</hbox>
<hbox>
<button>
<input file icon="harddrive"></input>
<label>LSPCI - List PCI Devices </label>
<width>45</width>
<action>lspci | zenity --text-info --title "lspci"</action>
</button>
</hbox>
</frame>
</hbox>
<button ok></button>
</vbox>
</window>
'
case $1 in
-d | --dump) echo "$MAIN_DIALOG" ;;
*) $GTKDIALOG --program=MAIN_DIALOG --center ;;
esac
Some of the key points in the code are:
- Font color, type and size can be adjusted with the <span> tag. Note: see the Pango Markup Language for details.
- To put icon on button use: <input file icon=xxxx></input>
- Output from Bash commands can be piped to the Zenity dialog tool.
Custom Colors
A color file can be used to define many of the gtkdialog objects. To reference a custom color file:
- Add a name item to the window object (< window name=”MyWindowBg”)
- Create a GTK2_RC_FILES variable and reference the color file ( export GTK2_RC_FILES=gtkrc_mono )
The color file (gtkrc_mono in this example) references the name of the window (MyWindowBg) and any required custom color settings.
style "bgWhite" { bg[NORMAL] = "#FFFFFF" }
style "fgWhite" { fg[NORMAL] = "#FFFFFF" }
style "bgBlack" { bg[NORMAL] = "#000000" }
style "bgRed" { bg[NORMAL] = "#FF0000" }
style "fgRed" { fg[NORMAL] = "#FF0000" }
style "bgGreen" { bg[NORMAL] = "#FFFF00" }
style "fgGreen" { fg[NORMAL] = "#FFFF00" }
style "bgBlue" { bg[NORMAL] = "#0000FF" }
style "fgBlue" { fg[NORMAL] = "#0000FF" }
widget "MyWindowBg" style "bgBlack"
widget "MyWindowBg.GtkVBox.GtkHBox.MyButtonBg" style "bgGreen"
widget "MyWindowBg.GtkVBox.myEVB" style "bgBlue"
widget_class "*<GtkFrame>.GtkLabel" style "fgWhite"
widget_class "*<GtkButton>.*.GtkLabel" style "fgBlue"
For the earlier example if the line : # export GTK2_RC_FILES=gtkrc_mono is changed to:
# Pass a custom color file if required
export GTK2_RC_FILES=gtkrc_mono
The dialog will be changed to a black background with white frames and blue button text:

Summary
Understanding gtkdialog is a useful exercise, especially if you’re working on older system.
Manually creating gtkdialog layouts can quickly become painful. Tools like Glade offer a visual interface for creating complex graphic interfaces.
There are some Python libraries that support gtk graphic interfaces.
I’ll probably stick using basic Zenity or Yad for my Bash GUIs, or Python for more complex projects.