FE 'tkGooie' Utilities

'SYSTEMtools' group

Meters for
Memory-and-Swap
Usage

(drawn Tachometer Style)

(FE = Freedom Environment)

GUI to show memory
and swap usage ---
using tachometer-style
meters --- drawn using
'create arc' and
'create oval' and
'create line' and
'create text' on 2
Tk 'canvas' widgets.

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'SYSTEMtools' Page >

This
'Meters_forMemoryAndSwap_drawnTachStyle'
tkGooie Page

INTRODUCTION to a Tcl-Tk script for
'Meters for Memory-and-Swap Usage
(drawn Tachometer Style)'

Around 2013 July, I put it on my '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.

One of the first applications of the meter that I had in mind was to show memory and swap used on my computer at any time --- by using a Tk script as a 'wrapper' for the 'free' command, which is available on my operating system (Ubuntu 9.10, 2009 October, 'Karmic Koala').

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

Besides showing two 'tachometer style' meters, side by side, on two Tk 'canvas' widgets --- I originally wanted to provide a 'scale' widget on the GUI, by which the user could specify at any time a new 'sampling rate' (actually, a 'wait-time' = 'wave-length', rather than a 'frequency').

But I found that there were technical problems with using the wait-time.

Namely, in my attempt at implementation, the GUI became essentially non-interactive during the wait time.

    (Problem was resolved in an UPDATE below.)

So, for now, I have supplied a 'Refresh' button on the GUI, so that the user can request at ANY TIME, a new set of memory and swap values to be displayed on the GUI. ('Manual' update instead of 'auto' update.)

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 meters, like Maggi did.

After several iterations (including restructuring the procs a few times and revising the widgets available on the GUI), I ended up with the GUI seen in the following image.

When the GUI first comes up, the two meters (their canvases) are sized at 200x200 pixels --- and the data shown is based on an initial execution of the 'free' command.

One rather unique thing about this implementation of the meters (something not done by Maggi in his demo) is that the window and the canvases and the meters 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 --- as you can see in the following image.

I had hoped to come up with a technique to avoid the 'aliasing' effect on the needles --- but you can see in this image that, for certain angles of the needles, there is a pronounced 'stair-step' effect.

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 --- say, to report a memory-leak problem for some software --- 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.


A LITTLE MEMORY EXPERIMENT:

To get the memory figures to change, I tried bringing up an instance of the Seamonkey web browser on my computer and then clicking on the 'Refresh' button of the Tk GUI.

I found that for each new instance of Seamonkey that I started (I started about seven), the memory usage went up about 2 to 10 Megabytes.

At that level of memory consumption, the percent-needle hardly moved, because, when about 3 Gigabytes (= 3000 megabytes) of memory are installed, 10/3000 is less than one-half of one percent.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'memory-and-swap in tachometers' 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 new thing that I have started doing recently 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 for this GUI.

In particular ...

The label and button widgets stay fixed in size and relative-location if the window is re-sized --- while the two canvas areas (without scroll bars) expand/contract whenever the window is re-sized, and the 'Refresh' button is clicked.

The meters expand/contract when the window is re-sized --- but probably not always in a way you would expect.

Occasionally, you may need to tug the borders of the window to center the meters 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.

You can look into the code that is drawing the meters 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.


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 2 meters within their 2 Tk (square) canvases.

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

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

   '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 needles on the 2 meters.

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

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

   'popup_msgVarWithScroll' - called by the 'Help' button,
                             to show text in variable $HELPtext.


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 skydiving free falls gone scarily wrong.

    (Anyone see the video of the old grandmother who almost slips out of the harness and grasp of the skydiving instructor who no doubt assured her that there's nothing to worry about?

    If the instructor had not been able to hold onto her, the photographer who was free-falling with them would have probably, helplessly, gotten a video sequence of her free-falling without a parachute, to the ground below.)


The Tcl-Tk CODE

Here is a link to CODE for the Tk script

'meters_memory_swap.tk'.


The shell script (the 'wrapee') :

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

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_memory_and_swap.sh'.


SIMILAR UTILITIES:

There are several more 'meter utilities' on my 'to-do' list for 'tkGooies' --- in the 'METERS' group.

In particular, I may make a meter utility that shows network activity --- and a meter utility that shows CPU activity (preferably for all 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.


2013sep09 UPDATE

Prodded by suggestions from someone on wiki.tcl.tk, I tried getting an auto-update feature working, based on 'wait-seconds' of a 'scale' widget on the GUI.

I got that working in a similar meters script that I composed after this script.

See the web page describing 'SYSTEMtools' tkGooie

'A Pair of Tachometer-style Meters
--- for Network Activity'
.

I used that experience to put the feature in this script.

I have replaced the code above with the new code.

Below is an image of the GUI with the added 'scale' widget.

I also added a display of a count just to the right of the scale.

This is a count of the number of times the 2 meters are updated --- either updates via auto-update based on the current 'wait-seconds' of the scale widget or updates via the 'Refresh' button.

The memory and swap numbers are often not changing at all, so neither the needles nor the TOT-and-USED integers displayed on the GUI are changing.

Having the count displayed confirms that the sampling is occurring at the rate that you have requested.

If you want to eliminate use of the 'external' shell script that runs the 'free' command and extracts the 4 integers needed, you can try implementing one of the commented alternatives in the 'update_needles' proc.

Bottom of this page for
presenting Tcl-Tk and shell scripts for GUI
Meters for Memory-and-Swap 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 Sep 01 at http://wiki.tcl.tk/38637.

This FE web page was created 2014 May 09.
(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 04.
(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:
This code-and-description has not been posted on a Tcler's Wiki page --- at wiki.tcl-lang.org --- formerly wiki.tcl.tk.

If I ever do so, as a backup and alternative to this page, I plan to add a link to that Wiki page here.