FE 'tkGooie' Utilities

'SYSTEMtools' group

A Meter for
File Systems'
Usage

(drawn
Tachometer Style)

(FE = Freedom Environment)

GUI to show storage
usage of a user-selected
file system (mount)
using a tachometer-style
meter --- drawn using
'create arc' and 'create oval' and
'create line' and 'create text'
on a Tk 'canvas' widget.

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'SYSTEMtools' Menu >

This
'Meter_forFileSystemsUsage_
drawnTachStyle'
Tk-GUI code Page

INTRODUCTION to a Tcl-Tk script for a
"Meter for File Systems' Usage
(drawn Tachometer Style)"

In mid-2013, I put it on my Tk-scripts 'to do' list to implement some practical applications for the nice 'tachometer style' meter for which Marco Maggi provided a demo script at wiki.tcl.tk/9107 back in 2003.

Below is an image of the GUI created by Maggi's demo script.

I have implemented two applications of this tachometer-style meter to:

In the first case, the Tk script was essentially a 'wrapper' for the 'free' command, which is available on my operating system (Ubuntu 9.10, 2009 October, 'Karmic Koala').

In the 2nd case, the Tk script was essentially a 'wrapper' for the 'ifconfig' command.

The code for the memory-and-swap application was 'published' on a Tcler's Wiki (wiki.tcl.tk) page titled 'A Pair of Tachometer-style Meters --- for Memory and Swap'.

The code for the network-activity application was 'published' on a Tcler's Wiki (wiki.tcl.tk) page titled 'A Pair of Tachometer-style Meters --- for Network Activity'.

I had at least two other applications of the 'tachometer style' meter on my 'to-do' list --- including a file-system storage-space-usage monitoring application --- essentially a wrapper for the 'df' command.

That is the subject of this page.

Since the 'df' command is probably available on most Linux, Unix, and BSD systems --- and since the Apple Mac operating system is based on a BSD system, this 'file-system-usage' utility is probably usable (with very little change) on Linux-or-Unix-or-BSD-or-Mac systems.

The 'df -kl' command returns data like the following.



   $ df -kl
   Filesystem           1K-blocks      Used Available Use% Mounted on
   /dev/sda1             74611932  59225272  11596528  84% /
   udev                   1677060       328   1676732   1% /dev
   none                   1677060       264   1676796   1% /dev/shm
   none                   1677060        84   1676976   1% /var/run
   none                   1677060         0   1677060   0% /var/lock
   none                   1677060         0   1677060   0% /lib/init/rw   
   /dev/sdb5             76920384  66102948   6910032  91% /home


In this case, you can see that there are two major file systems (/dev/sd*) on this computer --- 'Mounted on' the root (/) and home (/home) directories.

On this computer, there are two separate 80 Gigabyte disk drives --- one used for the 'root' file system, and one used for the 'home' file system.

However, on many home computers, there is only one major file system --- the 'root' file system.

---

Goals for the GUI

So in designing this GUI, I decided to go with a single meter on the GUI --- rather than 2 meters, like in the 'memory-and-swap' and the 'network-activity' Tk GUI's that I had devised before.

Besides showing a 'percent-usage' meter (on a Tk canvas on the GUI), I wanted to provide a means for the user to query the mount points available on the computer --- and to choose one of the mount points to monitor.

And I wanted to provide a Tk 'scale' widget on the GUI, by which the user can specify, at any time, a new 'sampling rate' --- for getting the usage data via the 'df' command.

(Actually, the 'sampling rate' is a 'wait-time' = 'wave-length', rather than a 'frequency'.)

I was able to implement that ability by use of the Tcl 'after' command, in the form

after   $WAITmillisecs   update_needles

This command is called once to initialize the GUI --- and it is called within the 'update_needles' proc, to continue getting storage-space usage data for a user-specified mount point via the 'df' command.

Since, typically, the '%-used' storage space of a large file system is changing very gradually, a sampling rate larger than a minute or two may suffice for most needs.

