繁体   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