Как правильно располагать и выравнивать элементы в Flet?

Позиционирую элемент через alignment=ft.Alignment(-0.7, -0.6) <br/> <br/> def button1( <br/> page: ft.Page, <br/> text: str, <br/> color: str, <br/> function: Callable <br/> ) -> ft.Container: <br/> return ft.Container(content=ft.Stack( <br/> [ <br/> ft.Image( <br/> src='assets/images/bgforbt.png', <br/> fit="contain", <br/> height=page.window.height * 0.158, <br/> width=page.window.width * 0.936 <br/> <br/> ), <br/> ft.Container( <br/> content=ft.Text( <br/> value=text, <br/> color=color, <br/> size=16, <br/> weight=ft.FontWeight.BOLD, <br/> text_align=ft.TextAlign.CENTER <br/> ), <br/> alignment=ft.Alignment.CENTER, <br/> ) <br/> <br/> ]), <br/> on_click=function, <br/> alignment=ft.Alignment(-0.7, -0.6) <br/> ) <br/> <br/> В Container у меня находится Stack с изображением и вложенным Container для текста, но в приложении текст отображается отдельно от изображения, хотя должен быть поверх него, и изображение имеет неверный размер. В чём может быть причина и как это исправить?
  • 2 апреля 2026 г. 11:01
Ответы на вопрос 2
Кратко — проблема в размере и в том, где вы задаёте выравнивание:

1) alignment=ft.Alignment(...) у Container управляет положением самого контейнера в родителе, но не позиционирует детей внутри Stack.  
2) Stack сам по себе должен иметь явный размер (width/height) или быть растянут (expand=True), иначе дочерние элементы могут не совпадать по размерам и накладываться неверно.  
3) page.window.width/height на момент создания виджета может быть ещё 0 (или не то, что вы ждёте), поэтому расчёты размеров могут дать неправильные значения.

Что сделать — варианты исправления:

- Явно задайте ширину/высоту внешнего Container (или Stack). Тогда Image и накладываемый Text будут иметь одинаковую область:
  Пример:
  def button1(page, text, color, function):
      w = page.window.width * 0.936 or 600   # запасной вариант, если 0
      h = page.window.height * 0.158 or 60
      return ft.Container(
          width=w,
          height=h,
          on_click=function,
          content=ft.Stack(
              [
                  ft.Image(src='assets/images/bgforbt.png',
                           fit="cover",  # или "fill", если нужно полностью заполнить
                           width=w, height=h),
                  ft.Container(content=ft.Text(value=text, color=color, size=16,
                                               weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
                               alignment=ft.Alignment.CENTER)
              ]
          )
      )

- Или сделать Stack expand=True и дать Image растягиваться:
  ft.Container(width=..., height=..., content=ft.Stack([ft.Image(..., fit="cover", expand=True), ft.Container(..., alignment=ft.Alignment.CENTER)], expand=True))

- Если нужно точечное позиционирование текста внутри Stack, используйте ft.Positioned (если доступен) или контейнеры с alignment внутри Stack:
  ft.Stack([
      ft.Image(...),
      ft.Positioned(left=0, top=0, right=0, bottom=0, child=ft.Container(..., alignment=ft.Alignment.CENTER))
  ])

- Избегайте опоры исключительно на page.window.* при первом создании UI. Лучше:
  - задать фиксированные размеры или проценты от родителя (через expand и родительские контейнеры),
  - или пересоздавать/обновлять размеры после события resize страницы (page.on_resize), когда реальные размеры окна известны.

Итого: задайте размер для контейнера/Stack (или используйте expand), позиционируйте текст через Container(alignment=...) или Positioned внутри Stack, и убедитесь, что вычисления размеров по page.window.* выполняются в момент, когда окно уже имеет реальные размеры. Это исправит некорректный размер изображения и раздельное отображение текста.
у тебя внутренний Container (с текстом) не имеет размеров — он сжимается до размера самого Text и не перекрывает Image. Добавь ему те же width/height что и у картинки: <br/> <br/> <pre><code>ft.Container(
    content=ft.Text(
        value=text,
        color=color,
        size=16,
        weight=ft.FontWeight.BOLD,
        text_align=ft.TextAlign.CENTER
    ),
    alignment=ft.Alignment.CENTER,
    width=page.window.width * 0.936,
    height=page.window.height * 0.158,
)</code></pre> <br/> <br/> а то что картинка "не того размера" — скорее всего из-за fit="contain", он сохраняет пропорции и не заполняет область целиком. Попробуй fit=ft.ImageFit.COVER если нужно заполнить.
Похожие вопросы