• 0
antarey

Как вычислить размер текста?

Вопрос

Как задать ширину едита по длине текста?

В лейбела есть свойство AutoSize там все просто :), а как в едита???

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

8 ответов на этот вопрос

  • 0

Примерно так:

function GetTextWidth(AText: string; AFont: TFont): Single;
var
  txt: TText;
begin
  txt := TText.Create(nil);
  try
    txt.Align := TAlignLayout.alNone;
    txt.VertTextAlign := TTextAlign.Leading;
    txt.HorzTextAlign := TTextAlign.Leading;
    txt.Trimming := TTextTrimming.None;
    txt.Font := AFont;
    txt.WordWrap := False;
    txt.BeginUpdate;
    txt.Text := AText;
    txt.EndUpdate;
    txt.AutoSize := True;
    Result := txt.Width;
  finally
    FreeAndNil(txt);
  end;
end;

Написал не проверяя, но вроде все верно.

Используйте у TEdit событие OnTyping или OnKeyDown, ну или типа того.. И меняйте соответственно значению функции.

 

P.S. Забыл добавить, что к значению функции Вам надо добавить некую X по ширине, так как сам TEdit имеет внутренний Padding.Left/Right, соответственно установленному стилю. Можно его "ручками" поставить, а можно рассчитывать программно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
AlexG 
 
TText *txt = new TText(Application);
try
{
txt->Align = TAlignLayout::alNone;
txt->VertTextAlign = TTextAlign::Leading;
txt->HorzTextAlign = TTextAlign::Leading;
txt->Trimming = TTextTrimming::None;
txt->Font = AFont;
txt->WordWrap = false;
txt->AutoSize = true;
txt->BeginUpdate();
txt->Text = AText;
txt->EndUpdate();
return txt->Width;
}
 __finally
{
txt->Free();
}

Всегда возвращает 0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Нужно использовать TTextLayout для этого. Это будет быстрее, чем создавать TText, TLabel, которые по сути в конечном итоге используют тот же TTextLayout.
 
В приведенном ниже коде, нужно правильно задать требуемые настройки текста: шрифт, переносы, выравнивание и тд.

uses
  FMX.TextLayout;

{$R *.fmx}

procedure TForm3.Button1Click(Sender: TObject);
var
  TextLayout: TTextLayout;
begin
  TextLayout := TTextLayoutManager.DefaultTextLayout.Create;
  try
    TextLayout.BeginUpdate;
    try
      TextLayout.Text := Text;
      TextLayout.MaxSize := TPointF.Create(Width, 1000);
      TextLayout.WordWrap := WordWrap;
      TextLayout.Font := Font;
      TextLayout.HorizontalAlign := TextAlign;
      TextLayout.VerticalAlign := VertTextAlign;
    finally
      TextLayout.EndUpdate;
    end;
    // TextLayout.TextRect; <- Здесь будет размер текста
  finally
    TextLayout.Free;
  end;
end;

Когда получите размер текста в TEdit, не забудьте, что нужно учесть размер рамки эдита и возможное наличие кнопок, что корректно задать ширину.

 

Обновлять ширину надо в события OnChange и OnChangeTrtacking, в зависимости от требуемой вам ситуации.

antarey, Kitty и Andrew понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

надо убрать строку

txt->HorzTextAlign = TTextAlign::Leading;

на билдере будет так

 

int TForm2::GetTextWidth(String AText,TFont *AFont)
{
TText *txt = new TText(Application);
_di_ITextSettings Settings;


try
{
txt->BeginUpdate();
txt->Align = TAlignLayout::alNone;
txt->Font = AFont;
if(txt->GetInterface(Settings))
{
Settings->TextSettings->VertAlign=TTextAlign::Leading;
Settings->TextSettings->WordWrap=false;
Settings->TextSettings->Trimming=TTextTrimming::None;
Settings->StyledSettings=Settings->StyledSettings>>TStyledSetting::ssOther;
}


txt->AutoSize = true;
txt->Text = AText;
txt->EndUpdate();
return txt->Width+2;
}
 __finally
{
txt->Free();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Edit3KeyDown(TObject *Sender, WORD &Key, System::WideChar &KeyChar,
 TShiftState Shift)
{
Edit3->Width=(Edit3->Width>GetTextWidth(Edit3->Text,Edit3->Font))?Edit3->Width:GetTextWidth(Edit3->Text,Edit3->Font);
}
//---------------------------------------------------------------------------

но все равно что - то не то - если повешать на OnKeyDown то все нормально, а если менять по клику на какой-то кнопке - то размер больше чем надо :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Ярослав, исходя из чего брать Width

TextLayout.MaxSize := TPointF.Create(Width, 1000);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Исходя из ваших предпочтений в какую область у вас должен быть вписан текст. Если у вас нету ограничения, то поставьте этот размер большим. Я для примера взял 1000 пикселей для высоты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Я создаю и добавляю  едит в динамике

 

TEdit *editbutton = new TEdit(Application);
editbutton->Text=Edit3->Text;
editbutton->Width=GetTextWidth(Edit3->Text.Trim(),Edit3->Font);
editbutton->Align=TAlignLayout::FitLeft;

Вот переделал под билдер

int TForm2::GetTextWidth(String AText,TFont *AFont)
{
TTextLayout *TextLayout = TTextLayoutManager::TextLayoutForClass(TTextLayoutManager::DefaultTextLayout);


try
{
   TextLayout->BeginUpdate();
   TextLayout->Text = AText;
   TextLayout->MaxSize = TPointF(1000, 1000);
   TextLayout->WordWrap = false;
   TextLayout->Font = AFont;
   TextLayout->HorizontalAlign = TTextAlign::Leading;
   TextLayout->VerticalAlign   = TTextAlign::Leading;
   TextLayout->EndUpdate();


   return TextLayout->TextRect.Width();
}
 __finally
{
TextLayout->Free();
}


}

но размер едита больше чем надо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Размер TEdit больше, так как вычисление размеров текста нужно производить в момент, когда стиль загружен.

А при создании в рантайме, контрол загрузит свой стиль при первой отрисовке. Либо же надо перед вычислением размера текста форсировать загрузку стиля вызовом метода: 

Edit.ApplyStyle;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость
Эта тема закрыта для публикации сообщений.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу