4

Perl Tkx を使用して単純なアプリケーションを作成しており、ユーザーがディレクトリを選択できるようにしています。名前が長すぎる場合は、テキストの折り返しを使用したり、ボックスをばかげた長さに伸ばしたりしてディレクトリ名全体を表示するのではなく、名前を切り詰めて最後に「...」を追加したいと考えています。

問題は、ラベルの幅が任意の値 (40 など) に定義されていることです。この値がラベルに収まる文字数の測定値である場合、文字列を 37 に切り捨てて「...」を追加するだけで済みますが、そうではないようです。

-widthPerl Tkx を使用したラベルの実際の測定値を知っている人はいますか? -width文字列が占める単位の量を見つけるにはどうすればよいのでしょうか?


編集:

Tclマニュアルでこの回答を見つけました:

データベース クラス: 幅 ラベルの希望の幅を指定します。画像またはビットマップがラベルに表示されている場合、値は画面単位 (つまり、Tk_GetPixels で受け入れられる任意の形式) です。テキストの場合は文字です。

このオプションが指定されていない場合、ラベルの目的の幅は、表示されているイメージ、ビットマップ、またはテキストのサイズから計算されます。

これは、幅 40 でテキストを切り捨てるには、文字列を 37 文字に切り捨てて "..." を追加するだけでよいことを意味します。

ラベルをすべて「M」で埋めて、これをテストしました。通常、最も幅の広い文字であるため、「M」という文字を使用しました (こちら を参照)。37 個の "M" で切り捨てて末尾に "..." を追加するコードを書きましたが、約 24 個の "M" の後、"M" がラベルの末尾を超えてオーバーフローするようです。

これは、最も幅の広い文字の 40 文字に合わせてラベルを引き伸ばすだけであると想定するのは安全ではないことを意味します。したがって、私の質問にはまだ答えがありません。

文字列の「幅」を決定して、適切に切り捨てるにはどうすればよいですか?


EDIT2:

回避策を見つけましたが、探していた解決策ではありません。ラベルのテキストを等幅フォントに変更すると、正しく機能します。見栄えはよくないので、固定幅以外のフォントで機能するソリューションが本当に欲しいです。

4

1 に答える 1

5

for labels が文字数として解釈されるとドキュメントに記載されている場合、-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 に答える