У меня есть довольно большое приложение tkinter, которое будет специальной системой планирования рабочего персонала для моей работы. Расписание содержит сетку виджетов входа в размере количества дней в месяце, в зависимости от месяца выбранного расписания. В каждой записи руководство будет вводить HR-код человека, который выполняет его повседневную работу.
В зависимости от уровня доступа человека он может войти в систему со своими учетными данными для просмотра и управления ролями персонала или просто просмотрите их в режиме только для чтения, если у них нет необходимого доступа. картинка для контекста:
график работы
В настоящее время пытаюсь сделать так, чтобы при просмотре в режиме «только для чтения» виджеты входа были отключены; однако я хочу, чтобы они по-прежнему были окрашены так, как если бы они были включены. Для этого я использую следующий код с импортированной функцией вне класса. Код класса довольно длинный, поэтому я приложу только соответствующие части для справки:
метод data_loaded в классе ScheduleHrsFrame (фрейм, содержащий записи расписания. Этот метод принимает переданные данные -> список в параметре и применяет их). к записям
def data_loaded(self, data):
"""
Callback function to handle the loaded data.
This method is called by the WorkbookDataLoader thread when the data is loaded.
It updates the existing frames with the loaded data or creates new frames if needed.
"""
# Destroy existing frames before creating new ones
self.destroy_frames()
if self.schedule_type == "Overtime":
frames = []
for i, (name, starting_asking_hours, starting_working_hours, hours_data) in enumerate(data):
frame = HrsMatrixFrame(self.inner_frame, name, self.hdr_date_grid,
self.ranking_frame, starting_asking_hours,
starting_working_hours)
frame.pack(pady=5, fill="x")
frames.append(frame)
for j, (working_hours, asking_hours) in enumerate(hours_data):
working_hours_entry = frame.working_hours_entries[j]
working_hours_entry.delete(0, tk.END)
working_hours_entry.insert(0, working_hours)
asking_hours_entry = frame.asking_hours_entries[j]
asking_hours_entry.delete(0, tk.END)
asking_hours_entry.insert(0, asking_hours)
# Update column sums and labels for Overtime frames
frame.update_column_sums(None)
frame.labels[0].config(text=name)
self.frames = frames
# TODO: May need error handling here
if self.access_level == "read-only":
for frame in self.frames:
lock_widgets(frame)
else:
frames = []
for i, (name, role_data) in enumerate(data):
frame = WorkScheduleMatrixFrame(self.inner_frame, name, self.hdr_date_grid,
self.ranking_frame)
frame.pack(pady=5, fill="x")
frames.append(frame)
for j, role in enumerate(role_data):
entry = frame.crew_member_role_entries[j]
entry.delete(0, tk.END)
entry.insert(0, role)
apply_entry_color_specs(entry, role)
self.work_schedule_frames = frames
# TODO: Entry widgets should disabled but remain appropriately colored
# depending on string value. A bug is preventing the widgets from being
# disabled after the color function is executed. No errors generated.
if self.access_level == "read-only":
for frame in self.work_schedule_frames:
lock_and_color_entry_widgets(frame)
self.display_legend()
self.update_scrollbar()
self.get_labels()
self.adjust_canvas_size()
функции:
def lock_and_color_entry_widgets(container):
"""
Lock (disable) all Entry widgets and apply formatting in the given container.
Args:
container (tk.BaseWidget): The container widget.
"""
for child in container.winfo_children():
if isinstance(child, (tk.Entry, ctk.CTkEntry)):
entry_text = child.get()
bg_color, fg_color = apply_entry_color_specs(child, entry_text)
child.configure(disabledbackground=bg_color, disabledforeground=fg_color)
child.configure(state=tk.DISABLED)
def assignment_code_formatting(frame, label, code_text, color_specs):
"""
Format the WSMatrix Legend labels with the appropriate formatting.
Args:
frame (widget): The passed frame.
label (widget): The passed label.
code_text (str): The text contained in the label.
color_specs (dict): color specifications {code_text:{bg:color, text:color}}
"""
if code_text in color_specs:
frame.configure(fg_color=color_specs[code_text]["frame"])
label.configure(fg_color=color_specs[code_text]["label_bg"], text_color=color_specs[code_text]["label_text"])
else:
frame.configure(fg_color="blue")
label.configure(fg_color="blue", text_color="white")
Постоянные переменные:
COLOR_SPECS = {
"FC":{"frame":"#e26b0a", "label_bg":"#e26b0a", "label_text":"yellow"},
"HT":{"frame":"#c0504d", "label_bg":"#c0504d", "label_text":"white"},
"FTF":{"frame":"#ddd9c4", "label_bg":"#ddd9c4", "label_text":"black"},
"ST":{"frame":"#d9d9d9", "label_bg":"#d9d9d9", "label_text":"black"},
"BB":{"frame":"#0071c4", "label_bg":"#0071c4", "label_text":"white"},
"G":{"frame":"#c4d79b", "label_bg":"#c4d79b", "label_text":"black"},
"R":{"frame":"#ffff00", "label_bg":"#ffff00", "label_text":"black"},
"SC":{"frame":"#b1a0c7", "label_bg":"#b1a0c7", "label_text":"black"},
"SA":{"frame":"#c5d9eb", "label_bg":"#c5d9eb", "label_text":"black"},
"T":{"frame":"#00b050", "label_bg":"#00b050", "label_text":"white"},
"BH":{"frame":"#0097b9", "label_bg":"#0097b9", "label_text":"black"},
"V":{"frame":"#00b0f0", "label_bg":"#00b0f0", "label_text":"white"},
"PC":{"frame":"#00b0ef", "label_bg":"#00b0ef", "label_text":"black"},
"ERT":{"frame":"#ff0000", "label_bg":"#ff0000", "label_text":"yellow"},
"BT":{"frame":"#00ffff", "label_bg":"#00ffff", "label_text":"black"},
"M":{"frame":"#ffffff", "label_bg":"#ffffff", "label_text":"black"},
"JD":{"frame":"#d8e4bc", "label_bg":"#d8e4bc", "label_text":"black"},
"SK":{"frame":"#da9694", "label_bg":"#da9694", "label_text":"black"},
"SW":{"frame":"#4e3b63", "label_bg":"#4e3b63", "label_text":"white"},
"OC":{"frame":"#ffc000", "label_bg":"#ffc000", "label_text":"black"},
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... ot-working