Grid как объединить две ячейки
Перейти к содержимому

Grid как объединить две ячейки

  • автор:

CSS Grid Layout: Применение областей сетки

От автора: эта статья является частью серии «CSS Grid Layout». Одна вещь, о которой мы упоминали, но пока что должным образом не рассматривали в этой серии — это какие области имеет CSS сетка. До сих пор наши элементы сетки содержались в одной ячейке сетки, но мы можем создавать более практически применимые макеты, нарушая эти границы. Давайте рассмотрим как!

Определение областей сетки

Вот сетка, с которой мы работали: девять элементов сетки, автоматически размещенных в трех равных столбцах, трех равных строках, разделенных зазорами в 20px.

В настоящее время наши элементы имеют только цветовые стили, но вернемся к тому, что мы узнали в первой статье, и добавим правила grid-column и grid-row, на этот раз дополнив их:

background : #b03532;
grid — column : 1 / 3 ;
grid — row : 1 ;

В этом сокращенном выражении grid-column мы эффективно используем grid-column-start и grid-column-end, сообщая, что элемент должен начинаться с линии сетки 1 и заканчиваться на лини 3 сетки.

Вот что это нам дает; первый элемент теперь распространяется на две ячейки, сдвигая другие элементы вправо и вниз в соответствии с алгоритмом автоматического размещения Grid.

То же самое можно сделать со строками, что даст нам гораздо большую область в верхнем левом углу сетки.

background : #b03532;
grid — column : 1 / 3 ;
grid — row : 1 / 3 ;

Объединение ячеек

Используя, возможно, более простой синтаксис, мы можем переключить конец столбца grid-column с помощью ключевого слова span. Используя span мы не привязаны к тому, чтобы указать, где заканчивается область, вместо этого мы определяем, на сколько линий должен распространяться элемент:

background : #b03532;
grid — column : 1 / span 2 ;
grid — row : 1 / span 2 ;

Это дает нам тот же результат, но если бы мы изменили место, где начинается элемент, его конец мы могли бы не указывать отдельно.

В следующей демо-версии вы видите, что мы очистили макет, удалив четыре элемента. Мы указали позиционирование для двух элемента: первый охватывает два столбца и две строки, в то время как четвертый начинается в столбце 3, строке 2 и распространяется вниз на две линии:

Остальные элементы автоматически заполняют доступное пространство. Это прекрасно демонстрирует, что макет сетки не должен отражать исходный порядок элементов.

Примечание. Существует много ситуаций, когда исходный порядок должен полностью отражать представление — не забывайте о доступности.

Именованные области

Использование методов нумерации, которые мы описали до этого, работает отлично, но Области шаблонов Grid могут сделать определение макетов еще более интуитивно понятным.

В частности, они позволяют нам именовать области сетки. С помощью именования областей мы можем ссылаться на них (вместо номеров строк) для указания позиций. Давайте придерживаться нашей текущей демо-версии и используем ее, чтобы создать приближенный макет страницы, включающий:

Мы определяем эти области в контейнере сетки, как будто рисуем их:

Метод grid

Grid является одним из трех менеджеров геометрии в Tkinter (другими являются уже рассмотренный ранее Pack, а также Place). У всех виджетов есть соответствующий данному менеджеру метод grid . «Grid» с английского переводится как «сетка», однако по смыслу правильнее говорить о таблице.

Табличный способ размещения предпочтителен из-за его гибкости и удобства, когда дело доходит до разработки относительно сложных интерфейсов. Grid позволяет избежать использования множества фреймов, что неизбежно в случае упаковщика Pack.

При размещении виджетов методом grid родительский контейнер (обычно это окно) условно разделяется на ячейки подобно таблице. Адрес каждой ячейки состоит из номера строки и номера столбца. Нумерация начинается с нуля. Ячейки можно объединять как по вертикали, так и по горизонтали.

Ячейки и их адреса

