Helley's comments are why I hate working on GUIs. Not to mention the huge time sink they are. I thought this would take me a couple hours and 20 lines of code, it's taking a couple days and a couple pages of code.
This is just a first cut. Once we're happy things are working right I'm replacing the tk entry widget with some sort of database query to get the MAC address (we build 100+ of these things a week). But the database server won't be available until sometime this summer, I have to start programming MACs Monday.
My current script is below. It's still got bugs, but to be honest I've spent a lot more time on it than I ever thought it would take.
#!perl -w
#
# Perl/tk script to present the user with the existing MAC address, an
+d
# allow them to enter a new one.
#
# Known bugs.
# 1) Make an invalid entry '333', and tab. You go to the next field.
# 2) I've seen the background stay red. Not sure how I do it, but on
+ce it
# goes red it stays red.
use strict;
use MyPerlConstants;
use Tk;
# Take a 6 element array and make it string.
sub makeString {
my @data = @_;
my $result = sprintf "%02s:%02s:%02s:%02s:%02s:%02s",
$data[0], $data[1], $data[2], $data[3], $data[4], $data
+[5];
return $result;
}
my $debug = $TRUE;
# If the user control-C's out, or kills my window, this will stay fals
+e
my $done = $FALSE;
# I want the first widget to have focus when I start, the only way I'v
+e
# managed to do so is to save all my entry widgets.
my @entries;
# Turns out it's useful to know what entry your on....
my $current = 0;
sub validate {
my ($val) = @_;
my $b_valid = ($val =~ /^[0-9a-f]{1,2}$/i)? 1: 0;
# debugging, print the field.
printf"<%s>: %s valid\n", $val, $b_valid? "IS": "is NOT" if $debu
+g;
whoopsie() if !$b_valid;
if($b_valid) {
$current++;
$current = 0 if $current > 5;
}
#$entries[$current]->focus();
return $b_valid;
}
# Called when the user makes an invalid entry.
sub whoopsie {
my $widget = $entries[$current];
my $bg = $widget->cget(-background);
$widget->bell;
$widget->configure(-background => 'red');
$widget->update();
$widget->after(500, sub { $widget->configure(-background => $bg) }
+);
$widget->selectionFrom(0);
$widget->selectionTo(100);
$widget->focus();
#$widget->selectionRange(0, 3);
}
sub doit {
my @addy = @_;
my $mw = MainWindow->new(-title => 'MAC Address Input');
# 3 frames: original, new, and the buttons.
my $forig = $mw->Frame()->pack(-expand => 1, -fill => 'both')->
pack(-side => 'top');
my $fnew = $mw->Frame()->pack(-expand => 1, -fill => 'both')->
pack(-side => 'top');
my $fdone = $mw->Frame()->pack(-expand => 1, -fill => 'both')->
pack(-side => 'top');
$forig->Label(-text => 'Current MAC address ', -width => 20)->
pack(-side => 'left');
$fnew->Label(-text => 'Enter new MAC address ', -width => 20)->
pack(-side => 'left');
# Now build some entry widgets to change it.
for my $i (0 .. 5) {
$forig->Label(-text => $addy[$i], -width => 2, -takefocus => 0)
->pack(-side => 'left');
# Don't add a trailing colon (jeez, the mental image that brings
+....)
if($i != 5) {
$forig->Label(-text => ':', -width => 1)->pack(-side => 'left
+');
}
$entries[$i] = $fnew->Entry(
-textvariable => \$addy[$i],
-width => 2,
-validate => 'focusout',
-validatecommand => \&validate,
#-invalidcommand => [ \&whoopsie, $entries[$i] ],
)->pack(-side => 'left');
if($i != 5) {
$fnew->Label(-text => ':', -width => 1)->pack(-side => 'left'
+);
}
}
$entries[0]->focus; # give first widget focus.
$entries[0]->selectionFrom(0);
$entries[0]->selectionTo(100);
$fdone->Label(-width => 12)->pack(-side => 'left');
$fdone->Label(-width => 12)->pack(-side => 'right');
$fdone->Button(-text => "Program",
-command => sub {$mw->destroy;$done = $TRUE},
-background => 'green',
-activebackground => 'green2',
)->pack(-side => 'left');
$fdone->Button(-text => "Cancel",
-command => sub {$mw->destroy;},
-background => 'red',
-activebackground => 'red2',
)->pack(-side => 'right');
MainLoop;
return(@addy);
}
#my @foo = (0x10, 0x22, 0x33, 0x4b, 0x5f, 0x6d);
my @foo = qw/10 22 33 4b 5f 6d/;
print "Starting with: " . makeString(@foo) . "\n";
my @bar = doit(@foo);
print "Ended with: " . makeString(@bar) . "\n";
print 'done: ' . $done . "\n";
Anyway, thanks for your help, and I'm sure you'll see some of your DNA in this script.
I'd actually enjoy any critique of this code you might write up. As I said, I'm new to this and would rather not unlearn bad habits in a few months. My email is jharkins@qualcomm.com if you want to critique it privately.
| [reply] [d/l] |