如何在块中构建堆叠的文本行:文本小部件或 canvas?

How to build stacked rows of text in blocks: text widget or canvas?

我正在尝试以“块”的形式垂直堆叠文本,并从右到左组织这些块,以显示圣经经文和希伯来语原文的行间视图。通常,每个原始单词一个块,如下所示为两个这样的块。

          H1254               H7225
          bā·rā           bə·rê·šîṯ
            בְּרֵאשִׁ֖ית              בָּרָ֣א  
        created    In the beginning
 V‑Qal‑Perf‑3ms       Prep‑b | N‑fs 

我对如何解决这个问题或者是否应该在文本小部件或 canvas 中完成感到困惑?每行文字都会有不同的字体和标签,标签有不同的绑定。

由于字体不同,使用 canvas 并分别绘制每个单词的正确方法是否正确?我假设 canvas 宽度可以固定,然后确定每个块中最大文本行的宽度以确定每行可以容纳多少个块。

也许我在这里是愚蠢的,这并不难。我唯一的 GUI 经验是盒子模型,而 flex box 使这很容易;所以,我认为 Tk 也可以做到这一点,但我只是没有看到它。

谢谢。

您可以使用其中任何一个来执行此操作。显然,使用 canvas 您可以将文本放置在任何您想要的位置(使用文本项的边界框来帮助您确定位置),但它有点自己动手。

如果您使用的是文本小部件,则需要设置合适的选项卡和标签。特别是,设置选项卡以使文本按您希望的方式对齐。选项卡设置默认为经典的“每 8 个字符”样式,但您应该改为使用如下内容:

.t configure -tabs {5c right}

所以你可以像这样插入文本(注意:我根本不读希伯来语所以我 真的 不能告诉你那行是否正确):

set dataSource {
          H1254               H7225
          bā·rā           bə·rê·šîṯ
            בְּרֵאשִׁ֖ית              בָּרָ֣א  
        created    {In the beginning}
 V‑Qal‑Perf‑3ms       {Prep‑b | N‑fs}
}
# You've got a better data source than a literal list, but it's good for testing

set aWidth 0
set bWidth 0
set font [.t cget -font]
foreach {a b} $dataSource {
    set aWidth [expr {max($aWidth, [font measure $font $a])}]
    set bWidth [expr {max($bWidth, [font measure $font $b])}]
    .t insert end \t$a\t$b\n
}
.t configure -tabs [list [expr {$aWidth + 10}] right [expr {$aWidth + $bWidth + 20}] right]

请注意,我已经集成了测量文本(使用 font measure)以便根据数据计算出制表符位置。 (10 和 20 只是多了一点 space,这样您就可以看到发生了什么。)

使用标签将样式应用于文本范围,例如不同的字体,或使文本能够响应点击。

set tagName "Title"
.t tag configure $tagName -font {Arial 18 bold} -foreground red
.t tag bind $tagName <1> {puts "Clicked on title"}
.t tag add $tagName 1.0 1.end
# You can also apply tags when inserting
# .t insert end "Example" $tagName

如果需要,您可以在一系列字符上显示很多标签;有一个优先级系统 属性 实际上应用的是来自指定它的最高优先级标签的系统(或者如果没有其他内容,则来自整个小部件的配置属性)。