4

我正在使用 Perl Tkx 制作一个简单的应用程序,并允许用户选择一个目录。如果名称太长,我想截断它并将“...”附加到末尾,而不是使用文本换行或将框拉伸到荒谬的长度来显示整个目录名称。

问题是标签的宽度被定义为任意值(如 40)。如果这个值是标签可以容纳多少个字符的度量,我可以将字符串截断为 37 并附加“...”,但情况似乎并非如此。

有谁知道-width使用 Perl Tkx 的标签实际上是什么?如何找到-width我的字符串将占用的单位数量,以便找出截断它的适当点?


编辑:

我在tcl 手册中找到了这个答案:

数据库类:宽度 指定标签的所需宽度。如果在标签中显示图像或位图,则该值以屏幕为单位(即 Tk_GetPixels 可接受的任何形式);对于文本,它是字符。

如果未指定此选项,则标签的所需宽度是根据其中显示的图像或位图或文本的大小来计算的。

这应该意味着对于 40 的宽度来截断文本,我只需要将字符串截断为 37 个字符并添加“...”。

我通过用所有“M”填充标签来测试这一点。我使用了字母“M”,因为它通常是最宽的字符(见这里)。我编写了代码以在 37 个“M”处截断并在末尾添加“...”,但在大约 24 个“M”之后,“M”似乎溢出标签的末尾。

这意味着假设它只是将标签拉伸以适应最宽的 40 个字符是不安全的……因此我的问题仍未得到解答。

如何确定字符串的“宽度”,以便适当截断它?


编辑2:

我找到了一种解决方法,但它仍然不是我正在寻找的解决方案。如果您将标签上的文本更改为固定宽度的字体,它将正常工作。虽然它看起来不太好,所以我真的很想要一个适用于非固定宽度字体的解决方案。

4

1 回答 1

5

当文档说-width标签被解释为多个字符时,它可能使用字符的平均宽度而不是最大宽度。正如您所发现的,当使用固定宽度字体时,您可以在字符中工作,并且一切都会很好地呈现出来。当使用可变宽度字体时,事情很快就会变得困难,因为字符和像素之间没有固定的关系。

您需要以一致的单位(即像素)工作并缩短文本直到它适合 - 最好有一个良好的初始猜测以保持您的代码快速。您可以通过获取标签宽度(以像素为单位winfo reqwidth)和以像素为单位的文本宽度(对于特定字体),使用font measure.

use strict;
use warnings;
use Tkx;
Tkx::package_require('tile');

my $text;
my $mw    = Tkx::widget->new('.');
my $label = $mw->new_ttk__label(-width => 10, -textvariable => \$text);

Tkx::pack($label, -side => 'left');

$text = limit_text($label, 'abcdefghijklmnopqrstuvwxyz');

Tkx::MainLoop;

sub limit_text {
    my $label       = shift;
    my $text        = shift;
    my $font        = $label->cget('-font') || 'TkDefaultFont';
    my $label_width = $label->g_winfo_reqwidth;
    my $text_width  = Tkx::font_measure($font, $text);
    my $i           = int length($text) * ($label_width / $text_width);

    while ($text_width > $label_width) {
        $text       = substr($text, 0, --$i) . '...';
        $text_width = Tkx::font_measure($font, $text);
    }
    return $text;
}
于 2015-06-03T13:54:07.860 回答