На рисунке пунктир обозначает объединение ячеек. Общая ячейка в таком случае обозначается адресом первой.

Никаких предварительных команд по разбиению родительского виджета на ячейки не выполняется. Tkinter делает это сам, исходя из указанных позиций виджетов.

Размещение виджета в той или иной ячейке задается через аргументы row и column , которым присваиваются соответственно номера строки и столбца. Чтобы объединить ячейки по горизонтали, используется атрибут columnspan , которому присваивается количество объединяемых ячеек. Опция rowspan объединяет ячейки по вертикали.

Пусть надо запрограммировать такой GUI:

Пример интерфейса

Представим данный интерфейс в виде таблицы и пронумеруем ячейки, в которых будут располагаться виджеты:

Подготовка к использованию менеджера геометрии Grid

Теперь пишем код:

from tkinter import * root = Tk() Label(text="Имя:").grid(row=0, column=0) Entry(width=30).grid(row=0, column=1, columnspan=3) Label(text="Столбцов:").grid(row=1, column=0) Spinbox(width=7, from_=1, to=50).grid(row=1, column=1) Label(text="Строк:").grid(row=1, column=2) Spinbox(width=7, from_=1, to=100).grid(row=1, column=3) Button(text="Справка").grid(row=2, column=0) Button(text="Вставить").grid(row=2, column=2) Button(text="Отменить").grid(row=2, column=3) root.mainloop()

Примечание. В примере используются виджеты класса Spinbox , которые не рассматривались в курсе. Spinbox похож на Entry , но для него задается список принимаемых значений, и имеется подобие скроллера.

Выполнив приведенный выше программный код, получим:

Результат размещения виджетов методом grid

Похоже, но не совсем то, что хотелось. Теперь на помощь должны прийти другие свойства метода grid . У него, также как у pack , имеются атрибуты для задания внешних и внутренних отступов ( padx , pady , ipadx , ipady ).

Кроме этого есть атрибут sticky (липкий), который принимает значения направлений сторон света (N, S, W, E, NW, NE, SW, SE). Если, например, указать NW, то виджет прибьет к верхнему левому углу ячейки. Виджеты можно растягивать на весь объем ячейки ( sticky=N+S+W+E ) или только по одной из осей ( N+S или W+E ). Эффект от «липучки» заметен, только если виджет меньше ячейки.

from tkinter import * root = Tk() Label(text="Имя:")\ .grid(row=0, column=0, sticky=W, pady=10, padx=10) Entry()\ .grid(row=0, column=1, columnspan=3, sticky=W+E, padx=10) Label(text="Столбцов:")\ .grid(row=1, column=0, sticky=W, padx=10, pady=10) Spinbox(width=7, from_=1, to=50)\ .grid(row=1, column=1, padx=10) Label(text="Строк:")\ .grid(row=1, column=2, sticky=E) Spinbox(width=7, from_=1, to=100)\ .grid(row=1, column=3, sticky=E, padx=10) Button(text="Справка").grid(row=2, column=0, pady=10, padx=10) Button(text="Вставить").grid(row=2, column=2) Button(text="Отменить").grid(row=2, column=3, padx=10) root.mainloop()

Применение опций padx, pady и sticky метода grid

С помощью методов grid_remove и grid_forget можно сделать виджет невидимым. Отличие между этими методами лишь в том, что grid_remove запоминает прежнее положение виджета. Поэтому для его отображения в прежней ячейки достаточно применить grid без аргументов. После grid_forget потребуется заново конфигурировать положение виджета.

from tkinter import * def rem(): global l1_flag if l1_flag == 1: l1.grid_remove() l1_flag = 0 else: l1.grid() l1_flag = 1 def forg(): global l2_flag if l2_flag == 1: l2.grid_forget() l2_flag = 0 else: l2.grid(row=1) l2_flag = 1 root = Tk() l1_flag = 1 l2_flag = 1 l1 = Label(width=5, height=3, bg='blue') l2 = Label(width=5, height=3, bg='green') b1 = Button(bg='lightblue', command=rem) b2 = Button(bg='lightgreen', command=forg) l1.grid(row=0) l2.grid(row=1) b1.grid(row=2) b2.grid(row=3) root.mainloop()

