Pregunta

Tcl / Tk es una forma sencilla de escribir pequeñas GUI.

¿Alguien puede dar un buen ejemplo con un botón y un widget de texto ? Cuando se presiona el botón, se debe ejecutar un comando de shell y la salida se canaliza al widget text .

Si tienes otros ejemplos agradables y limpios para tareas útiles, agrégalos también.

¿Fue útil?

Solución

Aquí hay un ejemplo más completo que usa eventos de archivo. Esto se desplazará automáticamente todo el tiempo. Para fines de usabilidad, probablemente solo desee desplazarse automáticamente si la parte inferior del texto es visible (es decir, si el usuario no ha movido la barra de desplazamiento), pero lo dejaré como un ejercicio para que el lector mantenga este ejemplo ya largo de obtener más tiempo.

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

Otros consejos

Algunas sugerencias:

Para agregar la salida al widget text , en lugar de especificar la línea 999999, puede usar el índice end , que se refiere a la posición justo después de la última línea nueva. Por ejemplo,

.main insert end "$x\n"

Para hacer que el texto se desplace a medida que se emita el comando, use el comando ver . Por ejemplo, después de adjuntar al widget de texto principal

.main see end

Es posible que también desee considerar la posibilidad de capturar la salida del comando de forma asíncrona, mediante el comando fileevent .

Puedo dar un comienzo ... por favor sugerir mejoras. Es decir, me gustaría que se desplace cuando se emita el comando

#!/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 es un buen sitio web para todo tipo de ejemplos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top