簡體   English   中英

如何在 Tcl/Tk 中自動換行 label 中的文本?

[英]How to wrap text in label automatically in Tcl/Tk?

有沒有人做過或知道如何進行自動 [ label ] 換行符? 還是智能識別到達每一行的末尾,即邊緣的邊緣,僅限於小部件本身?

代碼:

package require Img

# Container
frame .fr -borderwidth 2 -bg white 

# Text Variable
set description "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris"

# Thumbnail
image create photo pic -file /home/tc/webvideo/galinha_pitadinha/seu_lobato.jpg
button .fr.bt -relief flat -bg white -image pic

# Description
label .fr.lb -bg white -textvariable description -wraplength 250 -width 30 -justify left

pack .fr .fr.bt .fr.lb -side left -fill x -padx .5c -pady .5c

代碼結果:

在此處輸入圖像描述

從編程上講,我希望它看起來像這樣:

在此處輸入圖像描述

我想打破句子,以及上面的說明性圖像。

請注意,缺少正則表達式來尋找第二行的末尾並與末尾的小盆(橢圓)結婚。 當然,隱藏文本的 rest。

通過以下方式將鼠標懸停在label小部件上時,將顯示所有文本: tooltip

我一直在思考兩個假設。 他們是:

  • 1) 顯示 Text 變量中“字符”的總數

    tk_messageBox -message [string length $description]

  • 2) 顯示 Text 變量中“單詞”的總數

    tk_messageBox -message [llength $description]

我停在這里:

-wraplength 250屬性的這個設置中,我每兩行有10 個單詞的變化。 基於此,我可以應用一個條件並將單詞字符的數量作為決定因素,只顯示到第二行。

# If it were to quantify Characters and not words, this would be
if {[string length $description] < 40} {
pack [label .b -textvariable description -wraplength 250 -width 30 -justify left] -side top -fill x
}

或者比較一定數量的單詞,在這種情況下是 10 個單詞。 如果為真,則執行正則表達式的動作

 # If it were to quantify words and not characters, this would be
 if {[llength $description] <10} {
  ... RegExp code here ...
 }

label小部件采用-wraplength選項 在任何 forms 中都需要一個環繞寬度,以提供屏幕距離測量值(例如, 190像素的 190 像素,5 厘米的5c )。

(很少使用的)消息小部件可以改為專注於嘗試為其包含的文本獲得特定的縱橫比。


如果您願意破壞性地更改正在顯示的文本,則可以在腳本中進行省略號注入。

pack [label .l -textvar msg]
set msg "Lorem ipsum,\nfoo bar grill whatever to make this long"

proc trimWithEllipsis {msg width font {ellipsis ...}} {
    set ew [font measure $font $ellipsis]
    set out ""
    foreach c [split $msg ""] {
        if {[font measure $font $out$c] > $width} {
            set oute ""
            foreach c2 [split $out ""] {
                if {[font measure $font $oute$c2$ellipsis] > $width} {
                    return $oute$ellipsis
                }
                append oute $c2
            }
            # failed to find ellipsis injection point??? keep going normally... 
        }
        append out $c
    }
    return $msg
}

# How to apply the code
set msgLines {}
foreach line [split $msg "\n"] {
    # 200 (pixels) was a good demonstration value on this system
    lappend msgLines [trimWithEllipsis $line 200 [.l cget -font]]
}
set msg [join $msgLines "\n"]

我與其他 Tk 開發人員談過話,我們一致認為這類事情應該是核心功能,特別是因為它也可以很好地適用於其他小部件類型(尤其是條目和列表框)。 這應該是核心功能的另一個原因是,這意味着包裝的細節不會是 Model 的一部分(即 variable/ -message屬性的內容),而純粹是一個視圖問題。 但是它沒有機會制作 8.6 或更早版本。

在我看來,我在黎明時進行的這種編碼似乎是一個可能的解決方案。 但是,我還沒有測試與Tk相關的編碼。 如果成功或失敗,我會做測試和任何消息。 我會更新這個答案。

我在這里(在下面的代碼中)基本上要做的是創建一個文件作為指針,從那里我將開始找到我想在 label 上顯示的兩行。 請遵循源代碼中包含的注釋:

#!/usr/bin/env tclsh

# Opening a nonexistent file (empty)
set file [open "input.txt" w]

# Writing on it ..
puts $file "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris"

# Close. This saves a few bytes.
close $file

# Opening it again, now let's read.
set file [open "input.txt" r]

# Read me.
set read [read $file]

# Now I need to replace multiple spaces with '+' as a reference for
# we quantify and subsequently break the phrase into the variable at this point (+)
set add [string map -nocase {{ } {+}} $read]