В данной программе голубая метка после удаления будет появляться в том же месте, где была до этого, несмотря на то, что в функции rem к ней применяется метод grid без настроек. В отличие от нее зеленая метка, если ей не указать место размещения после удаления, появлялась бы под кнопками.

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

Практическая работа

Перепрограммируйте второе окно из практической работы предыдущего урока, используя метод grid .

Результат разметки интерфейса методом grid

Курс с примерами решений практических работ: pdf-версия

X Скрыть Наверх

Tkinter. Программирование GUI на Python

CSS Grid Layout: возвращение табличной вёрстки. Часть 2

В первой части этой статьи мы знакомились с вёрстой макетов HTML-страниц с помощью CSS Grid Layout. И по ходу выяснили, что это по сути возвращение к интуитивно понятным принципам вёрстки табличками, практиковавшейся повсеместно в годы первоначального накопления контента во Всемирной Паутине.

Автоматизация — главное, чем отличается CSS Grid Layout от табличной HTML-вёрстки Общий алгоритм этой автоматизации прост. Если элемент веб-страницы имеет свойство отображения display: grid , то браузерный модуль CSS Grid автоматически нарисует на месте этого элемента сетку-табличку согласно явно или по умолчанию заданным свойствам и автоматически заполнит ячейки этой таблички дочерними элементами. Осталось только попрактиковаться с основными свойствами CSS Grid, чтобы получался нужный табличный шаблон.

По умолчанию, если все параметры сетки не заданы явным образом, модуль CSS Grid нарисует табличку в одну колонку, где для каждого элемента будет выделена ячейка в новом ряду. Ширина колонки будет занимать всё свободное место по ширине, а высота каждого ряда будет подогнана к высоте каждого элемента. Зазор между ячейками отсутствует.

Но мы ведь хотим чего-то большего в этой жизни, чем табличка в одну колонку. Поэтому придётся задавать для неё некоторые свойства явным образом.

Основные параметры любой таблицы это количество колонок и рядов, их размеры и зазор между ячейками. В CSS Grid количество и размер колонок явно задаётся CSS-свойством grid-template-columns , количество и размер рядов — свойством grid-template-rows , а свойства grid-column-gap и grid-row-gap зададут ширину вертикальных и горизонтальных дорожек между ячейками.

Для примера сверстаем с помощью CSS Grid шаблон галереи изображений. Ниже пример шаблона галереи на четыре колонки и три ряда с ячейками по 220х164 пикселя и расстоянием между ними шесть пикселей по вертикали и десять по горизонтали.

.mygrid

После чего забрасываем наши картинки с самым популярным контентом Веба — котиками и собачками — в этот шаблон и автоматически получаем галерею.

[Галерея с помощью CSS Grid]

Ещё больше лаконизма

Как видим, даже в самом явном виде таблица CSS Grid не теряет своей компактности, о которой с большим пафосом было написано в первой части статьи.

А можно ли сделать явное определение сетки CSS Grid ещё более коротким? — Можно. Для этого следует использовать нотацию repeat(), чтобы указанное количество раз повторить структуру трека. И галерею выше можно определить так:

.mygrid

В огромных сетках-таблицах с большим количеством ячеек нотация repeat() будет часто выручать.

Но и это ещё не предел компактности. Как и многие определения каскадных таблиц стилей, свойства CSS Grid имеют сокращённую форму записи. Колонки и строки можно описать одним свойством grid . Сокращённая форма для зазоров между ячейками — gap .

Пример явного определения той же галереи картинок с использованием свойств grid и gap :

.mygrid< display: grid; grid: repeat(3, 164px)/repeat(4, 220px); gap: 10px 6px; >

Ещё больше автоматизации

