Closed nutanlade closed 7 months ago
@nutanlade
import flet as ft
def main(page: ft.Page):
page.add(
ft.DataTable(border=ft.border.all(2, "red"),
border_radius=10,
horizontal_margin=10,
vertical_lines=ft.border.BorderSide(3, "red"),
horizontal_lines=ft.border.BorderSide(1, "red"),
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
ft.DataColumn(ft.Text("Age"), numeric=True),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(
ft.Container(
content=ft.Text("Alice"),
padding=ft.padding.all(0),
bgcolor="red",
width=float("inf")
)
),
ft.DataCell(ft.Text("Smith")),
ft.DataCell(ft.Text("43")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red",width=float("inf"))),
ft.DataCell(ft.Text("Brown")),
ft.DataCell(ft.Text("19")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red",width=float("inf"))),
ft.DataCell(ft.Text("Wong")),
ft.DataCell(ft.Text("25")),
],
),
],
),
)
ft.app(target=main)
Thanks @burhansvural for your help. I have tried but still some white space is left as below attached image. I need whole cell to be in red color. Made some modifications to your code. Please refer the same below.
def main(page: ft.Page):
page.add(
ft.DataTable(border=ft.border.all(2, "red"),
border_radius=10,
horizontal_margin=20,
vertical_lines=ft.border.BorderSide(3, "red"),
horizontal_lines=ft.border.BorderSide(1, "red"),
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
ft.DataColumn(ft.Text("Age"), numeric=True),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(
ft.Container(
content=ft.Text("Alice"),
padding=ft.padding.all(10),
bgcolor="red",
width=float("inf")
)
),
ft.DataCell(ft.Text("Smith")),
ft.DataCell(ft.Text("43")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red",width=float("inf"))),
ft.DataCell(ft.Text("Brown")),
ft.DataCell(ft.Text("19")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red",width=float("inf"))),
ft.DataCell(ft.Text("Wong")),
ft.DataCell(ft.Text("25")),
],
),
],
),
)
ft.app(target=main)```
@nutanlade
import flet as ft
def main(page: ft.Page):
page.add(
ft.DataTable(
border=ft.border.all(2, "red"),
vertical_lines=ft.border.BorderSide(3, "red"),
horizontal_lines=ft.border.BorderSide(1, "red"),
column_spacing=2,
horizontal_margin=0,
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
ft.DataColumn(ft.Text("Age"), numeric=True),
],
rows=[
ft.DataRow(
selected=True,
cells=[
ft.Row(
width=float("inf"),
expand=True,
controls=[
ft.Container(
content=ft.Text("Alice",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
expand=True,
bgcolor=ft.colors.RED,
alignment=ft.alignment.center
)
]
),
ft.DataCell(ft.Text("Smith")),
ft.DataCell(ft.Text("43")),
],
),
],
),
)
ft.app(target=main)
or
import flet as ft
def main(page: ft.Page):
page.add(
ft.DataTable(
border=ft.border.all(2, "red"),
vertical_lines=ft.border.BorderSide(3, "red"),
horizontal_lines=ft.border.BorderSide(1, "red"),
column_spacing=2,
horizontal_margin=0,
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
ft.DataColumn(ft.Text("Age"), numeric=True),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(ft.Container(
content=ft.Text("Alice",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
expand=True,
bgcolor=ft.colors.RED,
alignment=ft.alignment.center
)),
ft.DataCell(ft.Text("Smith")),
ft.DataCell(ft.Text("43")),
],
),
],
),
)
ft.app(target=main)
or write a new class extend DataTable
There is no proper solution for this, from what I see. I found this SO suggestion which suggests to use linear gradient to paint the column.
Example below:
import flet as ft
def main(page: ft.Page):
page.add(
ft.DataTable(border=ft.border.all(2, "red"),
border_radius=10,
horizontal_margin=20,
vertical_lines=ft.border.BorderSide(3, "red"),
horizontal_lines=ft.border.BorderSide(1, "red"),
gradient=ft.LinearGradient(
begin=ft.alignment.center_left,
end=ft.alignment.center_right,
stops=[0.4, 0.4],
colors=[ft.colors.RED, ft.colors.TRANSPARENT],
),
columns=[
ft.DataColumn(ft.Text("First name")),
ft.DataColumn(ft.Text("Last name")),
ft.DataColumn(ft.Text("Age"), numeric=True),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(
ft.Container(
content=ft.Text("Alice"),
padding=ft.padding.all(10),
bgcolor="red",
width=float("inf")
)
),
ft.DataCell(ft.Text("Smith")),
ft.DataCell(ft.Text("43")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red", expand=True)),
ft.DataCell(ft.Text("Brown")),
ft.DataCell(ft.Text("19")),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(ft.Text("Alice"), padding=ft.padding.all(0), bgcolor="red",width=float("inf"))),
ft.DataCell(ft.Text("Wong")),
ft.DataCell(ft.Text("25")),
],
),
],
),
)
ft.app(target=main)
@nutanlade
This is a solution :
import flet as ft
dt=ft.DataTable(
border=ft.border.all(2, ft.colors.RED_200),
vertical_lines=ft.border.BorderSide(3, ft.colors.RED_200),
horizontal_lines=ft.border.BorderSide(1, ft.colors.RED_200),
column_spacing=3,
horizontal_margin=0,
columns=[
ft.DataColumn(ft.Text("First name",width=120,text_align=ft.TextAlign.CENTER)),
ft.DataColumn(ft.Text("Last name",width=120,text_align=ft.TextAlign.CENTER)),
ft.DataColumn(ft.Text("Age",width=120,text_align=ft.TextAlign.CENTER), numeric=True),
],
rows=[
ft.DataRow(
cells=[
ft.DataCell(ft.Container(
content=ft.Text("Alice",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
bgcolor=ft.colors.RED,
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("Smith",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("43",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(
content=ft.Text("Alice",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
bgcolor=ft.colors.RED,
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("Brown",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("19",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
],
),
ft.DataRow(
cells=[
ft.DataCell(ft.Container(
content=ft.Text("Alice",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
bgcolor=ft.colors.RED,
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("Wong",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
ft.DataCell(ft.Container(
content=ft.Text("25",text_align=ft.TextAlign.CENTER,width=float("inf")),
height=float("inf"),
width=float("inf"),
alignment=ft.alignment.center
)),
],
),
],
)
def main(page: ft.Page):
page.window_width=500
page.add(
ft.SafeArea(
content=ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
vertical_alignment=ft.CrossAxisAlignment.CENTER,
expand=True,
controls=[dt]
)
)
)
page.update()
ft.app(target=main)
Thanks @burhansvural and @ndonkoHenri for the help. @burhansvural your last solution worked as expected.
How to change DataCell color on_tap?
import flet as ft
import calendar
import json
# Список сотрудников
employees = ["Сотрудник 1", "Сотрудник 2", "Сотрудник 3", "Сотрудник 4"]
# Статусы
statuses = {
"P": ("Должен работать", ft.colors.GREEN),
"O": ("Отпуск или больничный", ft.colors.RED),
"F": ("Свободен", ft.colors.BLUE),
"N": ("Нет данных", ft.colors.WHITE)
}
days = {0: "ПН", 1: "ВТ", 2: "СР", 3: "ЧТ", 4: "ПТ", 5: "СБ", 6: "ВС"}
# Состояние выбранных ячеек
selected_cells = []
# Хранение данных таблицы
table_data = {}
def generate_columns():
columns = [ft.DataColumn(ft.Text("Сотрудник"))]
for week in calendar.monthcalendar(2024, 7):
n = 0
for day in week:
if day != 0:
columns.append(ft.DataColumn(ft.Column(controls=[
ft.Text(str(day)),
ft.Text(days[n])
])))
n += 1
return columns
def on_tap(e):
cell = e.control
print(e.page)
if cell in selected_cells:
selected_cells.remove(cell)
cell.bgcolor = None
else:
selected_cells.append(cell)
cell.bgcolor = ft.colors.YELLOW
e.page.update()
def generate_rows():
rows = []
for employee in employees:
cells = [ft.DataCell(ft.Text(employee))]
for _ in range(calendar.monthrange(2024, 7)[1]):
cell = ft.DataCell(ft.Text("N", bgcolor=ft.colors.RED), on_tap=on_tap)
cells.append(cell)
rows.append(ft.DataRow(cells=cells))
return rows
def main(page: ft.Page):
page.title = "Table Test"
def set_status(status):
status_text, color = statuses[status]
for cell in selected_cells:
cell.content.value = status
cell.bgcolor = color
cell.update()
selected_cells.clear()
save_table_data()
page.update()
def save_table_data():
for row in table.rows:
employee = row.cells[0].content.value
table_data[employee] = [cell.content.value for cell in row.cells[1:]]
with open('table_data.json', 'w', encoding='utf-8') as f:
json.dump(table_data, f, ensure_ascii=False, indent=4)
# Создаем кнопки для статусов
status_buttons = ft.Row(
controls=[
ft.ElevatedButton(text=val, on_click=lambda e, s=key: set_status(s)) for key, (val, _) in statuses.items()
]
)
table = ft.DataTable(
columns=generate_columns(),
rows=generate_rows()
)
page.add(
ft.Column(
controls=[
status_buttons,
ft.ListView(
controls=[table]
)
]
)
)
ft.app(target=main)
How to change DataCell color on_tap?
DataCell does not have bgcolor property. Instead, if the control used in the datacell has a bgcolor property, it is assigned to the bgcolor property of that control. Then, it is activated on the screen by typing e.control.update().
1.===========================================
def on_tap(e):
cell = e.control
# print(e.page)
print("сработало событие ontap.")
# if cell in selected_cells:
# selected_cells.remove(cell)
# cell.bgcolor = None
# else:
# selected_cells.append(cell)
# cell.bgcolor = ft.colors.YELLOW
e.control.content.bgcolor=ft.colors.YELLOW
e.control.update()
# e.page.update()
def on_tap(e):
cell = e.control
# print(e.page)
print("сработало событие ontap.")
if cell in selected_cells:
selected_cells.remove(cell)
cell.content.bgcolor = ft.colors.TRANSPARENT
e.control.update()
else:
selected_cells.append(cell)
cell.content.bgcolor = ft.colors.YELLOW
e.control.update()
I want to have a data cell background to be red color. I have multiple ways to set but only background color of text is red rest all is white. I tried different combinations with padding margin but still no luck. Can someone help in solving the issue? Below is the sample code and screenshot of the result. I want whole cell should be in red instead of white.
`import flet as ft
def main(page: ft.Page): page.add( ft.DataTable(border=ft.border.all(2, "red"), border_radius=10, horizontal_margin=10, vertical_lines=ft.border.BorderSide(3, "red"), horizontal_lines=ft.border.BorderSide(1, "red"), columns=[ ft.DataColumn(ft.Text("First name")), ft.DataColumn(ft.Text("Last name")), ft.DataColumn(ft.Text("Age"), numeric=True), ], rows=[ ft.DataRow( cells=[ ft.DataCell(ft.Container(ft.Text("Alice"), expand=True, padding=ft.padding.all(0), bgcolor="red")), ft.DataCell(ft.Text("Smith")), ft.DataCell(ft.Text("43")), ], ), ft.DataRow( cells=[ ft.DataCell(ft.Container(ft.Text("Alice"), expand=True, padding=ft.padding.all(0), bgcolor="red")), ft.DataCell(ft.Text("Brown")), ft.DataCell(ft.Text("19")), ], ), ft.DataRow( cells=[ ft.DataCell(ft.Container(ft.Text("Alice"), expand=True, padding=ft.padding.all(0), bgcolor="red")), ft.DataCell(ft.Text("Wong")), ft.DataCell(ft.Text("25")), ], ), ], ), )
ft.app(target=main, view=ft.WEB_BROWSER, port=8502)`