I’m building a GUI with tkinter and was wondering if there is way to set a background color for rows that meet a certain criteria.
An example:
from tkinter import *
from tkinter import filedialog, ttk
import tkinter.font as tkfont
from tkinter.messagebox import OK, INFO, showinfo
import xml.etree.ElementTree as ET
class Detail:
def __init__(self, children):
self.name = children[0].text
self.max_amount = int(children[1].text)
self.curr_amount = 0
self.scanned = 'red'
def __hash__(self):
return hash(self.name)
def __eq__(self, other):
return self.name == other.name
def conv_part_list_to_table(part_list):
res = []
for part in part_list:
res.append((part.name, part.max_amount, part.curr_amount))
return res
def conv_part_list_to_colors(part_list):
res = {}
for i, part in enumerate(part_list):
if part.scanned == 'red':
res[str(i)] = ('white', 'red')
elif part.scanned == 'green':
res[str(i)] = ('white', 'green')
elif part.scanned == 'yellow':
res[str(i)] = ('black', 'yellow')
return res
def saveXmlTree(part_list):
root = ET.Element('data')
for part in part_list:
child1 = ET.Element('part')
name_elem = ET.SubElement(child1, 'name')
name_elem.text = str(part.name)
qnt_elem = ET.SubElement(child1, 'qnt')
qnt_elem.text = str(part.max_amount)
root.append(child1)
tree = ET.ElementTree(root)
tree.write('new_output.xml')
def change_font(event):
font_type = combo_style.get()
font_size = combo_size.get()
font_family = (font_type, font_size) # Настраиваем размер шрифта
#table.config(font=font_family)
text_area.config(font=font_family)
all_check_btn.config(font=font_family)
del_btn.config(font=font_family)
style = ttk.Style()
style.configure("Treeview.Heading", font=(font_type, font_size))
style.configure("Treeview", rowheight=40)
def change_items_font_size(event):
item_font_size = combo_size.get()
custom_font.configure(size=item_font_size)
row_height = custom_font.metrics('linespace')
table.tag_configure("custom_tag", font=custom_font)
def read_xml_file(file_path):
global part_list
try:
tree = ET.parse(file_path)
root = tree.getroot()
parts = root.findall('part')
part_list = []
for child in parts:
part_list.append(Detail(child))
return part_list
except ET.ParseError as e:
print("Ошибка при чтении XML файла:", e)
return None
def display_data_in_table(part_list):
for i, row in enumerate(part_list):
table.insert('', 'end', values=part_list[i], tags='custom_tag')
def open_xml_file_and_display():
file_path = filedialog.askopenfilename(filetypes=[("XML files", "*.xml")])
if file_path:
data = conv_part_list_to_table(read_xml_file(file_path))
colors = conv_part_list_to_colors(read_xml_file(file_path))
if data:
display_data_in_table(data)
apply_colors_to_treeview(table, colors)
def handle_input(part_list):
global cycle_counter, part_counter
name_inp = text_area.get()
text_area.delete(0, 'end')
detail_found = False
for part in part_list:
if part.name == name_inp:
detail_found = True
if part.scanned != 'green':
part.curr_amount += 1
if part.curr_amount == part.max_amount:
part.scanned = 'green'
part_list.remove(part)
part_list.insert(0, part)
cycle_counter += 1
else:
part.scanned = 'yellow'
part_list.remove(part)
part_list.insert(0, part)
part_counter += 1
update_treeview(part_list)
saveXmlTree(part_list)
apply_colors_to_treeview(conv_part_list_to_colors(part_list))
else:
all_scanned()
break
if not detail_found:
not_found()
def update_treeview(part_list):
for record in table.get_children():
table.delete(record)
for data in conv_part_list_to_table(part_list):
table.insert("", 'end', values=data, tags='custom_tag')
def apply_colors_to_treeview(table, rows_colors_dict):
for item, colors in rows_colors_dict.items():
bg_color, fg_color = colors
table.tag_configure(item, background=bg_color, foreground=fg_color)
def not_found():
showinfo(title="DetailSorter", message="Деталь не найдена в базе",
detail="Введите верный код", icon=INFO, default=OK)
def all_scanned():
showinfo(title="DetailSorter", message="Все детали отсканированы",
detail="Выберите другой набор", icon=INFO, default=OK)
window = Tk()
window.resizable(True, True)
window.title('DetailSorter')
part_list = []
font_size = 0
item_font_size = 0
cycle_counter = 0
part_counter = 0
main_menu = Menu(window)
window.config(menu= main_menu)
file_menu = Menu(main_menu, tearoff=0)
file_menu.add_command(label='Открыть', command=open_xml_file_and_display)
file_menu.add_command(label='Сохранить как')
file_menu.add_separator()
file_menu.add_command(label='Выход')
settings_menu = Menu(main_menu, tearoff=0)
settings_menu.add_command(label='Теги для вывода')
help_menu = Menu(main_menu, tearoff=0)
help_menu.add_command(label='Помощь')
help_menu.add_command(label='О программе')
main_menu.add_cascade(label='Файл', menu = file_menu)
main_menu.add_cascade(label='Настройки', menu = settings_menu)
main_menu.add_cascade(label='Справка', menu = help_menu)
combo_frame = Frame(window)
combo_frame.pack(fill=X, padx=20)
font_list = ['Arial', 'Verdana', 'Helvetica', 'Times New Roman', 'Courier New']
combo_style = ttk.Combobox(combo_frame, values= font_list, state='readonly')
combo_style.set(font_list[0])
combo_style.grid(row= 0, column = 0, pady=5, sticky = NW)
font_size_list = [i for i in range(8,73, 2)]
custom_font = tkfont.Font(family="Helvetica", size=12)
combo_size = ttk.Combobox(combo_frame, values= font_size_list, state='readonly')
combo_size.set(font_size_list[2])
combo_size.grid(row= 0, column = 1, pady=5, padx= 5, sticky = NW)
data_frame = Frame(window)
data_frame.pack(expand=True, fill=BOTH)
cols = ('code', 'qnt', 'scanned')
table = ttk.Treeview(data_frame, columns = cols, show= 'headings')
table.pack(expand=True, fill=BOTH, padx=20, pady=5)
for column in table['columns']:
table.column(column, anchor=CENTER)
table.heading('code', text='Кодировка')
table.heading('qnt', text='Количество')
table.heading('scanned', text='Отмечено')
table.tag_configure("custom_tag", font=custom_font)
combo_style.bind("<<ComboboxSelected>>", change_font)
combo_size.bind("<<ComboboxSelected>>", change_font, add='+')
combo_size.bind("<<ComboboxSelected>>", change_items_font_size, add='+')
entry_btn_frame = Frame(window)
entry_btn_frame.pack(fill=X, padx=20, pady=20)
text_area = Entry(entry_btn_frame)
text_area.pack(side=LEFT, expand=True, fill=X)
text_area.bind("<Return>", lambda event: handle_input(part_list))
all_check_btn = Button(entry_btn_frame, text='Отметить все')
all_check_btn.pack(side=RIGHT)
del_btn = Button(entry_btn_frame, text='Удалить')
del_btn.pack(side=RIGHT, padx=5)
window.mainloop()
The conv_part_list_to_colors function creates a dictionary with the colors to color the strings in table = ttk.treeview.The apply_colors_to_treeview function applies the previously generated dictionary with colors to my table. However, the problem is that in practice this does not work. Please help me find the error
New contributor
Bruh Moment is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.