Но что, если лень или не хватает пальцев на руках и ногах, чтобы посчитать количество изображений в галерее? Или же, например, в нашу галерею картинки с котиками передают через форму посетители сайта и неизвестно, сколько нужно создавать ячеек.

Если элементов в контейнере больше, чем явно задано в определении сетки, то модуль CSS Grid просто самостоятельно дорисует новые ячейки в таблице. И этой автоматизацией можно управлять посредством свойств grid-auto-rows , grid-auto-columns .

Например, для нашей галереи можно определить свойство grid-auto-rows , чтобы ряды, создаваемые автоматически, были высотой 164 пикселя. И у нас получится снова та же самая галерея.

.mygrid

Grid area — объединение ячеек

В HTML-таблицах было возможно объединение ячеек через атрибуты colspan и rowspan . Объединение ячеек возможно и в CSS Grid. Объединённые ячейки называются grid area.

Ряды в таблицах CSS Grid ограничены горизонтальными линями, а столбцы вертикальными. Каждая линия имеет свой номер, по которому к ней можно обращаться.

[Линии CSS Grid]

Указывая номера четырех линий, ограничивающих по горизонтали и вертикали CSS несколько ячеек в сетке, можно выделить область, в которой эти ячейки будут объединены в одну большую. Задаётся grid area, отдельным классом в правилах CSS через свойства grid-row-start , grid-column-start , grid-row-end , grid-column-end .

Например, объединим в нашей галерее первые две ячейки первого и второго ряда в одну область для большой картинки.

.myarea

Существует и короткий вариант этой записи посредством свойства grid-area .

.myarea < grid-area: 1/1/3/3; >

Потом присвоим этот класс нужному нам элементу, который и займёт всю эту область объединённых ячеек. А мы без особого труда получим галерею в стиле «Metro Windows»

 
.

[Объединение ячеек в CSS Grid]

Z-index

В отличие от HTML-таблиц в CSS Grid ячейки и области расположены не только в плоскости — они могут располагаться ещё и «стопочкой», как слои в «Фотошопе». Каждому слою можно задать номер через специальное свойство z-index . Чем больше номер, тем выше область или ячейка Grid Layout по сравнению с другими ячейками. Это позволяет использовать свойство z-index для эффекта наложения областей и ячеек друг на друга.

.myarea < grid-area: 1/1/3/3; z-index: 4; >

[Эффект перекрывания областей в CSS Grid]

Адаптивная вёрстка

Адаптивная вёрстка веб-страницы предполагает, что шаблон страницы будет гибко трансформироваться в зависимости от размеров и пропорций дисплея. В CSS Grid адаптивная вёрстка включается использованием ключевого слова auto-fill или auto-fit в функции repeat(), которую мы рассматривали выше. И всё.

.mygrid

В результате наша галерея будет автоматически подстраиваться по количеству колонок в зависимости от размеров и разрешения дисплея.

[Адаптивная вёрстка CSS Grid]

Заключение

Чем отличается auto-fill от auto-fit , а также использование новой единицы измерения «фракция», функции «резинового размера» minmax( ) , свойства порядка автоматического заполнения ячеек grid-auto-flow — всё это оставим уже в качестве домашнего задания. Потому что цель этой статьи показать практическую простоту использования CSS Grid Layout. Интуитивная понятность, лаконизм, автоматизация CSS Grid действительно упростит жизнь при создании сайтов.

Практически все современные браузеры — MS Edge, Firefox, Opera, Chrome — хвастают поддержкой CSS Grid Layout Level 1. За исключением, как можно догадаться, MS Internet Explorer. Поэтому разного рода корпоративным веб-дизайнерам, можно сказать, не повезло. Но создателям обычных частных личных сайтов CSS Grid не противопоказан. Тем более, если снова вспомнить историю, Всемирная Паутина начиналась отнюдь не с корпоративных веб-порталов.

Grid как объединить две ячейки

Контейнер Grid располагает вложенные элементы в виде таблицы:

