Frage

Tcl / Tk ist ein einfacher Weg, um Skript kleine GUIs.

Kann jemand ein schönes Beispiel geben mit einer Taste und text Widget. Wenn die Taste gedrückt wird, sollte ein Shell-Befehl ausgeführt und die Ausgabe einer Pipeline an die text Widget.

Wenn Sie andere schöne und saubere Beispiele für nützliche Aufgaben haben, fügen Sie sie auch.

War es hilfreich?

Lösung

Hier ist ein vollständigeres Beispiel mit fileevents. Dies wird automatisch bewegt die ganze Zeit. Für Usability Zwecke möchten Sie wahrscheinlich nur auf Autoscroll, wenn der Boden des Textes sichtbar ist (dh: wenn der Benutzer die Scrollbar nicht bewegt hat), aber ich werde das als eine Übung überlassen dem Leser diese schon lange Beispiel zu halten von nicht mehr zu bekommen.

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

Andere Tipps

Einige Vorschläge:

Um die Ausgabe an den Text Widget anhängen, statt eines festen Linie 999999, können Sie den Index Ende verwenden, die nur nach dem letzten Newline auf die Position bezieht. Zum Beispiel:

.main insert end "$x\n"

den Text blättern zu haben, wie der Befehl ausgegeben wird, verwenden Sie die sehen Befehl. Zum Beispiel, nachdem sie den .main Text-Widget Anhänge

.main see end

Sie können auch wollen die Befehlsausgabe asynchron betrachten Grabbing, mithilfe der Fileevent Befehl.

Ich kann einen Start geben ... Bitte Verbesserungen vorschlagen. D.h Ich mag würde es blättern, wie der Befehl ausgibt

#!/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 ist gute Website für alle Arten von Beispiele

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top