Source code for interface.data_collection

"""
Frontend Data Collection Page File for AGE-ABM Visual Interface
@Author Meghan Ireland
@Co-Authors Max Hall and Matthew Fleischman

"""

import tkinter as tk
from tkinter import ttk
import customtkinter

[docs] class DataCollection: """Defines widgets and functionality of data collection page. """ def __init__(self, ec_app_ui): """Creates widgets for the Data Collector class. """ self.ec_app_ui = ec_app_ui self.ids = tk.BooleanVar(self.ec_app_ui.root) self.collect_all_agents = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_mean = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_total = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_min = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_max = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_var = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_std = tk.BooleanVar(self.ec_app_ui.root) self.radio_var_med = tk.BooleanVar(self.ec_app_ui.root) self.pos = tk.BooleanVar(self.ec_app_ui.root) self.added_components = [] self.temp_components = [] ### Label frames ### self.labelframe_collectors_components = tk.LabelFrame(self.ec_app_ui.page_frame , font=self.ec_app_ui.font2, text="Add Components", height = self.ec_app_ui.entry_width , width = 4*self.ec_app_ui.entry_width, bg=self.ec_app_ui.frame_colour , fg = self.ec_app_ui.button_font_colour) self.labelframe_collectors_agents = tk.LabelFrame(self.ec_app_ui.page_frame , font=self.ec_app_ui.font2, text="Agent", height = 3*self.ec_app_ui.entry_width//5 , width = 4*self.ec_app_ui.entry_width, bg=self.ec_app_ui.frame_colour , fg = self.ec_app_ui.button_font_colour) ### Frames ### self.frame_small = tk.Frame(master = self.ec_app_ui.page_frame, bg=self.ec_app_ui.frame_colour , height = self.ec_app_ui.button_height , width = 3*self.ec_app_ui.button_width//2) ### Title ### self.label_collectors_title = tk.Label(self.ec_app_ui.title_frame, text="Data Collector" , font=self.ec_app_ui.font1, bg=self.ec_app_ui.title_colour , fg=self.ec_app_ui.label_text_colour) self.label_collectors_add_agent_title = tk.Label(self.ec_app_ui.title_frame , text="Add Agent of Interest", font=self.ec_app_ui.font1 , bg=self.ec_app_ui.title_colour, fg=self.ec_app_ui.label_text_colour) ### Labels ### self.label_collectors_agent = tk.Label(self.labelframe_collectors_agents , text="Select Agent", font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour, fg=self.ec_app_ui.label_text_colour) self.label_collectors_all_agents = tk.Label(self.labelframe_collectors_agents , text="Collect Total Count?", font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour, fg=self.ec_app_ui.label_text_colour) self.label_collectors_positions = tk.Label(self.labelframe_collectors_agents , text="Collect Positions?", font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour, fg=self.ec_app_ui.label_text_colour) self.label_collectors_collection_method = tk.Label(self.labelframe_collectors_agents , text="Select Collection Methods:", font=self.ec_app_ui.font2, justify="left" , bg=self.ec_app_ui.frame_colour, fg=self.ec_app_ui.label_text_colour) self.label_collectors_individual = tk.Label(self.labelframe_collectors_agents , text="Collect Component Values Per Individual Agent ID",font=self.ec_app_ui.font2 , justify="left",bg=self.ec_app_ui.frame_colour,fg=self.ec_app_ui.label_text_colour) self.label_collectors_component = tk.Label(self.labelframe_collectors_components , text="Select Component of Interest", font=self.ec_app_ui.font2 , justify="left",bg=self.ec_app_ui.frame_colour,fg=self.ec_app_ui.label_text_colour) ### Buttons ### self.button_collectors_add = customtkinter.CTkButton(self.frame_small , hover_color=self.ec_app_ui.highlight_colour,text="Add" , command=self.btn_collectors_add,fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, height=self.ec_app_ui.button_height , width=self.ec_app_ui.button_width/2) self.button_collectors_remove = customtkinter.CTkButton(self.frame_small , hover_color=self.ec_app_ui.highlight_colour,text="Remove" , command=self.btn_collectors_remove, fg_color=self.ec_app_ui.comp_btn_colour , font = self.ec_app_ui.font2, height=self.ec_app_ui.button_height , width=self.ec_app_ui.button_width/2) self.button_collectors_save_component = customtkinter.CTkButton(self.labelframe_collectors_components , text="Add", command=self.btn_collectors_component_save , fg_color=self.ec_app_ui.comp_btn_colour, font = self.ec_app_ui.font2 , hover_color=self.ec_app_ui.highlight_colour , height = self.ec_app_ui.entry_height, width=self.ec_app_ui.entry_width) self.button_collectors_save = customtkinter.CTkButton(self.ec_app_ui.page_frame,text="Save" , command=self.btn_collectors_save, fg_color=self.ec_app_ui.comp_btn_colour , hover_color=self.ec_app_ui.highlight_colour , font = self.ec_app_ui.font2, height = self.ec_app_ui.entry_height , width=self.ec_app_ui.entry_width) ### Check Buttons ### self.checkbox_collectors_agent_id = customtkinter.CTkCheckBox(self.labelframe_collectors_agents , border_color=self.ec_app_ui.tbl_colour,hover_color=self.ec_app_ui.highlight_colour , variable=self.collect_all_agents, text = "", fg_color = self.ec_app_ui.check_color) self.checkbox_collectors_all_agents = customtkinter.CTkCheckBox(self.labelframe_collectors_agents , border_color=self.ec_app_ui.tbl_colour,hover_color=self.ec_app_ui.highlight_colour , variable=self.ids, text = "", fg_color = self.ec_app_ui.check_color) self.checkbox_collectors_positions = customtkinter.CTkCheckBox(self.labelframe_collectors_agents , border_color=self.ec_app_ui.tbl_colour,hover_color=self.ec_app_ui.highlight_colour , variable=self.pos, text = "", fg_color = self.ec_app_ui.check_color) ### Switch Buttons ### self.switch_collectors_mean = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_mean, text = "Mean" , font = self.ec_app_ui.font2, text_color = self.ec_app_ui.button_font_colour , fg_color = self.ec_app_ui.off_switch) self.switch_collectors_total = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_total , text = "Total", font = self.ec_app_ui.font2 , text_color = self.ec_app_ui.button_font_colour, fg_color = self.ec_app_ui.off_switch) self.switch_collectors_min = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour , variable=self.radio_var_min, text = "Min" , font = self.ec_app_ui.font2, text_color = self.ec_app_ui.button_font_colour , fg_color = self.ec_app_ui.off_switch) self.switch_collectors_max = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_max , text = "Max", font = self.ec_app_ui.font2 , text_color = self.ec_app_ui.button_font_colour, fg_color = self.ec_app_ui.off_switch) self.switch_collectors_var = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_var , text = "Variance", font = self.ec_app_ui.font2 , text_color = self.ec_app_ui.button_font_colour, fg_color = self.ec_app_ui.off_switch) self.switch_collectors_std = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_std , text = "Std Dev", font = self.ec_app_ui.font2 , text_color = self.ec_app_ui.button_font_colour, fg_color = self.ec_app_ui.off_switch) self.switch_collectors_median = customtkinter.CTkSwitch(self.labelframe_collectors_agents , progress_color=self.ec_app_ui.tbl_colour, variable=self.radio_var_med , text = "Median", font = self.ec_app_ui.font2 , text_color = self.ec_app_ui.button_font_colour, fg_color = self.ec_app_ui.off_switch) ### Drop down ### self.dropdown_collectors_agents = customtkinter.CTkOptionMenu(self.labelframe_collectors_agents , values = [], fg_color = self.ec_app_ui.dropdown_menu_color , button_color=self.ec_app_ui.comp_btn_colour, command = self.on_selected_agent , button_hover_color= self.ec_app_ui.highlight_colour , height = self.ec_app_ui.entry_height, width=self.ec_app_ui.entry_width , font = self.ec_app_ui.font2) self.dropdown_collectors_agents.set("Select Agent") self.dropdown_collectors_components = customtkinter.CTkOptionMenu(self.labelframe_collectors_components , values = [], fg_color = self.ec_app_ui.dropdown_menu_color , button_color=self.ec_app_ui.comp_btn_colour , button_hover_color= self.ec_app_ui.highlight_colour , height = self.ec_app_ui.entry_height, width=self.ec_app_ui.entry_width , font = self.ec_app_ui.font2) self.dropdown_collectors_components.set("Select Component") self.dropdown_collectors_components.bind("<<ComboboxSelected>>", self.on_selected_component) ### Table for collector systems ### self.collectors_arr = [] self.collectors_frame = customtkinter.CTkFrame(self.ec_app_ui.page_frame , fg_color=self.ec_app_ui.tbl_colour , height = 300, width = 580) self.vertical_scroll3 = tk.Scrollbar(self.collectors_frame) self.collectors_tbl = ttk.Treeview(self.collectors_frame, padding = 5, height = 8 , yscrollcommand=self.vertical_scroll3.set) self.collectors_tbl['columns'] = ('Name', 'Reason for Collection') self.collectors_tbl.column("#0", width=0, stretch='NO') self.collectors_tbl.column("Name",anchor='center', width=190) self.collectors_tbl.column("Reason for Collection",anchor='center',width=380) self.collectors_tbl.heading("#0",text="",anchor='center') self.collectors_tbl.heading("Name",text="Name",anchor='center') self.collectors_tbl.heading("Reason for Collection", text="Collected Components",anchor='center') self.collectors_tbl.bind("<<TreeviewSelect>>", self.display_selected_collectors) ### Table for components ### self.ad_comp_frame = customtkinter.CTkFrame(self.ec_app_ui.page_frame , fg_color=self.ec_app_ui.tbl_colour , height = 150 , width = self.ec_app_ui.window_width/5) self.vertical_scroll = tk.Scrollbar(self.ad_comp_frame) self.ad_comp_tbl = ttk.Treeview(self.ad_comp_frame,padding = 5,height=4 , yscrollcommand=self.vertical_scroll.set) self.ad_comp_tbl['columns'] = 'Name' self.ad_comp_tbl.column("#0", width=0, stretch='NO') self.ad_comp_tbl.column("Name",anchor='center', width=250) self.ad_comp_tbl.heading("#0",text="",anchor='center') self.ad_comp_tbl.heading("Name",text="Components",anchor='center') self.selected_collector = "" ### Data Tab ###
[docs] def clear_collectors(self): """Clears the data collection page """ self.collectors_frame.grid_forget() self.collectors_tbl.pack_forget() self.dropdown_collectors_agents.grid_forget() self.dropdown_collectors_components.grid_forget() self.switch_collectors_max.grid_forget() self.switch_collectors_min.grid_forget() self.switch_collectors_total.grid_forget() self.switch_collectors_mean.grid_forget() self.labelframe_collectors_components.grid_forget() self.labelframe_collectors_agents.grid_forget() self.label_collectors_title.grid_forget() self.label_collectors_add_agent_title.grid_forget() self.label_collectors_agent.grid_forget() self.label_collectors_all_agents.grid_forget() self.label_collectors_collection_method.grid_forget() self.label_collectors_individual.grid_forget() self.label_collectors_component.grid_forget() self.button_collectors_add.grid_forget() self.button_collectors_remove.grid_forget() self.button_collectors_save_component.grid_forget() self.checkbox_collectors_agent_id.grid_forget() self.checkbox_collectors_all_agents.grid_forget() self.ad_comp_tbl.grid_forget() self.ad_comp_frame.grid_forget() self.button_collectors_save.grid_forget() self.frame_small.grid_forget()
[docs] def data_tab_btn(self): """This method is called when the user clicks on the Data Collection button """ self.ec_app_ui.clear_all() self.added_components = [] self.temp_components = [] self.selected_collector = "" ### Reset switches ### self.switch_collectors_mean.deselect() self.switch_collectors_total.deselect() self.switch_collectors_min.deselect() self.switch_collectors_max.deselect() self.switch_collectors_std.deselect() self.switch_collectors_var.deselect() self.checkbox_collectors_positions.deselect() ### Table ### self.update_tbl_collectors() self.collectors_frame.grid(row = 0, column = 0, columnspan=3 , pady = (40,5)) self.vertical_scroll3.pack(side="right", fill="y", padx=(0,5), pady=5) self.collectors_tbl.pack(fill = "x", padx = (5,0), pady = 5) ### Add, edit, remove buttons ### self.frame_small.grid(row = 1, column = 0, columnspan=3) self.button_collectors_add.grid(row = 0,column = 0, sticky = "W", padx = 120) self.button_collectors_remove.grid(row = 0, column = 1, sticky = "E", padx = 120) ### Title ### self.label_collectors_title.grid(row = 0, column = 0)
[docs] def btn_collectors_add(self): """Method called when user clicks the add button. """ self.update_tbl() self.ec_app_ui.clear_all() self.checkbox_collectors_all_agents.deselect() self.checkbox_collectors_agent_id.deselect() self.dropdown_collectors_agents.configure(self , values = self.ec_app_ui.new_model.get_list_agents()) ### Page title ### self.label_collectors_add_agent_title.grid(row = 0, column = 0) ### Page Frame ### self.labelframe_collectors_agents.grid_propagate(0) self.labelframe_collectors_agents.configure(height = self.ec_app_ui.entry_width , width = 4*self.ec_app_ui.entry_width) self.labelframe_collectors_agents.grid(row = 0, column = 0, columnspan=3) ### Select Agent ### agents = self.ec_app_ui.new_model.get_list_agents() self.label_collectors_agent.grid(row = 0, column = 0, pady = 5, sticky="W", columnspan=6 , padx = 5) self.dropdown_collectors_agents.configure(values = agents) self.dropdown_collectors_agents.set("Select Agent") self.dropdown_collectors_agents.grid(row = 0, column = 6, pady = 5, sticky="E", columnspan=1 , padx = 13 ) ### Collect count ### self.label_collectors_all_agents.grid(row = 1, column = 0, pady = 5, sticky="W", padx = 5 , columnspan=6) self.checkbox_collectors_all_agents.grid(row = 1, column = 6, pady = 5, sticky="W" , padx=16) ### Grid World ### if self.ec_app_ui.new_model.get_model_details().get_gridworld(): self.label_collectors_positions.grid(row = 2, column = 0, pady = 5, sticky="W", padx = 5 , columnspan=6) self.checkbox_collectors_positions.grid(row = 2, column = 6, pady = 5, sticky="W" , padx=16) self.labelframe_collectors_agents.configure(height = 9*self.ec_app_ui.entry_width/8) ### Collection Method ### self.label_collectors_collection_method.grid(row = 3, column = 0, pady = 5, sticky="W" , columnspan=5, padx = 5) self.switch_collectors_mean.grid(row = 4, column = 0, padx = 5, pady = 5, sticky="W") self.switch_collectors_total.grid(row = 4, column = 1, padx = 5, pady = 5, sticky="W") self.switch_collectors_min.grid(row = 4, column = 2, padx = 5, pady = 5, sticky="W") self.switch_collectors_max.grid(row = 4, column = 3, padx = 5, pady = 5, sticky="W") self.switch_collectors_var.grid(row = 4, column = 4, padx = 5, pady = 5, sticky="W") self.switch_collectors_std.grid(row = 4, column = 5, padx = 5, pady = 5, sticky="W") self.switch_collectors_median.grid(row = 4, column = 6, padx = 5, pady = 5, sticky="W") ### Collect data per ID ### self.label_collectors_individual.grid(row = 5, column = 0, pady = 5, sticky="W" , columnspan=5, padx = 5) self.checkbox_collectors_agent_id.grid(row = 5, column = 6, columnspan = 1, pady = 5 , sticky="W", padx=16) ### Frame ### self.labelframe_collectors_components.configure(height = self.ec_app_ui.entry_width//2 , width = 4*self.ec_app_ui.entry_width) self.labelframe_collectors_components.grid_propagate(0) self.labelframe_collectors_components.grid(row = 1, column = 0, columnspan=3) ### Select Component ### self.dropdown_collectors_components.configure(self , values = self.ec_app_ui.new_model.get_list_components()) self.dropdown_collectors_components.set("Select Components") self.label_collectors_component.grid(row = 1, column = 0, pady = 5, sticky="W" , columnspan=1, padx = 5) self.dropdown_collectors_components.grid(row = 1, column = 1, columnspan = 1, pady = 5 , sticky="W", padx = (428,5)) ### Add Button ### self.button_collectors_save_component.grid(row = 5, column = 1, columnspan = 1, sticky="W" , padx = (428,5)) ### Save Button ### self.button_collectors_save.grid(row = 2, column = 2,pady = 5, sticky = "NW") ### Table ### self.ad_comp_frame.grid(row = 2, column = 0, pady = 5,sticky="E") self.vertical_scroll.pack(side="right", fill="y", padx=(0,5), pady=5) self.ad_comp_tbl.pack(fill = "both", padx = (5,0), pady = 5)
[docs] def btn_collectors_component_save(self): """Saves the information about a component being saved """ # Reset drop down self.temp_components.remove(self.dropdown_collectors_components.get()) self.added_components.append(self.dropdown_collectors_components.get()) self.dropdown_collectors_components.set("Select Component") self.dropdown_collectors_components.configure(values = self.temp_components) self.update_tbl()
[docs] def btn_collectors_save(self): """Saves the data collector """ if self.checkbox_collectors_all_agents.get(): count = True else: count = False if self.checkbox_collectors_agent_id.get(): ids = True else: ids = False if self.checkbox_collectors_positions.get(): pos = True else: pos = False self.ec_app_ui.new_model.add_agent_of_interest(self.dropdown_collectors_agents.get(), self.added_components, count, pos, ids, self.radio_var_mean.get(), self.radio_var_med.get(), self.radio_var_total.get(), self.radio_var_max.get(), self.radio_var_min.get(), self.radio_var_var.get(), self.radio_var_std.get()) self.data_tab_btn()
[docs] def btn_collectors_edit(self): """Method called when user clicks the edit button. """
[docs] def display_selected_collectors(self, *args): """Gets the collector in the table that was selected """ selected_items = self.collectors_tbl.selection() if selected_items: selected_item = self.collectors_tbl.selection()[0] self.selected_collector = self.collectors_tbl.item(selected_item)['values'][0]
[docs] def btn_collectors_remove(self): """Method called when user clicks the remove button. """ self.ec_app_ui.new_model.remove_agent_of_interest(self.selected_collector) self.update_tbl_collectors()
[docs] def on_selected_agent(self,*args): """When user selects the agent """ agent = self.dropdown_collectors_agents.get() self.dropdown_collectors_components.configure(values = []) self.dropdown_collectors_components.set("Select Component") self.temp_components = self.ec_app_ui.new_model.get_agent(agent).get_given_components() agent_given_components = self.ec_app_ui.new_model.get_agent(agent).get_given_components() self.dropdown_collectors_components.configure(values = agent_given_components)
[docs] def on_selected_component(self,*args): """Required method """
[docs] def update_tbl(self): """Updates the component table """ id7 = 0 components = self.added_components for comp in self.ad_comp_tbl.get_children(): self.ad_comp_tbl.delete(comp) for compo in components: self.ad_comp_tbl.insert(parent='',index='end',iid=id7,text='',values=(compo,)) id7+=1
[docs] def update_tbl_collectors(self): """Updates the data collectors table """ agnet_tbl_id = 0 agents = self.ec_app_ui.new_model.get_list_agents_of_interest() for child in self.collectors_tbl.get_children(): self.collectors_tbl.delete(child) for agent in agents: comps = self.ec_app_ui.new_model.get_agent_of_interest(agent).get_comp_of_interest() str_comps = "" number_of_comps = len(comps) for i in range(number_of_comps): if i != 0: str_comps = str_comps +", " + comps[i] else: str_comps = comps[i] self.collectors_tbl.insert(parent='',index='end',iid=agnet_tbl_id,text='' , values=(agent,str_comps)) agnet_tbl_id+=1