event_window
This module defines the EventWindow class, a tkinter Toplevel window used to display timestamps and other details for experiment event data (licks, motor movments) in a table format using a ttk.Treeview element.
1""" 2This module defines the EventWindow class, a tkinter Toplevel window used to display timestamps 3and other details for experiment event data (licks, motor movments) in a table format using a ttk.Treeview element. 4""" 5 6import tkinter as tk 7from tkinter import ttk 8 9#### USED FOR TYPE HINTS #### 10from models.event_data import EventData 11#### USED FOR TYPE HINTS #### 12 13from views.gui_common import GUIUtils 14 15 16class EventWindow(tk.Toplevel): 17 """ 18 This class represents a Toplevel window that displays experiment event data using a ttk.Treeview widget. 19 It pulls in data from an `models.event_data` `EventData` instance and is updated as new events occur. 20 After creation, window is hidden and can be shown using the `show`() method. 21 22 Attributes 23 ---------- 24 - **event_data** (*EventData*): A reference to the data model instance (`models.event_data.EventData`) 25 that holds the event DataFrame containing the data to be displayed. 26 - **last_item** (*int*): Tracks the index of the last row added from the DataFrame to the Treeview. 27 This is used to efficiently update the table by only adding new rows. 28 - **licks_frame** (*tk.Frame*): The main tkinter Frame widget within the window that contains the Treeview table. 29 - **timestamped_events** (*ttk.Treeview*): The Treeview widget used to display the event data in a table format. 30 31 Methods 32 ------- 33 - `show`() 34 Updates the table with the latest data from the `event_data` model and makes the window visible (deiconifies it). 35 - `update_table`() 36 Efficiently adds new rows from the event DataFrame (held by `event_data`) to the Treeview display. It only adds rows 37 that haven't been added previously, based on the `last_item` attribute. 38 - `build_table`() 39 Creates the main frame (`licks_frame`) and the `ttk.Treeview` widget (`timestamped_events`). Configures the Treeview columns 40 and headings based on the columns present in the `event_data.event_dataframe`. 41 """ 42 43 # inject the event dataframe when we create the class so we have access to that data 44 def __init__(self, event_data: EventData) -> None: 45 """ 46 Initialize the EventWindow. Sets up the window title, icon, key bindings (Ctrl+W to hide), 47 and the close protocol (also hides the window). It builds the table structure and initially 48 hides the window using `withdraw()`. 49 50 Parameters 51 ---------- 52 - **event_data** (*EventData*): An instance of the `models.event_data.EventData` model containing the 53 event DataFrame to be displayed. 54 """ 55 super().__init__() 56 # reference to event model 57 self.event_data = event_data 58 59 self.title("Experiment Event Data") 60 self.bind("<Control-w>", lambda event: self.withdraw()) 61 62 # Bind closing the window to self.withdraw() to hide the window but not destroy it 63 self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw()) 64 65 window_icon_path = GUIUtils.get_window_icon_path() 66 GUIUtils.set_program_icon(self, icon_path=window_icon_path) 67 68 # init last_item in the table to zero we haven't added anything into the table 69 # this is used to efficiently update the table when program is running 70 self.last_item = 0 71 72 self.build_table() 73 74 self.withdraw() 75 76 def show(self): 77 """ 78 Updates the table with the latest event data and makes the window visible. 79 Calls `update_table()` first, then `deiconify()` to show the window. 80 """ 81 self.update_table() 82 self.deiconify() 83 84 def update_table(self): 85 """ 86 Updates the Treeview widget by adding only the new rows from the event DataFrame 87 since the last update. It uses `self.last_item` to determine the starting index 88 for adding new rows, ensuring efficient updates without reprocessing existing entries. 89 """ 90 # df we are working with is self.event_data.event_dataframe, get rid of self prefix and such to save room 91 df = self.event_data.event_dataframe 92 # num rows in that df currently 93 len_event_df = len(df) 94 95 last_item = self.last_item 96 97 # Insert data from the DataFrame. iterrows() returns an iterator over the rows of a df of form (index, series (of data)) 98 for i in range(last_item, len_event_df): 99 row_content = df.iloc[i] 100 101 item_iid = f"item {i}" 102 103 self.timestamped_events.insert( 104 "", tk.END, iid=item_iid, values=list(row_content) 105 ) 106 # update the last item with the LAST item that was added on this iteration, next time we will start 107 # the loop with this, so that we don't unneccesarily update entries already there 108 self.last_item = len(df) 109 110 def build_table(self) -> None: 111 """ 112 Creates the main frame (`licks_frame`) and the `ttk.Treeview` widget (`timestamped_events`) 113 used to display the event data. Configures the Treeview columns and headings based on the 114 columns present in the `event_data.event_dataframe`. Calls `update_table()` to initially 115 populate the table. 116 """ 117 self.licks_frame = tk.Frame(self) 118 self.licks_frame.grid(row=0, column=0, sticky="nsew") 119 120 # Create a Treeview widget 121 # show='headings' ensures we only see columns with headings defined 122 self.timestamped_events = ttk.Treeview( 123 self.licks_frame, show="headings", height=25 124 ) 125 126 self.timestamped_events["columns"] = list( 127 self.event_data.event_dataframe.columns 128 ) 129 130 # Configure the names of the colums to reflect the heaader labels 131 for col in self.timestamped_events["columns"]: 132 self.timestamped_events.heading(col, text=col) 133 134 self.update_table() 135 136 self.timestamped_events.pack(fill="both", expand=True)
17class EventWindow(tk.Toplevel): 18 """ 19 This class represents a Toplevel window that displays experiment event data using a ttk.Treeview widget. 20 It pulls in data from an `models.event_data` `EventData` instance and is updated as new events occur. 21 After creation, window is hidden and can be shown using the `show`() method. 22 23 Attributes 24 ---------- 25 - **event_data** (*EventData*): A reference to the data model instance (`models.event_data.EventData`) 26 that holds the event DataFrame containing the data to be displayed. 27 - **last_item** (*int*): Tracks the index of the last row added from the DataFrame to the Treeview. 28 This is used to efficiently update the table by only adding new rows. 29 - **licks_frame** (*tk.Frame*): The main tkinter Frame widget within the window that contains the Treeview table. 30 - **timestamped_events** (*ttk.Treeview*): The Treeview widget used to display the event data in a table format. 31 32 Methods 33 ------- 34 - `show`() 35 Updates the table with the latest data from the `event_data` model and makes the window visible (deiconifies it). 36 - `update_table`() 37 Efficiently adds new rows from the event DataFrame (held by `event_data`) to the Treeview display. It only adds rows 38 that haven't been added previously, based on the `last_item` attribute. 39 - `build_table`() 40 Creates the main frame (`licks_frame`) and the `ttk.Treeview` widget (`timestamped_events`). Configures the Treeview columns 41 and headings based on the columns present in the `event_data.event_dataframe`. 42 """ 43 44 # inject the event dataframe when we create the class so we have access to that data 45 def __init__(self, event_data: EventData) -> None: 46 """ 47 Initialize the EventWindow. Sets up the window title, icon, key bindings (Ctrl+W to hide), 48 and the close protocol (also hides the window). It builds the table structure and initially 49 hides the window using `withdraw()`. 50 51 Parameters 52 ---------- 53 - **event_data** (*EventData*): An instance of the `models.event_data.EventData` model containing the 54 event DataFrame to be displayed. 55 """ 56 super().__init__() 57 # reference to event model 58 self.event_data = event_data 59 60 self.title("Experiment Event Data") 61 self.bind("<Control-w>", lambda event: self.withdraw()) 62 63 # Bind closing the window to self.withdraw() to hide the window but not destroy it 64 self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw()) 65 66 window_icon_path = GUIUtils.get_window_icon_path() 67 GUIUtils.set_program_icon(self, icon_path=window_icon_path) 68 69 # init last_item in the table to zero we haven't added anything into the table 70 # this is used to efficiently update the table when program is running 71 self.last_item = 0 72 73 self.build_table() 74 75 self.withdraw() 76 77 def show(self): 78 """ 79 Updates the table with the latest event data and makes the window visible. 80 Calls `update_table()` first, then `deiconify()` to show the window. 81 """ 82 self.update_table() 83 self.deiconify() 84 85 def update_table(self): 86 """ 87 Updates the Treeview widget by adding only the new rows from the event DataFrame 88 since the last update. It uses `self.last_item` to determine the starting index 89 for adding new rows, ensuring efficient updates without reprocessing existing entries. 90 """ 91 # df we are working with is self.event_data.event_dataframe, get rid of self prefix and such to save room 92 df = self.event_data.event_dataframe 93 # num rows in that df currently 94 len_event_df = len(df) 95 96 last_item = self.last_item 97 98 # Insert data from the DataFrame. iterrows() returns an iterator over the rows of a df of form (index, series (of data)) 99 for i in range(last_item, len_event_df): 100 row_content = df.iloc[i] 101 102 item_iid = f"item {i}" 103 104 self.timestamped_events.insert( 105 "", tk.END, iid=item_iid, values=list(row_content) 106 ) 107 # update the last item with the LAST item that was added on this iteration, next time we will start 108 # the loop with this, so that we don't unneccesarily update entries already there 109 self.last_item = len(df) 110 111 def build_table(self) -> None: 112 """ 113 Creates the main frame (`licks_frame`) and the `ttk.Treeview` widget (`timestamped_events`) 114 used to display the event data. Configures the Treeview columns and headings based on the 115 columns present in the `event_data.event_dataframe`. Calls `update_table()` to initially 116 populate the table. 117 """ 118 self.licks_frame = tk.Frame(self) 119 self.licks_frame.grid(row=0, column=0, sticky="nsew") 120 121 # Create a Treeview widget 122 # show='headings' ensures we only see columns with headings defined 123 self.timestamped_events = ttk.Treeview( 124 self.licks_frame, show="headings", height=25 125 ) 126 127 self.timestamped_events["columns"] = list( 128 self.event_data.event_dataframe.columns 129 ) 130 131 # Configure the names of the colums to reflect the heaader labels 132 for col in self.timestamped_events["columns"]: 133 self.timestamped_events.heading(col, text=col) 134 135 self.update_table() 136 137 self.timestamped_events.pack(fill="both", expand=True)
This class represents a Toplevel window that displays experiment event data using a ttk.Treeview widget.
It pulls in data from an models.event_data
EventData
instance and is updated as new events occur.
After creation, window is hidden and can be shown using the show
() method.
Attributes
- event_data (EventData): A reference to the data model instance (
models.event_data.EventData
) that holds the event DataFrame containing the data to be displayed. - last_item (int): Tracks the index of the last row added from the DataFrame to the Treeview. This is used to efficiently update the table by only adding new rows.
- licks_frame (tk.Frame): The main tkinter Frame widget within the window that contains the Treeview table.
- timestamped_events (ttk.Treeview): The Treeview widget used to display the event data in a table format.
Methods
show
() Updates the table with the latest data from theevent_data
model and makes the window visible (deiconifies it).update_table
() Efficiently adds new rows from the event DataFrame (held byevent_data
) to the Treeview display. It only adds rows that haven't been added previously, based on thelast_item
attribute.build_table
() Creates the main frame (licks_frame
) and thettk.Treeview
widget (timestamped_events
). Configures the Treeview columns and headings based on the columns present in theevent_data.event_dataframe
.
45 def __init__(self, event_data: EventData) -> None: 46 """ 47 Initialize the EventWindow. Sets up the window title, icon, key bindings (Ctrl+W to hide), 48 and the close protocol (also hides the window). It builds the table structure and initially 49 hides the window using `withdraw()`. 50 51 Parameters 52 ---------- 53 - **event_data** (*EventData*): An instance of the `models.event_data.EventData` model containing the 54 event DataFrame to be displayed. 55 """ 56 super().__init__() 57 # reference to event model 58 self.event_data = event_data 59 60 self.title("Experiment Event Data") 61 self.bind("<Control-w>", lambda event: self.withdraw()) 62 63 # Bind closing the window to self.withdraw() to hide the window but not destroy it 64 self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw()) 65 66 window_icon_path = GUIUtils.get_window_icon_path() 67 GUIUtils.set_program_icon(self, icon_path=window_icon_path) 68 69 # init last_item in the table to zero we haven't added anything into the table 70 # this is used to efficiently update the table when program is running 71 self.last_item = 0 72 73 self.build_table() 74 75 self.withdraw()
Initialize the EventWindow. Sets up the window title, icon, key bindings (Ctrl+W to hide),
and the close protocol (also hides the window). It builds the table structure and initially
hides the window using withdraw()
.
Parameters
- event_data (EventData): An instance of the
models.event_data.EventData
model containing the event DataFrame to be displayed.
77 def show(self): 78 """ 79 Updates the table with the latest event data and makes the window visible. 80 Calls `update_table()` first, then `deiconify()` to show the window. 81 """ 82 self.update_table() 83 self.deiconify()
Updates the table with the latest event data and makes the window visible.
Calls update_table()
first, then deiconify()
to show the window.
85 def update_table(self): 86 """ 87 Updates the Treeview widget by adding only the new rows from the event DataFrame 88 since the last update. It uses `self.last_item` to determine the starting index 89 for adding new rows, ensuring efficient updates without reprocessing existing entries. 90 """ 91 # df we are working with is self.event_data.event_dataframe, get rid of self prefix and such to save room 92 df = self.event_data.event_dataframe 93 # num rows in that df currently 94 len_event_df = len(df) 95 96 last_item = self.last_item 97 98 # Insert data from the DataFrame. iterrows() returns an iterator over the rows of a df of form (index, series (of data)) 99 for i in range(last_item, len_event_df): 100 row_content = df.iloc[i] 101 102 item_iid = f"item {i}" 103 104 self.timestamped_events.insert( 105 "", tk.END, iid=item_iid, values=list(row_content) 106 ) 107 # update the last item with the LAST item that was added on this iteration, next time we will start 108 # the loop with this, so that we don't unneccesarily update entries already there 109 self.last_item = len(df)
Updates the Treeview widget by adding only the new rows from the event DataFrame
since the last update. It uses self.last_item
to determine the starting index
for adding new rows, ensuring efficient updates without reprocessing existing entries.
111 def build_table(self) -> None: 112 """ 113 Creates the main frame (`licks_frame`) and the `ttk.Treeview` widget (`timestamped_events`) 114 used to display the event data. Configures the Treeview columns and headings based on the 115 columns present in the `event_data.event_dataframe`. Calls `update_table()` to initially 116 populate the table. 117 """ 118 self.licks_frame = tk.Frame(self) 119 self.licks_frame.grid(row=0, column=0, sticky="nsew") 120 121 # Create a Treeview widget 122 # show='headings' ensures we only see columns with headings defined 123 self.timestamped_events = ttk.Treeview( 124 self.licks_frame, show="headings", height=25 125 ) 126 127 self.timestamped_events["columns"] = list( 128 self.event_data.event_dataframe.columns 129 ) 130 131 # Configure the names of the colums to reflect the heaader labels 132 for col in self.timestamped_events["columns"]: 133 self.timestamped_events.heading(col, text=col) 134 135 self.update_table() 136 137 self.timestamped_events.pack(fill="both", expand=True)
Creates the main frame (licks_frame
) and the ttk.Treeview
widget (timestamped_events
)
used to display the event data. Configures the Treeview columns and headings based on the
columns present in the event_data.event_dataframe
. Calls update_table()
to initially
populate the table.