So the scale is initialized at a sampling-rate of that magnitude.

I also wanted to supply a 'Refresh' button on the GUI, so that the user can request at ANY TIME, a new query of the usage data for the file system being monitored.

And, in case there is more than one file system that is 'near-full', I wanted to supply a 'Report' button on the GUI, so that the user can see, at any time, the usage of ALL the file systems on the computer.

In putting together the code for this GUI, I drew heavily on the 'shadow-circle' technique of Marco Maggi to make nice looking meters.

And I included a 'red-line' (danger) area on the meter, like he did.

One rather unique thing about this implementation of the meter (something not done by Maggi in his demo) is that the GUI window and the canvas and the meter are resizable.

In other words, I spent quite a bit of effort in converting Maggi's procs

  • FROM using hard-coded numbers for making the meters and their needles

  • TO using variables that work off of queries on the current size of frame and canvas widgets.

So the user is able to resize the window and click on the 'Refresh' button to get a bigger version of the meters and the needle position.

After several iterations, during which I decided on implementing the features described above, I ended up with the GUI seen in the following image.

When the GUI first comes up, the 'Mount-to-monitor' is defaulted to the 'root' file system --- since that file system is defined on all of the target computers of this utility.

Below is an image that shows that one can change the 'Mount-to-monitor' entry field so that a different file system is monitored --- in this case the 'home directories' file system mounted at /home.

The 'ShowMounts' button on the GUI can be used to show the available mount points.

A small window pops up showing a list of mount directories.

---

To enlarge the meter

When the GUI first comes up, the meter (its canvas) is sized at about 200x200 pixels --- and the data shown is based on an initial execution of the 'df' command --- from which data for the 'root' file system is extracted.

You can see the 'SYSTEMtools' tkGooie page titled 'A Pair of Tachometer-style Meters --- for Memory and Swap' to see an example image that demonstrates that the user is able to resize the window and click on the 'Refresh' button to get a bigger version of the meter(s) and the needle position.

---

Anti-aliasing (jaggies)

I had hoped to come up with a technique to avoid the 'aliasing' effect on the needles --- but I did not do it for the 'memory-and-swap' script --- and I have still not done that for the 'network-activity' script and this script.

However, as 'retina display' monitors come into use more and more (with resolutions above about 2000x1500 pixels), even without changing the needle-drawing code in this script, you may find that the 'jaggies' are hard to see.

(I do not have such a monitor yet, so I cannot say for sure.)


CAPTURING THE GENERATED IMAGE:

When you get an image that you want to save --- for example, the images that I posted above to show some GUI features of this utility --- a screen/window capture utility (like 'gnome-screenshot' on Linux) can be used to capture the GUI image in a PNG or GIF file, say.

If necessary, an image editor (like 'mtpaint' on Linux) can be used to crop the window capture image.

The image could also be down-sized --- say to make a smaller image suitable for presentation in an email or on a web page.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'file-system percent-used' display utility.

I follow my usual 'canonical' structure for Tk code for this Tk script:



  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control,
     text-array-for-labels-etc).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in other scripts (code re-use).

I call your attention to step-zero.

One thing that I have started doing in 2013 is using a text-array variable --- named 'aRtext' --- for text in labels, buttons, and other widgets in the GUI.

This can make it easier for people to internationalize my scripts.

I will be using a text-array like this in most of my scripts in the future.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main 'pack' parameters:

  • '-side'
  • '-anchor'
  • '-fill'
  • '-expand'

on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think that I have used a pretty nice choice of the 'pack' parameters.

In particular ...

The label and button widgets stay fixed in size and relative-location if the window is re-sized --- while the canvas area (without scroll bars) expands/contracts whenever the window is re-sized, and the 'Refresh' button is poked.

The meter expands/contracts when the window is re-sized --- but perhaps not always in a way you would desire.

Occasionally, you may need to tug the borders of the window to show the meter in a way that suits you.

You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want.

And you can look into the code that is drawing the meter to see if you can devise meter-resizing behavior that pleases you more.

