Source code for ecapp

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

"""

import tkinter as tk
import customtkinter
from interface.agents import Agents
from interface.components import Components
from interface.model_details import Details
from interface.data_collection import DataCollection
from interface.compile import Compile
from interface.home import Home
from interface.execute import Execute
from interface.edit_attributes import EditAttributes
from interface.libraries import Libraries
from interface.systems import Systems
from interface.visualisation import Visualisation

[docs] class ECAppUI: """Defines widgets and functionality of main tab buttons. """ def __init__(self): """Creates the main variables used for the application. """ # Create the main application window self.collapsed = False self.frame_colour = '#1E1E1E' self.entry_colour = '#434644' self.title_colour = '#252526' self.highlight_colour = "#7CA188" self.root = tk.Tk() self.root.title("EC-App") self.root.configure(bg="#FFFFFF") taskbar = 50 screen_width = self.root.winfo_screenwidth() screen_height = self.root.winfo_screenheight() logo_picture = tk.PhotoImage(file = 'logo.png') self.root.iconphoto(False, logo_picture) # Calculate the size and position for the full-screen window self.window_width = screen_width self.window_height = screen_height - taskbar - 40 self.panel_height = self.window_height self.panel_width = self.window_width/4 self.page_frame_height = self.window_height self.page_frame_width = self.window_width - self.panel_width x_pos = 0 self.collapse_bar_color = "#3A644E" y_pos = 0 self.root.geometry(f"{self.window_width}x{self.window_height}+{x_pos}+{y_pos}") ### Variables ### self.button_height = 50 self.button_width = self.window_width/4 self.frame_btn_width = self.panel_width - 4 self.tbl_colour = "#C6EBCA" self.panel_colour = "#323233" self.label_colour1 = "#5b7e84" self.dropdown_menu_color = "#86AD99" self.home_colour = "#16634B" self.label_text_colour = "white" self.entry_text_colour = "white" self.button_colour = "#0EA374" self.check_color = "#0EA374" self.space_btw_btns = 5 self.font1 = customtkinter.CTkFont(family="Montserrat", size=25) #self.font1=("Verdana", 20) self.font2 = customtkinter.CTkFont(family="Montserrat", size=18) self.font_menu = customtkinter.CTkFont(family="Montserrat", size=16) #self.font2=("Verdana", 16) #self.font3_underlined = Font(family="Verdana", size=16, underline=True) self.font3_underlined = customtkinter.CTkFont(family="Montserrat", size=16, underline=True) self.button_font_colour = "white" self.tbl_font_colour = "black" self.label_pos = 50 self.under_tbl = self.window_height/2 + 40 self.btn_comp_width = self.window_width//12 self.comp_btn_colour = "#53a57d" self.off_switch = "#F57872" self.menu_font_colour = "white" self.entry_height = 30 self.entry_width = self.entry_height*8 self.page_frame = tk.Frame(master = self.root, bg=self.frame_colour , height = 7*self.page_frame_height/8 , width = self.page_frame_width) self.page_frame.grid_columnconfigure(0, weight=1) self.page_frame.grid_columnconfigure(1, weight=1) self.page_frame.grid_columnconfigure(2, weight=1) self.page_frame.grid_propagate(0) self.title_frame = tk.Frame(master = self.root, bg=self.title_colour , height = self.page_frame_height/8 , width = self.page_frame_width) self.title_frame.grid_propagate(0) self.title_frame.grid_rowconfigure(0, weight=1) self.title_frame.grid_columnconfigure(0, weight=1) self.left_frame = tk.Frame(master = self.root, bg = self.panel_colour , height = self.panel_height , width = self.panel_width) self.left_frame.grid_propagate(0) self.collapser_frame = tk.Frame(master = self.root, bg = self.collapse_bar_color , height=self.window_height, width=6) self.title_position_row = 0 self.title_position_column = 0 self.title_position_pady = 25 self.title_position_padx = 350 ### Variables for model ### self.new_model = None # Creates model_env object self.visual = None self.components = Components(self) self.agents = Agents(self) self.edit_attributes = EditAttributes(self) self.home = Home(self) self.details = Details(self) self.compile = Compile(self) self.data_collection = DataCollection(self) self.libraries = Libraries(self) self.visualisation = Visualisation(self) self.execute = Execute(self) self.systems = Systems(self) self.menu_height = self.page_frame_height//20 self.menu_frame = tk.Frame(master = self.root, bg=self.panel_colour , height = self.menu_height , width = self.window_width) self.menu_frame.grid_propagate(0) self.root.protocol("WM_DELETE_WINDOW", self.on_closing) ### Instantiating variables for frame self.home_save_button = None self.home_new_button = None self.home_upload_button = None self.home_tab_button = None self.libraries_tab_button = None self.components_tab_button = None self.edit_attribute_tab_button = None self.agents_tab_button = None self.systems_tab_button = None self.execute_tab_button = None self.data_tab_button = None self.details_button = None self.compile_tab_button = None self.visual_tab_button = None self.collapse_button = None
[docs] def on_closing(self): """Runs when the user tries to close the application """ message = "Have you saved your model?\n" \ "'No' to cancel - 'Yes' to close" # Show a message box with the help message and "Yes" and "No" buttons result = tk.messagebox.askyesno("Close Application", message) # Check the user's choice and act accordingly if result: # User clicked "Yes," close the application self.visualisation.on_close_graphs() self.root.quit() self.root.destroy()
[docs] def on_open(self): """Runs when the user tries to open an old model """ message = "Have you saved your model?\n" # Show a message box with the help message and "Yes" and "No" buttons result = tk.messagebox.askyesno("Close Application", message) # Check the user's choice and act accordingly if result: self.home.btn_home_make_exist_model()
[docs] def enable(self): """Enables buttons again """ self.libraries_tab_button.configure(state = "normal") self.components_tab_button.configure(state = "normal") self.edit_attribute_tab_button.configure(state = "normal") self.agents_tab_button.configure(state = "normal") self.systems_tab_button.configure(state = "normal") self.execute_tab_button.configure(state = "normal") self.data_tab_button.configure(state = "normal") self.details_button.configure(state = "normal") self.compile_tab_button.configure(state = "normal") self.visual_tab_button.configure(state = "normal")
[docs] def on_new(self): """Runs when the user tries to start a new model """ message = "Have you saved your model?\n" \ "'No' to cancel - 'Yes' to close" # Show a message box with the help message and "Yes" and "No" buttons result = tk.messagebox.askyesno("Close Application", message) # Check the user's choice and act accordingly if result: self.home.home_tab_btn() self.home_tab_button.configure(state = "disabled") self.libraries_tab_button.configure(state = "disabled") self.components_tab_button.configure(state = "disabled") self.edit_attribute_tab_button.configure(state = "disabled") self.agents_tab_button.configure(state = "disabled") self.systems_tab_button.configure(state = "disabled") self.execute_tab_button.configure(state = "disabled") self.data_tab_button.configure(state = "disabled") self.details_button.configure(state = "disabled") self.compile_tab_button.configure(state = "disabled") self.visual_tab_button.configure(state = "disabled")
[docs] def ec_app(self): """Below this point you will find the functions which are called when a user interacts with a widget. The functions also place widgets on the page and clear widgets from the interface. """ self.panel_height = self.window_height self.panel_width = self.window_width/4 menu_item_width = 2*self.menu_height ### Add main frames self.menu_frame.pack(fill="both") self.left_frame.pack(side='left', fill = "both", anchor="w") self.collapser_frame.pack(side="left", fill="both", anchor="w") self.title_frame.pack(side='top', fill = "both", anchor="w", expand=1) self.page_frame.pack(fill = "both", anchor="w", expand=1) # Create a PhotoImage object from an image file (replace 'icon.gif' with your image file) lib_icon = tk.PhotoImage(file="icons/lib.png") comp_icon = tk.PhotoImage(file="icons/comp.png") att_icon = tk.PhotoImage(file="icons/edit.png") agent_icon = tk.PhotoImage(file="icons/agent.png") system_icon = tk.PhotoImage(file="icons/chain.png") data_icon = tk.PhotoImage(file="icons/basket.png") exec_icon = tk.PhotoImage(file="icons/execute.png") details_icon = tk.PhotoImage(file="icons/details.png") visual_icon = tk.PhotoImage(file="icons/visual.png") compile_icon = tk.PhotoImage(file="icons/download.png") ### Add menu options ### self.home_save_button = customtkinter.CTkButton(master = self.menu_frame,text="💾 Save", command=self.home.home_tab_btn, fg_color=self.panel_colour , border_color=self.panel_colour, text_color = self.menu_font_colour , hover_color=self.highlight_colour , font = self.font_menu, height=self.menu_height - 4, width=menu_item_width) self.home_save_button.configure(state = "disabled") self.home_new_button = customtkinter.CTkButton(master = self.menu_frame,text="📄 New", command=self.on_new, fg_color=self.panel_colour , border_color=self.panel_colour, text_color = self.menu_font_colour , hover_color=self.highlight_colour, font = self.font_menu, height=self.menu_height - 4 , width=menu_item_width) self.home_upload_button = customtkinter.CTkButton(master = self.menu_frame,text="📂 Open", command=self.on_open, fg_color=self.panel_colour , border_color=self.panel_colour, text_color = self.menu_font_colour , hover_color=self.highlight_colour, font = self.font_menu, height=self.menu_height - 4 , width=menu_item_width) self.home_save_button.grid(row = 0, column = 0, padx = (0,2), pady = 2) self.home_new_button.grid(row = 0, column = 2, padx = 2, pady = 2) self.home_upload_button.grid(row = 0, column = 1, padx = 2, pady = 2) ### Left Frame Buttons ### self.home_tab_button = customtkinter.CTkButton(master = self.left_frame , text="ECAgent Builder", command=self.home.home_tab_btn, fg_color=self.home_colour , border_color=self.panel_colour, font = self.font1,hover_color=self.highlight_colour , height=3*self.button_height, width=self.frame_btn_width) self.home_tab_button.grid(pady=(0,2),row = 0, column = 0) self.libraries_tab_button = customtkinter.CTkButton(self.left_frame , text="Libraries to Import", command=self.libraries.libraries_tab_btn , fg_color=self.button_colour, border_color=self.panel_colour , image=lib_icon, compound="left" , font = self.font1, anchor = "w", height=self.button_height , width=self.frame_btn_width, hover_color=self.highlight_colour) self.libraries_tab_button.grid(pady=1,row = 1,column = 0) self.components_tab_button = customtkinter.CTkButton(self.left_frame,text="Components", command=self.components.components_tab_btn, fg_color=self.button_colour, border_color=self.panel_colour, font = self.font1, anchor = "w" , image=comp_icon, compound="left" , height=self.button_height, width=self.frame_btn_width , hover_color=self.highlight_colour) self.components_tab_button.grid(pady=1,row = 2,column = 0) self.edit_attribute_tab_button = customtkinter.CTkButton(self.left_frame , text="Attribute Editing", command=self.edit_attributes.edit_attribute_tab_btn , fg_color=self.button_colour, border_color=self.panel_colour, font = self.font1 , hover_color=self.highlight_colour, anchor = "w", height=self.button_height , image=att_icon, compound="left" , width=self.frame_btn_width) self.edit_attribute_tab_button.grid(pady=1,row = 3,column = 0) self.agents_tab_button = customtkinter.CTkButton(self.left_frame,text="Agents" , command=self.agents.agents_tab_btn, fg_color=self.button_colour , image=agent_icon, compound="left" , border_color=self.panel_colour, font = self.font1, anchor = "w", height=self.button_height, width=self.frame_btn_width,hover_color=self.highlight_colour) self.agents_tab_button.grid(pady=1,row = 4,column = 0) self.systems_tab_button = customtkinter.CTkButton(self.left_frame,text="Systems" , command=self.systems.systems_tab_btn, fg_color=self.button_colour , image=system_icon, compound="left" , border_color=self.panel_colour, font = self.font1,hover_color=self.highlight_colour , anchor = "w", height=self.button_height, width=self.frame_btn_width) self.systems_tab_button.grid(pady=1,row = 5,column = 0) self.execute_tab_button = customtkinter.CTkButton(self.left_frame , text="System's Executes", command=self.execute.execute_tab_btn , fg_color=self.button_colour, border_color=self.panel_colour, font = self.font1 , image=exec_icon, compound="left" , anchor = "w", height=self.button_height, width=self.frame_btn_width, hover_color=self.highlight_colour) self.execute_tab_button.grid(pady=1,row = 6,column = 0) self.data_tab_button = customtkinter.CTkButton(self.left_frame, text="Data Collection", command=self.data_collection.data_tab_btn, fg_color=self.button_colour , image=data_icon, compound="left" , border_color=self.panel_colour, font = self.font1, anchor = "w" , height=self.button_height, hover_color=self.highlight_colour , width=self.frame_btn_width) self.data_tab_button.grid(pady=1,row = 7,column = 0) self.details_button = customtkinter.CTkButton(self.left_frame,text="Model Details", command=self.details.details_tab_btn, fg_color=self.button_colour , image=details_icon, compound="left" , border_color=self.panel_colour, font = self.font1, anchor = "w" , height=self.button_height, width=self.frame_btn_width , hover_color=self.highlight_colour) self.details_button.grid(pady=1,row = 8,column = 0) self.visual_tab_button = customtkinter.CTkButton(self.left_frame,text="Visualisation" , command=self.visualisation.visual_tab_btn, fg_color=self.button_colour , image=visual_icon, compound="left" , border_color=self.panel_colour, font = self.font1, anchor = "w" , height=self.button_height, width=self.frame_btn_width , hover_color=self.highlight_colour) self.visual_tab_button.grid(pady=1,row = 9,column = 0) self.compile_tab_button = customtkinter.CTkButton(self.left_frame,text="Model Download" , command=self.compile.compile_tab_btn, fg_color=self.button_colour , image=compile_icon, compound="left" , border_color=self.panel_colour, font = self.font1, anchor = "w" , height=self.button_height, width=self.frame_btn_width , hover_color=self.highlight_colour) self.compile_tab_button.grid(pady=1,row = 10,column = 0) self.collapse_button = customtkinter.CTkButton(self.collapser_frame,text="<" , command=self.collapse_tab_btn, fg_color=self.collapse_bar_color , border_color=self.panel_colour, font = self.font1, anchor = "w" , height=self.window_height, hover_color=self.highlight_colour, width=6) self.collapse_button.grid(row = 0, column = 0) #self.home.button_home_make_model.config(state=tk.NORMAL) self.home.home_tab_btn() ### Initially these buttons are disabled: #self.edit_attribute_tab_button.config(state=tk.DISABLED) #self.agents_tab_button.config(state=tk.DISABLED) #self.systems_tab_button.config(state=tk.DISABLED) #self.execute_tab_button.config(state=tk.DISABLED) #self.visual_tab_button.config(state=tk.DISABLED) # Enter the main event loop self.root.mainloop()
[docs] def collapse_tab_btn(self): """This method is called when the collapse button is pressed. """ if self.collapsed: self.panel_height = self.window_height self.panel_width = self.window_width/4 self.frame_btn_width = self.window_width/4 - 4 self.page_frame_width = self.window_width - self.panel_width self.left_frame.configure(width=self.panel_width,height=self.panel_height) self.page_frame.configure(height = 7*self.page_frame_height/8 , width = self.page_frame_width) self.title_frame.configure(height = self.page_frame_height/8 , width = self.page_frame_width) self.home_tab_button.configure(text="ECAgent Builder", width=self.frame_btn_width) self.libraries_tab_button.configure(text="Libraries to Import", width=self.frame_btn_width) self.components_tab_button.configure(text="Components", width=self.frame_btn_width) self.edit_attribute_tab_button.configure(text="Attribute Editing", width=self.frame_btn_width) self.agents_tab_button.configure(text="Agents", width=self.frame_btn_width) self.systems_tab_button.configure(text="Systems", width=self.frame_btn_width) self.execute_tab_button.configure(text="System's Executes", width=self.frame_btn_width) self.data_tab_button.configure(text="Data Collection", width=self.frame_btn_width) self.details_button.configure(text="Model Details", width=self.frame_btn_width) self.compile_tab_button.configure(text="Model Download", width=self.frame_btn_width) self.visual_tab_button.configure(self.left_frame,text="Visualisation", width=self.frame_btn_width) self.collapse_button.configure(text="<") self.collapsed = False else: self.frame_btn_width = 60 self.panel_height = self.window_height self.panel_width = 64 self.left_frame.configure(width=self.panel_width,height=self.panel_height) self.page_frame.configure(height = 7*self.page_frame_height/8 , width = self.page_frame_width+9*self.panel_width) self.title_frame.configure(height = self.page_frame_height/8 , width = self.page_frame_width+9*self.panel_width) self.home_tab_button.configure(text=" ", width=self.frame_btn_width) self.libraries_tab_button.configure(text="", width=self.frame_btn_width) self.components_tab_button.configure(text="", width=self.frame_btn_width) self.edit_attribute_tab_button.configure(text="", width=self.frame_btn_width) self.agents_tab_button.configure(text="", width=self.frame_btn_width) self.systems_tab_button.configure(text="", width=self.frame_btn_width) self.execute_tab_button.configure(text="", width=self.frame_btn_width) self.data_tab_button.configure(text="", width=self.frame_btn_width) self.details_button.configure(text="", width=self.frame_btn_width) self.compile_tab_button.configure(text="", width=self.frame_btn_width) self.visual_tab_button.configure(self.left_frame,text="", width=self.frame_btn_width) self.collapse_button.configure(text=">") self.collapsed = True
[docs] def clear_all(self): """Clears all the pages """ self.systems.clear_systems() self.agents.clear_agents() self.agents.clear_add_agent() self.components.clear_components() self.components.clear_add_comp() self.compile.clear_compile() self.home.clear_home() self.edit_attributes.clear_edit_attributes() self.components.clear_add_comp() self.agents.clear_add_agent() self.systems.clear_add_system() self.systems.clear_systems() self.libraries.clear_lib() self.data_collection.clear_collectors() self.details.clear_details() self.visualisation.clear_visual() self.execute.clear_execute()
if __name__ == "__main__": model = ECAppUI() model.ec_app()