tjw*_*992 4 string perl user-interface truncate tkx
我正在使用Perl Tkx创建一个简单的应用程序,并允许用户选择一个目录.而不是使用文本包装或将框拉伸到荒谬的长度来显示整个目录名称,如果名称太长,我想截断它并将"..."追加到最后.
问题是标签的宽度被定义为某个任意值(如40).如果这个值是标签可以容纳多少个字符的度量,我可以将字符串截断为37并附加"...",但似乎并非如此.
有谁知道-width使用Perl Tkx的标签实际上是什么?我怎样才能找到-width我的字符串占用的单位数量,这样我就可以找出适当的点来截断它的位置?
编辑:
我在tcl手册中找到了这个答案:
数据库类:宽度指定标签的所需宽度.如果标签中正在显示图像或位图,则该值以屏幕为单位(即Tk_GetPixels可接受的任何形式); 对于文本,它是字符.
如果未指定此选项,则标签的所需宽度将根据图像或位图或其中显示的文本的大小计算.
这应该意味着对于40的宽度来截断文本我应该只需要将字符串截断为37个字符并添加"...".
我通过用所有"M"填充标签来测试这一点.我使用字母"M",因为它通常是最宽的字符(见这里).我编写的代码截断为37"M"并在末尾添加"...",但"M"似乎在大约24"M"之后溢出标签的末尾.
这意味着假设它只是拉伸标签以适应最宽的角色40这是不安全的...因此我的问题仍然没有答案.
如何确定字符串的"宽度",以便我可以适当地截断它?
EDIT2:
我找到了一个解决方法,但它仍然不是我想要的解决方案.如果将标签上的文本更改为固定宽度字体,它将正常工作.它看起来不太好看,所以我真的很喜欢适用于非固定宽度字体的解决方案.
当文档说-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;
}
Run Code Online (Sandbox Code Playgroud)