# Just an index, indicator that starts counting the for loop
set count 0
for {set value 0} {$value<10} {incr value} {

# In this variable I will extract line-by-line
set number [lindex $add $count]

# Now I create a list
set data [list]

# It's time to break the text by the '+' signs, saving the result (a list of words) in the data variable
lappend data [split $number +]

# Just an index, indicator that starts counting the while loop
set indice 0

# Loop running until 10 words are exhausted
while {$indice<10} {

# Is this variable , wich show result
# shows us the words the loop went through until the set value ended: 10
   set result [lindex $data 0 $indice]

    # See them now on screen, detail!
        # The variable phrase, which was once a single line, was broken and passed to the list.
        # Thus, every word followed by its comma (,) and / or period (.)
        # are in a single column, you will need to format them again to be displayed in "a single row"
        # We enter the argument "-nonewline" getting all words extracted by on one line
        # The space purposely placed in front of the variable "$ result"
        # Is required to have space between words again       
          puts -nonewline "$result "
   incr indice
}
        incr count
      puts ".."
   break
}

close $file 

結果 output:

打印屏幕

在此處輸入圖像描述

這里值得一提的是,我在我的機器(微機)中打包的是,Tcl 8.4和8.5的包還沒有8.6。 這是我在 Tcl/Tk 中編程的工作環境。

但是我在這個在線平台上編寫了代碼並運行了測試,運行 Tcl 8.6。


我現在的關注和工作是使用 Tk 庫調整上面的代碼。

我的任務是捕獲 output 並檢索它。 全部在運行時。

我多次嘗試將put命令的 output 傳遞到另一個可以檢索新內容的變量中。

但不幸的是,我不知道如何成功。 因為我是語言編程 Tcl 的新手。

因此,我使用帶有腳本 Tcl 的 Shell 腳本 Unix 進行了此捕獲。 見部分:

  • 這里恢復命令put的 output :
    set txt [exec cat./output.txt]

  • 這里放output: -textvariable txt
    label.fr.lb -bg white -textvariable txt -wraplength 250 -width 30 -justify left

現在將代碼放入包裝器中,此procedure全部終止對 Tcl 腳本進程的調用,並將其傳輸到 Bourn Shell 腳本,該腳本又返回一個 window 和已經格式化的label文本。 像這樣:

proc test {} { 
     .. The code .. 
  put "output some text"
}

# invoke in file end 
test

無需進一步解釋,僅分析和得出結論。

現在看結構

讓我們將puts命令的 output 重定向到外部文件output.txt

我們必須創建 3 個文件,其中兩個是 Tcl,另一個是 Bourne Shell。 看:

test.tcl:腳本 Tcl 主要

#!/usr/bin/env sh
# \
exec wish "$0" "$@"

package require Img

set txt [exec cat ./output.txt]

# Container
frame .fr -borderwidth 2 -bg white 

# Thumbnail
image create photo pic -file thumb.jpg
button .fr.bt -relief flat -bg white -image pic

# Description
label .fr.lb -bg white -textvariable txt -wraplength 250 -width 30 -justify left

# The help texts, as we said, stay in an array:

set subtitle(.fr.lb) [exec cat ./input.txt]

# The frame that will contain the help text itself:

frame .help -bd 1 -bg black
label .help.lab -wraplength 200 -width 30 -text "Texto da subtitle" -bg lightyellow -justify left
pack .help.lab

# Note that we do not materialize the frame as we do not want it to appear now.

# Now comes the most important part. When the mouse cursor enters a button, we should start the process of "Show in the future" the help frame.

bind .fr.lb <Enter> {+
    set subtitle(win) %W
    .help.lab config -text $subtitle(%W)
    set subtitle(id) [after 500 place .help \
        -x [expr %x + [winfo x %W]] \
        -y [expr %y + [winfo y %W] + 20] ]
}

# 

bind .fr.lb <Leave> {+
    if [info exists subtitle(id)] {
        after cancel $subtitle(id)
        unset subtitle(id)
    }
    place forget .help
}

pack .fr .fr.bt .fr.lb -side left -fill x -padx .5c -pady .5c

test.sh:調用腳本test.tcl e調用put命令的output

#!/usr/bin/env sh
# \
exec tclsh "$0" "$@"

set file [open "input.txt" w]

puts $file "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris"

close $file

proc test {} {

set file [open "input.txt" r]

set read [read $file]

set add [string map -nocase {{ } {+}} $read]

set value 0

for {set value 0} {$value<10} {incr value} {

set number [lindex $add $value]

set data [list]

lappend data [split $number +] 

set indice 0

while {$indice<10} {
    set result [lindex $data 0 $indice]
    puts -nonewline "$result "
    incr indice
    }    
  incr value
  puts ".."
  break
  }
 close $file
}

# Invoke
test

main.tcl:插入out of command放入文件output.txt

#!/usr/bin/env sh
# \
exec tclsh "$0" "$@"

exec ./test.sh > ./output.txt 
exec ./test.tcl

我不希望代碼位於單獨的文件中,但這組織得很好。

使用 Tk 庫的代碼時,適配一直在並行開發。。保持不變:即在同一平面上,不要相互切割。

我將留下腳本和圖片,以便從我的 Google Drive 帳戶下載 - Acess 以獲取

響應代碼太長,因為它包含tooltip代碼。

打印屏幕:

在此處輸入圖像描述

如果我現在或以后升級代碼,我會發布更改。 感謝所有人,通過貢獻

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM