Exemples Tcl / Tk?
-
03-07-2019 - |
Question
Tcl / Tk est un moyen simple de créer un script pour de petites interfaces graphiques.
Quelqu'un peut-il donner un bel exemple avec un bouton et un widget texte . Lorsque le bouton est enfoncé, une commande shell doit être exécutée et la sortie dirigée vers le widget text .
Si vous avez d'autres exemples intéressants et propres pour des tâches utiles, ajoutez-les également.
La solution
Voici un exemple plus complet utilisant fileevents. Cela fera défiler automatiquement tout le temps. Pour des raisons de convivialité, vous ne souhaiterez probablement faire défiler automatiquement que si le bas du texte est visible (c.-à-d. Si l'utilisateur n'a pas déplacé la barre de défilement), mais je laisserai cela comme exercice pour que le lecteur conserve cet exemple déjà long. d'obtenir plus longtemps.
package require Tk
proc main {} {
if {[lsearch -exact [font names] TkDefaultFont] == -1} {
# older versions of Tk don't define this font, so pick something
# suitable
font create TkDefaultFont -family Helvetica -size 12
}
# in 8.5 we can use {*} but this will work in earlier versions
eval font create TkBoldFont [font actual TkDefaultFont] -weight bold
buildUI
}
proc buildUI {} {
frame .toolbar
scrollbar .vsb -command [list .t yview]
text .t \
-width 80 -height 20 \
-yscrollcommand [list .vsb set] \
-highlightthickness 0
.t tag configure command -font TkBoldFont
.t tag configure error -font TkDefaultFont -foreground firebrick
.t tag configure output -font TkDefaultFont -foreground black
grid .toolbar -sticky nsew
grid .t .vsb -sticky nsew
grid rowconfigure . 1 -weight 1
grid columnconfigure . 0 -weight 1
set i 0
foreach {label command} {
date {date}
uptime {uptime}
ls {ls -l}
} {
button .b$i -text $label -command [list runCommand $command]
pack .b$i -in .toolbar -side left
incr i
}
}
proc output {type text} {
.t configure -state normal
.t insert end $text $type "\n"
.t see end
.t configure -state disabled
}
proc runCommand {cmd} {
output command $cmd
set f [open "| $cmd" r]
fconfigure $f -blocking false
fileevent $f readable [list handleFileEvent $f]
}
proc closePipe {f} {
# turn blocking on so we can catch any errors
fconfigure $f -blocking true
if {[catch {close $f} err]} {
output error $err
}
}
proc handleFileEvent {f} {
set status [catch { gets $f line } result]
if { $status != 0 } {
# unexpected error
output error $result
closePipe $f
} elseif { $result >= 0 } {
# we got some output
output normal $line
} elseif { [eof $f] } {
# End of file
closePipe $f
} elseif { [fblocked $f] } {
# Read blocked, so do nothing
}
}
main
Autres conseils
Quelques suggestions:
Pour ajouter la sortie au widget texte , au lieu de spécifier la ligne 999999, vous pouvez utiliser l'index end , qui fait référence à la position juste après la dernière nouvelle ligne. Par exemple,
.main insert end "$x\n"
Pour que le texte défile pendant la sortie de la commande, utilisez la commande voir . Par exemple, après avoir ajouté au widget de texte .main
.main see end
Vous pouvez également envisager de saisir la sortie de la commande de manière asynchrone, à l'aide de la commande fileevent .
Je peux commencer ... suggérer des améliorations. Je voudrais qu'il défile pendant que la commande affiche
#!/usr/bin/wish
proc push_button {} {
put_text
.main see end
}
proc put_text {} {
set f [ open "| date" r]
while {[gets $f x] >= 0} {
.main insert end "$x\n"
}
catch {close $f}
}
button .but -text "Push Me" -command "push_button"
text .main -relief sunken -bd 2 -yscrollcommand ".scroll set"
scrollbar .scroll -command ".main yview"
pack .but
pack .main -side left -fill y
pack .scroll -side right -fill y
wiki.tcl.tk est un bon site Web pour toutes sortes de exemples