سؤال

تي سي ال/تك هي طريقة بسيطة لكتابة واجهات المستخدم الرسومية الصغيرة.

يمكن لأي شخص أن يعطي مثالا لطيفا مع زر و أ نص القطعة.عند الضغط على الزر، يجب تنفيذ أمر shell وإرسال الإخراج إلى الملف نص القطعة.

إذا كان لديك أمثلة أخرى جميلة وواضحة للمهام المفيدة، فيرجى إضافتها أيضًا.

هل كانت مفيدة؟

المحلول

وفيما يلي مثال أكثر اكتمالا باستخدام fileevents. هذا لصناعة السيارات في التمرير في كل وقت. لأغراض الاستخدام ربما كنت ترغب فقط في صناعة السيارات في التمرير إذا كان أسفل النص مرئيا (أي: إذا كان المستخدم لم تتحرك شريط التمرير) ولكن سأترك ذلك باعتبارها ممارسة للقارئ للحفاظ على هذا المثال طويلة بالفعل من الحصول على أكثر من ذلك.

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

نصائح أخرى

بعض الاقتراحات:

لإلحاق الإخراج بـ نص القطعة، بدلاً من تحديد السطر 999999، يمكنك استخدام الفهرس نهاية, ، والذي يشير إلى الموضع بعد السطر الجديد الأخير مباشرة.على سبيل المثال،

.main insert end "$x\n"

لتمرير النص أثناء إخراج الأمر، استخدم يرى يأمر.على سبيل المثال، بعد الإلحاق بأداة النص .main

.main see end

قد ترغب أيضًا في التفكير في الحصول على مخرجات الأمر بشكل غير متزامن، باستخدام الملف fileevent يأمر.

وأستطيع أن أعطي بداية ... يرجى اقتراح التحسينات. أي بمعنى أود أن انتقل كأمر وإخراج

#!/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 هو موقع جيد لجميع أنواع <لأ href = "HTTP: / /wiki.tcl.tk/1291 "يختلط =" نوفولو noreferrer "> أمثلة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top