---

Additional experimentation with the GUI
--- its appearance:

You might want to change the fonts used for the various GUI widgets.

For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'.

Or change font families.

    In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding.

And I have included the '-relief' parameter on the definitions of frames and widgets.

Feel free to experiment with those 'appearance' parameters as well.

If you find the gray 'palette' of the GUI is not to your liking, you can change the value of the RGB parameter supplied to the 'tk_setPalette' command near the top of the code.


Some features in the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

You can look at the top of the PROCS section of the code to see a list of the procs used in this script, along with brief descriptions of how they are called and what they do.

The main procs are as follows.



   'make_tachometers' - to draw one (or more) meters within their Tk (square) canvases.

                        We allow the canvas(es) to resize according to
                        a resizing of the window. This proc will set the
                        SQUARE size of the canvas(es) according to the current
                        size of the frame containing the canvas(es).

   'make_one_tachometer' - called by 'make_tachometers', to make each meter.

                           In this utility, we draw only one meter --- but the
                           procs are structured to facilitate adding another
                           meter, if a Tcl-Tk coder so desired.

   'draw_rivet'          - called by 'make_one_tachometer', 4 times, to put
                           rivets in 4 corners around a meter.

   'draw_circle_shadow'  - called by 'make_one_tachometer' to put a shadowed
                           edge around the circle that makes the meter.
                           Also called to help make a 'pin' in the center of
                           the meter to hold the needle. Also called to make
                           the 4 rivets.

   'update_needles'      - to update the needle(s) on the meter(s).

   'update_one_needle'   - called by 'update_needles', to draw each needle.

   'Refresh'             - called by 'Refresh' button. Runs 'make_tachometers'
                           and 'update_needles'.

   'Report'              - called by 'Report' button.

   'show_mounts'         - called by 'ShowMounts' button.

   'popup_msgVarWithScroll' - called by the 'Help' button, to show text in
                              variable $HELPtext. Also used by the 'Report'
                              and 'show_mounts' procs.


Thanks to Marco Maggi whose 'shadow-circle' drawing technique (and code) made this script much easier to write.


Comments in the Code

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch videos of people (who shouldn't be rapping) rapping.


The Tcl-Tk CODE

Here is a link to CODE for the Tk script

'meters_forFileSystems_usage.tk'.


The shell script (the 'wrapee') :

And here is the code for the shell script called by this Tk script.

This is a wrapper script for the 'df' command.

This script takes a single string-parameter which can be either 'all' or 'mounts' or the name of a mount directory.

You can put this script in the same directory with the Tk script.

The Tk script includes some code (involving the 'argv0' variable) to determine the location of the shell script by extracting the name of the directory in which the Tk script lies.

Here is a link to CODE for the SHELL script

'get_fileSystems_spaceData.sh'.


SIMILAR UTILITIES:

There is at least one more 'meter utility' on my 'to-do' list in the 'METERS' group of the FE 'tkGooies' system.

In particular, I may make a meter utility that shows CPU activity --- allowing for monitoring the activity of ANY of the CPU's on multiple-CPU computers, which are everywhere nowadays.


IN CONCLUSION

As I have said on other code-donation pages on this site ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.

Bottom of this web page for
presenting Tcl-Tk code for
Meters for File Systems' Usage
(drawn Tachometer Style)

--- a utility in the FE 'tkGooies' system,
in the 'SYSTEMtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

The code was created in 2013 --- and posted 2013 Nov 21 at http://wiki.tcl.tk/38944.

This FE web page was created 2014 May 10.
(as a backup and alternative to the wiki.tcl.tk page)

This page was changed 2015 Oct 05.
(Small changes.)

Page was changed 2019 Mar 05.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jul 04.
(Specified image widths in percents to size the images according to width of the browser window. Also added some web links.)


NOTE:
The code here MAY BECOME more 'up-to-date' than the code posted on the Tcler's Wiki ---
wiki.tcl-lang.org --- formerly wiki.tcl.tk.