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.

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top