class MainPage : ContentPage < public MainPage() < Grid grid = new Grid < RowDefinitions = < new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >, new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >, new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >>, ColumnDefinitions = < new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >, new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >, new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >> >; grid.Children.Add(new BoxView < Color = Color.Red>, 0, 0); grid.Children.Add(new BoxView < Color = Color.Blue >, 0, 1); grid.Children.Add(new BoxView < Color = Color.Fuchsia >, 0, 2); grid.Children.Add(new BoxView < Color = Color.Teal>, 1, 0); grid.Children.Add(new BoxView < Color = Color.Green >, 1, 1); grid.Children.Add(new BoxView < Color = Color.Maroon >, 1, 2); grid.Children.Add(new BoxView < Color = Color.Olive >, 2, 0); grid.Children.Add(new BoxView < Color = Color.Pink >, 2, 1); grid.Children.Add(new BoxView < Color = Color.Yellow >, 2, 2); Content = grid; > >

Grid in Xamarin

С помощью свойств RowDefinitions и ColumnDefinitions грид создает набор строк и столбцов соответственно. Так, здесь задается три строки и три столбца, то есть в итоге 9 ячеек.

Для высоты строк и ширины столбцов задается значение new GridLength(1, GridUnitType.Star) . Число 1 указывает на то, что данный столбец или строка будет занимать одну долю от всего пространства (так как все три строки или столбца имеют значение 1, то все пространство условно будет равно 1+1+1=3, а одна строка или столбец будет занимать 1/3). А параметр GridUnitType.Star как раз указывает, что размеры будут вычисляться пропорционально.

Чтобы добавить элемент в определенную ячейку, мы указываем номер строки и столбца: grid.Children.Add(new BoxView < Color = Color.Blue >, 0, 1); — элемент BoxView добавляется в ячейку таблицы, которая находится на пересечении первого столбца и второй строки (исчисление начинается с 0, поэтому 1 будет представлять второй столбец или строку)

Употребление Grid в xaml:

Использование звездочки в xaml аналогично параметру GridUnitType.Star . Но кроме пропорциональных размеров мы можем задать автоматические размеры или абсолютные размеры, например:

Аналогичное определение разных типов размеров в коде C#:

Grid grid = new Grid < RowDefinitions = < new RowDefinition < Height = new GridLength(2, GridUnitType.Star) >, new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >, new RowDefinition < Height = 200 >>, ColumnDefinitions = < new ColumnDefinition < Width = GridLength.Auto >, new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >> >;

Отступы

Класс Grid определяет два специальных свойства для создания отступов:

  • ColumnSpacing : определяет пространство между столбцами
  • RowSpacing : определяет пространство между строками
var grid = new Grid < ColumnSpacing = 5 >; grid.ColumnDefnitions.Add(new ColumnDefinition < Width = new GridLength (1, GridUnitType.Star)>); grid.ColumnDefnitions.Add(new ColumnDefinition < Width = new GridLength (1, GridUnitType.Star)>);

Объединение ячеек

С помощью свойства ColumnSpan можно объединить несколько столбцов, а с помощью свойства RowSpan — объединить ячейки:

public class MainPage : ContentPage < public MainPage() < Grid grid = new Grid < RowDefinitions = < new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >, new RowDefinition < Height = new GridLength(1, GridUnitType.Star) >>, ColumnDefinitions = < new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >, new ColumnDefinition < Width = new GridLength(1, GridUnitType.Star) >> >; BoxView redBox = new BoxView < Color = Color.Red >; BoxView blueBox = new BoxView < Color = Color.Blue >; BoxView yellowBox = new BoxView < Color = Color.Yellow >; grid.Children.Add(redBox, 0, 0); grid.Children.Add(blueBox, 1, 0); grid.Children.Add(yellowBox, 0, 1); Grid.SetColumnSpan(yellowBox, 2); // растягиваем на два столбца Content = grid; > >

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *