A little login dialog

Summary

Richard Suchenwirth 2002-03-13: Here is a little proc that brings up a username/password widget, the password field being made unreadable as is usual, and grabs focus until terminated with "OK", "Cancel" or <Return>.

It returns a list of two elements: username and password, or an empty list if canceled.

Description

WikiDbImage login.jpg

Much can be done to improve this - just take it as a first shot!

proc tk_login {w {title "Log please"}} {
    toplevel $w -borderwidth 10
    wm title $w $title
    label  $w.u -text "User name:"
    entry  $w.user -textvar _username
    label  $w.p -text "Password:"
    entry  $w.pass -show * -textvar _password
    label  $w.dummy -text ""
    button $w.ok -text OK -command {set _res [list $_username $_password]}
    button $w.cancel -text Cancel -command {set _res {}}
    grid   $w.u $w.user -         -sticky wns
    grid   $w.p $w.pass -         -sticky wns
    grid   $w.dummy x   x
    grid   x    $w.ok   $w.cancel -sticky news
    bind $w <Return> [list $w.ok invoke]
    bind $w <Escape> [list $w.cancel invoke]
    raise $w
    grab set $w
    vwait _res
    destroy $w
    unset ::_username ::_password
    return $::_res
}
# Silly little test...
pack [text .t]
update
set password ""
while {$password != "secret"} {
    set userpass [tk_login .login]
    set password [lindex $userpass 1]
}
.t insert end "[lindex $userpass 0] logged in\n"

KPV: Here's a slight tweak of the above code to get better resize behavior. Of course, you could just make the windows un-resizable but I think it's better to allow it to get wider. Also, there's no need for the dummy label widget to get the spacing you want--just use grid to create an empty row with -minsize set.

proc tk_login2 {w {title "Login please"}} {
    toplevel $w -borderwidth 10
    wm title $w $title
  
    # change the following to 'wm resizable $w 0 0' to prevent resizing
    wm resizable $w 1 0
    wm protocol $w WM_DELETE_WINDOW {set _res {}}
    label  $w.u -text "User name:"
    entry  $w.user -textvar _username
    label  $w.p -text "Password:"
    entry  $w.pass -show * -textvar _password
    button $w.ok -text OK -width 8 -command {set _res [list $_username $_password]}
    button $w.cancel -text Cancel -width 8 -command {set _res {}}
    grid   $w.u $w.user -     -         -sticky news
    grid   $w.p $w.pass -     -         -sticky news
    grid   rowconfigure $w 10 -minsize 20
    grid   x    x       $w.ok $w.cancel -sticky news -row 11 -padx 2 -pady 2
    grid columnconfigure $w 1 -weight 1
    
    bind $w <Return> [list $w.ok invoke]
    bind $w <Escape> [list $w.cancel invoke]
    raise $w
    grab set $w
    
    focus $w.user

    vwait _res
    destroy $w
    unset ::_username ::_password
    return $::_res
}

http://www.frbc-va.org/misc/login.gif

Scott Nichols: I like this login window. I tweaked the above to set focus on the user entry.

RLH: Gave the buttons a uniform width and padding to make them look better.

rdt: Well, the problem that I see with this, is that reducing the size covers the buttons instead of using the left-side space. To me, this is real no-no!

RLH: I just re-ran the second version and it looks better. The original has the buttons side-by-side, a ui design no-no. The second one spaces them and makes the buttons uniform in size. I guess I do not see your point.

rdt: Now that it's resizable, reduce its size from the beginning value. The Cancel button gets truncated! A no-no!

RLH: I agree and disagree. I agree that truncating the buttons is a no-no. I disagree because the original change states that you could make the dialog "un-resizable" to prevent that, which is what I would do for a login dialog. So I was not thinking about resizing only aesthetics.

rdt: I understand. If its made resizable in order that the entry boxes can be made larger, then the resizing should _never_ truncate a button. RLH: No argument from me there.

RS 2004-09-14: Added a line each to unset ::_username and ::_password...

LV: So what could be added to the second login to keep it from being resized so small that the buttons disappear?

JJ: Added keybinding for <Escape> to both examples

EF: Added a wm protocol tweak to make sure closing the window is the same as pressing cancel.

See Also

Authentication by formula
tk login window