Updated 2016-04-25 20:16:53 by gold

See Also  edit

VUW Widgets
Provides a dial widget

Description  edit

From a news:comp.lang.tcl posting by Bob Techentin:

I'm looking more for an analog style meter. Kinda like those old volt meter.

Well, if you just want to display, why not write one into a canvas? It's pretty easy, and fun too. Try this:
# example volt-meter like display
package require Tk

grid [canvas .c -width 200 -height 110 -borderwidth 2 -relief sunken]
grid [scale .s -orient h -from 0 -to 100 -variable v]

.c create line 100 100 10 100 -tag meter

trace variable v w updateMeter

proc updateMeter {name1 name2 op} {
    upvar #0 $name1 v
    set min [.s cget -from]
    set max [.s cget -to]
    set pos [expr {$v / abs($max - $min)}]
    set x [expr {100.0 - 90.0*(cos($pos*3.14))}]
    set y [expr {100.0 - 90.0*(sin($pos*3.14))}]
    .c coords meter 100 100 $x $y
}

DKF: Here is a slightly more complex version which shows a little bit of history and fades nicely. Isn't Tk wonderful?
package require Tk
set ::pi 3.1415927 ;# Good enough accuracy for gfx...

# Create a meter 'enabled' canvas
proc makeMeter {w} {
    global meter angle
    canvas $w -width 200 -height 110 -borderwidth 2 -relief sunken -bg white
    for {set i 70;set j 0} {$i<100} {incr i 2;incr j} {
        set meter($j) [$w create line 100 100 10 100 \
            -fill grey$i -width 3 -arrow last]
        set angle($j) 0
        $w lower $meter($j)
        updateMeterLine $w 0.2 $j
    }
    $w create arc 10 10 190 190 -extent 108 -start 36 -style arc -outline red
    return $w
}

# Draw a meter line (and recurse for lighter ones...)
proc updateMeterLine {w a {l 0}} {
    global meter angle pi
    set oldangle $angle($l)
    set angle($l) $a
    set x [expr {100.0 - 90.0*cos($a * $pi)}]
    set y [expr {100.0 - 90.0*sin($a * $pi)}]
    $w coords $meter($l) 100 100 $x $y
    incr l
    if {[info exist meter($l)]} {updateMeterLine $w $oldangle $l}
}

# Convert variable to angle on trace
proc updateMeter {name1 name2 op} {
    upvar #0 $name1 v
    set min [.s cget -from]
    set max [.s cget -to]
    set pos [expr {($v - $min) / ($max - $min)}]
    updateMeterLine .c [expr {$pos*0.6+0.2}]
}

grid [makeMeter .c]
grid [scale .s -orient h -from 0 -to 100 -variable v]
trace variable v w updateMeter

# Fade over time
proc updateMeterTimer {} {
    set ::v $::v
    after 20 updateMeterTimer
}
updateMeterTimer

uniquename 2014-01-27:

Here is an image produced by the DKF code, on my Linux (Ubuntu 9.10) installation. The image indicates the needle history and fade that DKF mentions above.


simple voltmeter screen.png

gold added pix