listeningpy.gui.gui
This module contains the GUI classes for the listeningpy package.
1""" 2This module contains the GUI classes for the listeningpy package. 3""" 4import customtkinter as ctk 5import time 6import logging 7from typing import Callable 8from numpy import ndarray 9# logging.basicConfig(level=logging.INFO) 10import configparser 11 12import sys 13from listeningpy.stimuli import play_sound 14from listeningpy.processing import straight 15from listeningpy.config import person_identifiers 16 17class PlayButton(ctk.CTkButton): 18 '''Customized customtkinter.CTkButton 19 Attributes 20 ---------- 21 parent 22 parent customtkinter widget 23 24 Methods 25 ------- 26 reset_count() 27 Resets the click counter variable to 0. 28 ''' 29 def __init__(self, parent, *args, **kwargs): 30 ctk.CTkButton.__init__(self, parent, *args, **kwargs) 31 self.click_count = 0 32 33 def reset_count(self): 34 self.click_count = 0 35 36class InitFrame(ctk.CTkFrame): 37 def __init__(self, master, test_frame, cfg_file=None, *args, **kwargs): 38 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 39 self.test_frame = test_frame 40 self.first_name = str 41 self.second_name = str 42 self.date_of_birth = str 43 self.gender = str 44 self.hear_impaired = bool 45 self.first_name_label = ctk.CTkLabel(self, text='First name:') 46 self.second_name_label = ctk.CTkLabel(self, text='Second name:') 47 self.date_of_birth_label = ctk.CTkLabel(self, text='Date of birth:') 48 self.gender_label = ctk.CTkLabel(self, text='Gender:') 49 self.hear_impaired_label = ctk.CTkLabel(self, text='Hearing impaired:') 50 51 52 53 self.first_name_entry = ctk.CTkEntry(self) 54 self.second_name_entry = ctk.CTkEntry(self) 55 56 self.date_of_birth_frame = ctk.CTkFrame(self) 57 self.date_of_birth_day_entry = ctk.CTkEntry( 58 self.date_of_birth_frame, 59 width=35, 60 placeholder_text='DD' 61 ) 62 self.label_slash = ctk.CTkLabel(self.date_of_birth_frame, text='/') 63 self.date_of_birth_month_entry = ctk.CTkEntry( 64 self.date_of_birth_frame, 65 width=35, 66 placeholder_text='MM' 67 ) 68 self.label_slash2 = ctk.CTkLabel(self.date_of_birth_frame, text='/') 69 self.date_of_birth_year_entry = ctk.CTkEntry( 70 self.date_of_birth_frame, 71 width=50, 72 placeholder_text='YYYY' 73 ) 74 75 self.gender_menu = ctk.CTkComboBox(self, 76 values=['Man', 'Woman', 'Other'] 77 ) 78 79 self.hear_impaired_toggle = ctk.CTkSwitch( 80 self, 81 text='', 82 onvalue=True, 83 offvalue=False) 84 85 if cfg_file is not None: 86 self.set_identifiers(cfg_file) 87 88 self.start_button = ctk.CTkButton(self, text='Start test', command=self.button_clicked) 89 90 self.first_name_label.grid(column=0, row=1, 91 padx=10, 92 pady=5, 93 sticky='e') 94 self.second_name_label.grid(column=0, row=2, 95 padx=10, 96 pady=5, 97 sticky='e') 98 self.date_of_birth_label.grid(column=0, row=3, 99 padx=10, 100 pady=5, 101 sticky='e') 102 self.gender_label.grid(column=0, row=4, 103 padx=10, 104 pady=5, 105 sticky='e') 106 self.hear_impaired_label.grid(column=0, row=5, 107 padx=10, 108 pady=5, 109 sticky='e') 110 111 self.first_name_entry.grid(column=1, row=1, 112 padx=10, 113 pady=5) 114 self.second_name_entry.grid(column=1, row=2, 115 padx=10, 116 pady=5) 117 self.date_of_birth_frame.grid(column=1, row=3) 118 self.date_of_birth_day_entry.grid(column=0, row=0, 119 padx=1, 120 pady=5) 121 self.label_slash.grid(column=1, row=0, 122 padx=1, 123 pady=5) 124 self.date_of_birth_month_entry.grid(column=2, row=0, 125 padx=1, 126 pady=5) 127 self.label_slash2.grid(column=3, row=0, 128 padx=2, 129 pady=5) 130 self.date_of_birth_year_entry.grid(column=4, row=0, 131 padx=1, 132 pady=5) 133 134 self.gender_menu.grid(column=1, row=4, 135 padx=10, 136 pady=5) 137 self.hear_impaired_toggle.grid(column=1, row=5, 138 padx=10, 139 pady=8, sticky='w') 140 self.start_button.grid(column=1, row=6, 141 padx=10, 142 pady=5) 143 144 def set_identifiers(self, cfg_file): 145 identifiers = person_identifiers(cfg_file) 146 keys = identifiers.keys() 147 if 'first_name' in keys: 148 self.first_name = identifiers['first_name'] 149 self.first_name_entry.insert(0, self.first_name) 150 if 'second_name' in keys: 151 self.second_name = identifiers['second_name'] 152 self.second_name_entry.insert(0, self.second_name) 153 if 'date_of_birth' in keys: 154 self.date_of_birth = identifiers['date_of_birth'] 155 self.date_of_birth_day_entry.insert(0, self.date_of_birth[:2]) 156 self.date_of_birth_month_entry.insert(0, self.date_of_birth[3:5]) 157 self.date_of_birth_year_entry.insert(0, self.date_of_birth[6:10]) 158 if 'gender' in keys: 159 self.gender = identifiers['gender'] 160 self.gender_menu.set(self.gender) 161 if 'hear_impaired' in keys: 162 print(identifiers['hear_impaired']) 163 self.hear_impaired = identifiers['hear_impaired'].lower() == "true" 164 print(self.hear_impaired) 165 if self.hear_impaired: 166 self.hear_impaired_toggle.select() 167 168 def button_clicked(self): 169 self.first_name = self.first_name_entry.get() 170 self.second_name = self.second_name_entry.get() 171 self.date_of_birth = f'{self.date_of_birth_day_entry.get()}/{self.date_of_birth_month_entry.get()}/{self.date_of_birth_year_entry.get()}' 172 self.gender = self.gender_menu.get() 173 self.hear_impaired = self.hear_impaired_toggle.get() 174 self.master.switch_frame(self.test_frame) 175 176class InitFrameAdaptive(ctk.CTkFrame): 177 """A class representing the initial frame for an adaptive test. 178 179 This frame allows the user to input the participant identifier and the sentence set for the test. 180 181 Parameters 182 ---------- 183 master : cTK.Widget 184 The master widget. 185 test_frame : _type_ 186 The frame representing the test. 187 188 Attributes 189 ---------- 190 test_frame : _type_ 191 The frame representing the test. 192 timestamp : str 193 The current timestamp in the format "yy-mm-dd_HH-MM". 194 participant : str 195 The participant identifier. 196 sentence_set : str 197 The sentence set for the test. 198 participant_label : ctk.CTkLabel 199 The label for the participant identifier. 200 sentence_set_label : ctk.CTkLabel 201 The label for the sentence set. 202 participant_entry : ctk.CTkEntry 203 The entry field for the participant identifier. 204 sentence_set_entry : ctk.CTkEntry 205 The entry field for the sentence set. 206 start_button : ctk.CTkButton 207 The button to start the test. 208 209 Methods 210 ------- 211 button_clicked() 212 Event handler for the button click event. Sets the participant identifier and sentence set, 213 loads the sentences for the test, and switches to the test frame. 214 """ 215 def __init__(self, master, test_frame, *args, **kwargs): 216 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 217 self.test_frame : ctk.CTkFrame = test_frame 218 self.timestamp = time.strftime("%y-%m-%d_%H-%M") 219 self.participant = str 220 self.sentence_set = str 221 self.participant_label = ctk.CTkLabel(self, text='Participant identifier:') 222 self.sentence_set_label = ctk.CTkLabel(self, text='Sentence set:') 223 self.participant_entry = ctk.CTkEntry(self) 224 self.sentence_set_entry = ctk.CTkEntry(self) 225 self.start_button = ctk.CTkButton( 226 self, 227 text='Start test', 228 command=self.button_clicked) 229 230 self.participant_label.grid(column=0, row=1, 231 padx=10, 232 pady=5, 233 sticky='e') 234 self.sentence_set_label.grid(column=0, row=2, 235 padx=10, 236 pady=5, 237 sticky='e') 238 self.participant_entry.grid(column=1, row=1, 239 padx=10, 240 pady=5) 241 self.sentence_set_entry.grid(column=1, row=2, 242 padx=10, 243 pady=5) 244 self.start_button.grid(column=1, row=3, 245 padx=10, 246 pady=5) 247 248 def button_clicked(self): 249 """Handles the button click event. 250 251 This method retrieves the participant and sentence set information from the GUI, 252 sets the ID of the sentence set, loads the sentences, and switches to the test frame. 253 254 """ 255 self.participant = self.participant_entry.get() 256 self.sentence_set = self.sentence_set_entry.get() 257 self.test_frame.set_id = self.sentence_set 258 self.test_frame.load_sentences() 259 self.master.switch_frame(self.test_frame) 260 261class IntermediateFrameAdaptive(ctk.CTkFrame): 262 """A custom frame for intermediate adaptive testing. 263 264 This frame is used to display the intermediate adaptive testing interface. 265 It contains widgets for entering the next sentence set, starting the test, 266 and ending the test. 267 268 Parameters 269 ---------- 270 master : tk.Tk 271 The master widget. 272 test_frame : TestFrame 273 The test frame to switch to after starting the test. 274 *args : tuple 275 Additional positional arguments. 276 **kwargs : dict 277 Additional keyword arguments. 278 """ 279 def __init__(self, master, test_frame, *args, **kwargs): 280 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 281 self.test_frame = test_frame 282 self.sentence_set = str 283 self.sentence_set_label = ctk.CTkLabel(self, text='Next sentence set:') 284 self.sentence_set_entry = ctk.CTkEntry(self) 285 self.start_button = ctk.CTkButton( 286 self, 287 text='Start test', 288 command=self.button_clicked) 289 self.end_button = ctk.CTkButton( 290 self, 291 text='End test', 292 command=self.master.destroy) 293 294 self.sentence_set_label.grid(column=0, row=2, 295 padx=10, 296 pady=5, 297 sticky='e') 298 self.sentence_set_entry.grid(column=1, row=2, 299 padx=10, 300 pady=5) 301 self.start_button.grid(column=1, row=3, 302 padx=10, 303 pady=5) 304 self.end_button.grid(column=1, row=4, 305 padx=10, 306 pady=5, 307 ) 308 309 def button_clicked(self): 310 """Callback function for the start button click event. 311 312 This function is called when the start button is clicked. It retrieves 313 the sentence set entered by the user, sets it in the test frame, loads 314 the sentences for the test, and switches to the test frame. 315 """ 316 self.sentence_set = self.sentence_set_entry.get() 317 self.test_frame.set_id = self.sentence_set 318 self.test_frame.load_sentences() 319 self.master.switch_frame(self.test_frame) 320 321def count_add(button: PlayButton): 322 '''Adds 1 to click counter attribute of a PlayButton 323 324 Parameters 325 ---------- 326 button : PlayButton 327 ''' 328 button.click_count += 1 329 330def first_clicked(button: ctk.CTkButton): 331 '''Checks whether the button is clicked for the first time. In case 332 it is, the current time is stored for future duration evaluation. 333 334 Parameters 335 ---------- 336 button : ctk.CTkButton 337 ''' 338 if not hasattr(button, 'time') or button.time == 0: 339 button.time = time.time() 340 logging.info("clicked!") 341 342def stopwatch( 343 button_start: PlayButton, 344 button_end: ctk.CTkButton 345 ) -> float: 346 '''Calculates the time needed for the completion of current set. 347 348 Parameters 349 ---------- 350 button_start : PlayButton 351 first button clicked 352 button_end : ctk.CTkButton 353 last button clicked ('Next') 354 Returns 355 ------- 356 t : float 357 time between first and last click 358 ''' 359 t = button_end.time-button_start.time 360 button_start.time = 0 361 button_end.time = 0 362 return t 363 364def play_click( 365 stimuli_path: str, 366 button: PlayButton, 367 next_buttons: list[ctk.CTkButton, ctk.CTkRadioButton], 368 processing_func: Callable[[ndarray, int], ndarray]=straight, 369 **kwargs 370 ) -> None: 371 '''Defines actions for playback buttons. 372 373 - adding 1 to button.click_count 374 - playing stimuli 375 - enables next button 376 377 Parameters 378 ---------- 379 stimuli_path : str 380 path to stimuli 381 button : PlayButton 382 button just clicked (for counter) 383 next_buttons : list[ctk.CTkButton, ctk.CTkRadioButton] 384 list of buttons to be enabled after click 385 ''' 386 count_add(button) 387 first_clicked(button) 388 logging.info(f"Playing {stimuli_path}") 389 play_sound(path=stimuli_path, processing_func=processing_func, **kwargs) 390 for n in next_buttons: 391 n.configure(state=ctk.NORMAL) 392 393def check_choice( 394 last_played: PlayButton, 395 button_end: ctk.CTkButton 396 ): 397 '''Enables the 'Next' button. Checks whether all stimuli were played and 398 one chosen. 399 400 Parameters 401 ---------- 402 last_played : PlayButton 403 last enabled PlayButton 404 button_end : ctk.CTkButton 405 'Next' button 406 ''' 407 if last_played.cget("state") == ctk.NORMAL: 408 button_end.configure(state=ctk.NORMAL)
18class PlayButton(ctk.CTkButton): 19 '''Customized customtkinter.CTkButton 20 Attributes 21 ---------- 22 parent 23 parent customtkinter widget 24 25 Methods 26 ------- 27 reset_count() 28 Resets the click counter variable to 0. 29 ''' 30 def __init__(self, parent, *args, **kwargs): 31 ctk.CTkButton.__init__(self, parent, *args, **kwargs) 32 self.click_count = 0 33 34 def reset_count(self): 35 self.click_count = 0
Customized customtkinter.CTkButton
Attributes
- parent: parent customtkinter widget
Methods
reset_count() Resets the click counter variable to 0.
30 def __init__(self, parent, *args, **kwargs): 31 ctk.CTkButton.__init__(self, parent, *args, **kwargs) 32 self.click_count = 0
Construct a frame widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.
Inherited Members
- customtkinter.windows.widgets.ctk_button.CTkButton
- destroy
- configure
- cget
- invoke
- bind
- unbind
- focus
- focus_set
- focus_force
- customtkinter.windows.widgets.core_widget_classes.ctk_base_class.CTkBaseClass
- config
- unbind_all
- bind_all
- place
- place_forget
- pack
- pack_forget
- grid
- grid_forget
- tkinter.Misc
- deletecommand
- tk_strictMotif
- tk_bisque
- tk_setPalette
- wait_variable
- waitvar
- wait_window
- wait_visibility
- setvar
- getvar
- getboolean
- focus_get
- focus_displayof
- focus_lastfor
- tk_focusFollowsMouse
- tk_focusNext
- tk_focusPrev
- after
- after_idle
- after_cancel
- bell
- clipboard_get
- clipboard_clear
- clipboard_append
- grab_current
- grab_release
- grab_set
- grab_set_global
- grab_status
- option_add
- option_clear
- option_get
- option_readfile
- selection_clear
- selection_get
- selection_handle
- selection_own
- selection_own_get
- send
- lower
- tkraise
- lift
- winfo_atom
- winfo_atomname
- winfo_cells
- winfo_children
- winfo_class
- winfo_colormapfull
- winfo_containing
- winfo_depth
- winfo_exists
- winfo_fpixels
- winfo_geometry
- winfo_height
- winfo_id
- winfo_interps
- winfo_ismapped
- winfo_manager
- winfo_name
- winfo_parent
- winfo_pathname
- winfo_pixels
- winfo_pointerx
- winfo_pointerxy
- winfo_pointery
- winfo_reqheight
- winfo_reqwidth
- winfo_rgb
- winfo_rootx
- winfo_rooty
- winfo_screen
- winfo_screencells
- winfo_screendepth
- winfo_screenheight
- winfo_screenmmheight
- winfo_screenmmwidth
- winfo_screenvisual
- winfo_screenwidth
- winfo_server
- winfo_toplevel
- winfo_viewable
- winfo_visual
- winfo_visualid
- winfo_visualsavailable
- winfo_vrootheight
- winfo_vrootwidth
- winfo_vrootx
- winfo_vrooty
- winfo_width
- winfo_x
- winfo_y
- update
- update_idletasks
- bind_class
- unbind_class
- mainloop
- quit
- nametowidget
- register
- keys
- pack_propagate
- propagate
- pack_slaves
- slaves
- place_slaves
- grid_anchor
- anchor
- grid_bbox
- bbox
- grid_columnconfigure
- columnconfigure
- grid_location
- grid_propagate
- grid_rowconfigure
- rowconfigure
- grid_size
- size
- grid_slaves
- event_add
- event_delete
- event_generate
- event_info
- image_names
- image_types
- tkinter.Pack
- pack_configure
- forget
- pack_info
- info
- tkinter.Place
- place_configure
- place_info
- tkinter.Grid
- grid_configure
- grid_remove
- grid_info
- location
37class InitFrame(ctk.CTkFrame): 38 def __init__(self, master, test_frame, cfg_file=None, *args, **kwargs): 39 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 40 self.test_frame = test_frame 41 self.first_name = str 42 self.second_name = str 43 self.date_of_birth = str 44 self.gender = str 45 self.hear_impaired = bool 46 self.first_name_label = ctk.CTkLabel(self, text='First name:') 47 self.second_name_label = ctk.CTkLabel(self, text='Second name:') 48 self.date_of_birth_label = ctk.CTkLabel(self, text='Date of birth:') 49 self.gender_label = ctk.CTkLabel(self, text='Gender:') 50 self.hear_impaired_label = ctk.CTkLabel(self, text='Hearing impaired:') 51 52 53 54 self.first_name_entry = ctk.CTkEntry(self) 55 self.second_name_entry = ctk.CTkEntry(self) 56 57 self.date_of_birth_frame = ctk.CTkFrame(self) 58 self.date_of_birth_day_entry = ctk.CTkEntry( 59 self.date_of_birth_frame, 60 width=35, 61 placeholder_text='DD' 62 ) 63 self.label_slash = ctk.CTkLabel(self.date_of_birth_frame, text='/') 64 self.date_of_birth_month_entry = ctk.CTkEntry( 65 self.date_of_birth_frame, 66 width=35, 67 placeholder_text='MM' 68 ) 69 self.label_slash2 = ctk.CTkLabel(self.date_of_birth_frame, text='/') 70 self.date_of_birth_year_entry = ctk.CTkEntry( 71 self.date_of_birth_frame, 72 width=50, 73 placeholder_text='YYYY' 74 ) 75 76 self.gender_menu = ctk.CTkComboBox(self, 77 values=['Man', 'Woman', 'Other'] 78 ) 79 80 self.hear_impaired_toggle = ctk.CTkSwitch( 81 self, 82 text='', 83 onvalue=True, 84 offvalue=False) 85 86 if cfg_file is not None: 87 self.set_identifiers(cfg_file) 88 89 self.start_button = ctk.CTkButton(self, text='Start test', command=self.button_clicked) 90 91 self.first_name_label.grid(column=0, row=1, 92 padx=10, 93 pady=5, 94 sticky='e') 95 self.second_name_label.grid(column=0, row=2, 96 padx=10, 97 pady=5, 98 sticky='e') 99 self.date_of_birth_label.grid(column=0, row=3, 100 padx=10, 101 pady=5, 102 sticky='e') 103 self.gender_label.grid(column=0, row=4, 104 padx=10, 105 pady=5, 106 sticky='e') 107 self.hear_impaired_label.grid(column=0, row=5, 108 padx=10, 109 pady=5, 110 sticky='e') 111 112 self.first_name_entry.grid(column=1, row=1, 113 padx=10, 114 pady=5) 115 self.second_name_entry.grid(column=1, row=2, 116 padx=10, 117 pady=5) 118 self.date_of_birth_frame.grid(column=1, row=3) 119 self.date_of_birth_day_entry.grid(column=0, row=0, 120 padx=1, 121 pady=5) 122 self.label_slash.grid(column=1, row=0, 123 padx=1, 124 pady=5) 125 self.date_of_birth_month_entry.grid(column=2, row=0, 126 padx=1, 127 pady=5) 128 self.label_slash2.grid(column=3, row=0, 129 padx=2, 130 pady=5) 131 self.date_of_birth_year_entry.grid(column=4, row=0, 132 padx=1, 133 pady=5) 134 135 self.gender_menu.grid(column=1, row=4, 136 padx=10, 137 pady=5) 138 self.hear_impaired_toggle.grid(column=1, row=5, 139 padx=10, 140 pady=8, sticky='w') 141 self.start_button.grid(column=1, row=6, 142 padx=10, 143 pady=5) 144 145 def set_identifiers(self, cfg_file): 146 identifiers = person_identifiers(cfg_file) 147 keys = identifiers.keys() 148 if 'first_name' in keys: 149 self.first_name = identifiers['first_name'] 150 self.first_name_entry.insert(0, self.first_name) 151 if 'second_name' in keys: 152 self.second_name = identifiers['second_name'] 153 self.second_name_entry.insert(0, self.second_name) 154 if 'date_of_birth' in keys: 155 self.date_of_birth = identifiers['date_of_birth'] 156 self.date_of_birth_day_entry.insert(0, self.date_of_birth[:2]) 157 self.date_of_birth_month_entry.insert(0, self.date_of_birth[3:5]) 158 self.date_of_birth_year_entry.insert(0, self.date_of_birth[6:10]) 159 if 'gender' in keys: 160 self.gender = identifiers['gender'] 161 self.gender_menu.set(self.gender) 162 if 'hear_impaired' in keys: 163 print(identifiers['hear_impaired']) 164 self.hear_impaired = identifiers['hear_impaired'].lower() == "true" 165 print(self.hear_impaired) 166 if self.hear_impaired: 167 self.hear_impaired_toggle.select() 168 169 def button_clicked(self): 170 self.first_name = self.first_name_entry.get() 171 self.second_name = self.second_name_entry.get() 172 self.date_of_birth = f'{self.date_of_birth_day_entry.get()}/{self.date_of_birth_month_entry.get()}/{self.date_of_birth_year_entry.get()}' 173 self.gender = self.gender_menu.get() 174 self.hear_impaired = self.hear_impaired_toggle.get() 175 self.master.switch_frame(self.test_frame)
Frame with rounded corners and border. Default foreground colors are set according to theme. To make the frame transparent set fg_color=None. For detailed information check out the documentation.
38 def __init__(self, master, test_frame, cfg_file=None, *args, **kwargs): 39 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 40 self.test_frame = test_frame 41 self.first_name = str 42 self.second_name = str 43 self.date_of_birth = str 44 self.gender = str 45 self.hear_impaired = bool 46 self.first_name_label = ctk.CTkLabel(self, text='First name:') 47 self.second_name_label = ctk.CTkLabel(self, text='Second name:') 48 self.date_of_birth_label = ctk.CTkLabel(self, text='Date of birth:') 49 self.gender_label = ctk.CTkLabel(self, text='Gender:') 50 self.hear_impaired_label = ctk.CTkLabel(self, text='Hearing impaired:') 51 52 53 54 self.first_name_entry = ctk.CTkEntry(self) 55 self.second_name_entry = ctk.CTkEntry(self) 56 57 self.date_of_birth_frame = ctk.CTkFrame(self) 58 self.date_of_birth_day_entry = ctk.CTkEntry( 59 self.date_of_birth_frame, 60 width=35, 61 placeholder_text='DD' 62 ) 63 self.label_slash = ctk.CTkLabel(self.date_of_birth_frame, text='/') 64 self.date_of_birth_month_entry = ctk.CTkEntry( 65 self.date_of_birth_frame, 66 width=35, 67 placeholder_text='MM' 68 ) 69 self.label_slash2 = ctk.CTkLabel(self.date_of_birth_frame, text='/') 70 self.date_of_birth_year_entry = ctk.CTkEntry( 71 self.date_of_birth_frame, 72 width=50, 73 placeholder_text='YYYY' 74 ) 75 76 self.gender_menu = ctk.CTkComboBox(self, 77 values=['Man', 'Woman', 'Other'] 78 ) 79 80 self.hear_impaired_toggle = ctk.CTkSwitch( 81 self, 82 text='', 83 onvalue=True, 84 offvalue=False) 85 86 if cfg_file is not None: 87 self.set_identifiers(cfg_file) 88 89 self.start_button = ctk.CTkButton(self, text='Start test', command=self.button_clicked) 90 91 self.first_name_label.grid(column=0, row=1, 92 padx=10, 93 pady=5, 94 sticky='e') 95 self.second_name_label.grid(column=0, row=2, 96 padx=10, 97 pady=5, 98 sticky='e') 99 self.date_of_birth_label.grid(column=0, row=3, 100 padx=10, 101 pady=5, 102 sticky='e') 103 self.gender_label.grid(column=0, row=4, 104 padx=10, 105 pady=5, 106 sticky='e') 107 self.hear_impaired_label.grid(column=0, row=5, 108 padx=10, 109 pady=5, 110 sticky='e') 111 112 self.first_name_entry.grid(column=1, row=1, 113 padx=10, 114 pady=5) 115 self.second_name_entry.grid(column=1, row=2, 116 padx=10, 117 pady=5) 118 self.date_of_birth_frame.grid(column=1, row=3) 119 self.date_of_birth_day_entry.grid(column=0, row=0, 120 padx=1, 121 pady=5) 122 self.label_slash.grid(column=1, row=0, 123 padx=1, 124 pady=5) 125 self.date_of_birth_month_entry.grid(column=2, row=0, 126 padx=1, 127 pady=5) 128 self.label_slash2.grid(column=3, row=0, 129 padx=2, 130 pady=5) 131 self.date_of_birth_year_entry.grid(column=4, row=0, 132 padx=1, 133 pady=5) 134 135 self.gender_menu.grid(column=1, row=4, 136 padx=10, 137 pady=5) 138 self.hear_impaired_toggle.grid(column=1, row=5, 139 padx=10, 140 pady=8, sticky='w') 141 self.start_button.grid(column=1, row=6, 142 padx=10, 143 pady=5)
Construct a frame widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.
Inherited Members
- customtkinter.windows.widgets.ctk_frame.CTkFrame
- winfo_children
- configure
- cget
- bind
- unbind
- customtkinter.windows.widgets.core_widget_classes.ctk_base_class.CTkBaseClass
- destroy
- config
- unbind_all
- bind_all
- place
- place_forget
- pack
- pack_forget
- grid
- grid_forget
- tkinter.Misc
- deletecommand
- tk_strictMotif
- tk_bisque
- tk_setPalette
- wait_variable
- waitvar
- wait_window
- wait_visibility
- setvar
- getvar
- getboolean
- focus_set
- focus
- focus_force
- focus_get
- focus_displayof
- focus_lastfor
- tk_focusFollowsMouse
- tk_focusNext
- tk_focusPrev
- after
- after_idle
- after_cancel
- bell
- clipboard_get
- clipboard_clear
- clipboard_append
- grab_current
- grab_release
- grab_set
- grab_set_global
- grab_status
- option_add
- option_clear
- option_get
- option_readfile
- selection_clear
- selection_get
- selection_handle
- selection_own
- selection_own_get
- send
- lower
- tkraise
- lift
- winfo_atom
- winfo_atomname
- winfo_cells
- winfo_class
- winfo_colormapfull
- winfo_containing
- winfo_depth
- winfo_exists
- winfo_fpixels
- winfo_geometry
- winfo_height
- winfo_id
- winfo_interps
- winfo_ismapped
- winfo_manager
- winfo_name
- winfo_parent
- winfo_pathname
- winfo_pixels
- winfo_pointerx
- winfo_pointerxy
- winfo_pointery
- winfo_reqheight
- winfo_reqwidth
- winfo_rgb
- winfo_rootx
- winfo_rooty
- winfo_screen
- winfo_screencells
- winfo_screendepth
- winfo_screenheight
- winfo_screenmmheight
- winfo_screenmmwidth
- winfo_screenvisual
- winfo_screenwidth
- winfo_server
- winfo_toplevel
- winfo_viewable
- winfo_visual
- winfo_visualid
- winfo_visualsavailable
- winfo_vrootheight
- winfo_vrootwidth
- winfo_vrootx
- winfo_vrooty
- winfo_width
- winfo_x
- winfo_y
- update
- update_idletasks
- bind_class
- unbind_class
- mainloop
- quit
- nametowidget
- register
- keys
- pack_propagate
- propagate
- pack_slaves
- slaves
- place_slaves
- grid_anchor
- anchor
- grid_bbox
- bbox
- grid_columnconfigure
- columnconfigure
- grid_location
- grid_propagate
- grid_rowconfigure
- rowconfigure
- grid_size
- size
- grid_slaves
- event_add
- event_delete
- event_generate
- event_info
- image_names
- image_types
- tkinter.Pack
- pack_configure
- forget
- pack_info
- info
- tkinter.Place
- place_configure
- place_info
- tkinter.Grid
- grid_configure
- grid_remove
- grid_info
- location
177class InitFrameAdaptive(ctk.CTkFrame): 178 """A class representing the initial frame for an adaptive test. 179 180 This frame allows the user to input the participant identifier and the sentence set for the test. 181 182 Parameters 183 ---------- 184 master : cTK.Widget 185 The master widget. 186 test_frame : _type_ 187 The frame representing the test. 188 189 Attributes 190 ---------- 191 test_frame : _type_ 192 The frame representing the test. 193 timestamp : str 194 The current timestamp in the format "yy-mm-dd_HH-MM". 195 participant : str 196 The participant identifier. 197 sentence_set : str 198 The sentence set for the test. 199 participant_label : ctk.CTkLabel 200 The label for the participant identifier. 201 sentence_set_label : ctk.CTkLabel 202 The label for the sentence set. 203 participant_entry : ctk.CTkEntry 204 The entry field for the participant identifier. 205 sentence_set_entry : ctk.CTkEntry 206 The entry field for the sentence set. 207 start_button : ctk.CTkButton 208 The button to start the test. 209 210 Methods 211 ------- 212 button_clicked() 213 Event handler for the button click event. Sets the participant identifier and sentence set, 214 loads the sentences for the test, and switches to the test frame. 215 """ 216 def __init__(self, master, test_frame, *args, **kwargs): 217 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 218 self.test_frame : ctk.CTkFrame = test_frame 219 self.timestamp = time.strftime("%y-%m-%d_%H-%M") 220 self.participant = str 221 self.sentence_set = str 222 self.participant_label = ctk.CTkLabel(self, text='Participant identifier:') 223 self.sentence_set_label = ctk.CTkLabel(self, text='Sentence set:') 224 self.participant_entry = ctk.CTkEntry(self) 225 self.sentence_set_entry = ctk.CTkEntry(self) 226 self.start_button = ctk.CTkButton( 227 self, 228 text='Start test', 229 command=self.button_clicked) 230 231 self.participant_label.grid(column=0, row=1, 232 padx=10, 233 pady=5, 234 sticky='e') 235 self.sentence_set_label.grid(column=0, row=2, 236 padx=10, 237 pady=5, 238 sticky='e') 239 self.participant_entry.grid(column=1, row=1, 240 padx=10, 241 pady=5) 242 self.sentence_set_entry.grid(column=1, row=2, 243 padx=10, 244 pady=5) 245 self.start_button.grid(column=1, row=3, 246 padx=10, 247 pady=5) 248 249 def button_clicked(self): 250 """Handles the button click event. 251 252 This method retrieves the participant and sentence set information from the GUI, 253 sets the ID of the sentence set, loads the sentences, and switches to the test frame. 254 255 """ 256 self.participant = self.participant_entry.get() 257 self.sentence_set = self.sentence_set_entry.get() 258 self.test_frame.set_id = self.sentence_set 259 self.test_frame.load_sentences() 260 self.master.switch_frame(self.test_frame)
A class representing the initial frame for an adaptive test.
This frame allows the user to input the participant identifier and the sentence set for the test.
Parameters
- master (cTK.Widget): The master widget.
- test_frame (_type_): The frame representing the test.
Attributes
- test_frame (_type_): The frame representing the test.
- timestamp (str): The current timestamp in the format "yy-mm-dd_HH-MM".
- participant (str): The participant identifier.
- sentence_set (str): The sentence set for the test.
- participant_label (ctk.CTkLabel): The label for the participant identifier.
- sentence_set_label (ctk.CTkLabel): The label for the sentence set.
- participant_entry (ctk.CTkEntry): The entry field for the participant identifier.
- sentence_set_entry (ctk.CTkEntry): The entry field for the sentence set.
- start_button (ctk.CTkButton): The button to start the test.
Methods
button_clicked() Event handler for the button click event. Sets the participant identifier and sentence set, loads the sentences for the test, and switches to the test frame.
216 def __init__(self, master, test_frame, *args, **kwargs): 217 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 218 self.test_frame : ctk.CTkFrame = test_frame 219 self.timestamp = time.strftime("%y-%m-%d_%H-%M") 220 self.participant = str 221 self.sentence_set = str 222 self.participant_label = ctk.CTkLabel(self, text='Participant identifier:') 223 self.sentence_set_label = ctk.CTkLabel(self, text='Sentence set:') 224 self.participant_entry = ctk.CTkEntry(self) 225 self.sentence_set_entry = ctk.CTkEntry(self) 226 self.start_button = ctk.CTkButton( 227 self, 228 text='Start test', 229 command=self.button_clicked) 230 231 self.participant_label.grid(column=0, row=1, 232 padx=10, 233 pady=5, 234 sticky='e') 235 self.sentence_set_label.grid(column=0, row=2, 236 padx=10, 237 pady=5, 238 sticky='e') 239 self.participant_entry.grid(column=1, row=1, 240 padx=10, 241 pady=5) 242 self.sentence_set_entry.grid(column=1, row=2, 243 padx=10, 244 pady=5) 245 self.start_button.grid(column=1, row=3, 246 padx=10, 247 pady=5)
Construct a frame widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.
Inherited Members
- customtkinter.windows.widgets.ctk_frame.CTkFrame
- winfo_children
- configure
- cget
- bind
- unbind
- customtkinter.windows.widgets.core_widget_classes.ctk_base_class.CTkBaseClass
- destroy
- config
- unbind_all
- bind_all
- place
- place_forget
- pack
- pack_forget
- grid
- grid_forget
- tkinter.Misc
- deletecommand
- tk_strictMotif
- tk_bisque
- tk_setPalette
- wait_variable
- waitvar
- wait_window
- wait_visibility
- setvar
- getvar
- getboolean
- focus_set
- focus
- focus_force
- focus_get
- focus_displayof
- focus_lastfor
- tk_focusFollowsMouse
- tk_focusNext
- tk_focusPrev
- after
- after_idle
- after_cancel
- bell
- clipboard_get
- clipboard_clear
- clipboard_append
- grab_current
- grab_release
- grab_set
- grab_set_global
- grab_status
- option_add
- option_clear
- option_get
- option_readfile
- selection_clear
- selection_get
- selection_handle
- selection_own
- selection_own_get
- send
- lower
- tkraise
- lift
- winfo_atom
- winfo_atomname
- winfo_cells
- winfo_class
- winfo_colormapfull
- winfo_containing
- winfo_depth
- winfo_exists
- winfo_fpixels
- winfo_geometry
- winfo_height
- winfo_id
- winfo_interps
- winfo_ismapped
- winfo_manager
- winfo_name
- winfo_parent
- winfo_pathname
- winfo_pixels
- winfo_pointerx
- winfo_pointerxy
- winfo_pointery
- winfo_reqheight
- winfo_reqwidth
- winfo_rgb
- winfo_rootx
- winfo_rooty
- winfo_screen
- winfo_screencells
- winfo_screendepth
- winfo_screenheight
- winfo_screenmmheight
- winfo_screenmmwidth
- winfo_screenvisual
- winfo_screenwidth
- winfo_server
- winfo_toplevel
- winfo_viewable
- winfo_visual
- winfo_visualid
- winfo_visualsavailable
- winfo_vrootheight
- winfo_vrootwidth
- winfo_vrootx
- winfo_vrooty
- winfo_width
- winfo_x
- winfo_y
- update
- update_idletasks
- bind_class
- unbind_class
- mainloop
- quit
- nametowidget
- register
- keys
- pack_propagate
- propagate
- pack_slaves
- slaves
- place_slaves
- grid_anchor
- anchor
- grid_bbox
- bbox
- grid_columnconfigure
- columnconfigure
- grid_location
- grid_propagate
- grid_rowconfigure
- rowconfigure
- grid_size
- size
- grid_slaves
- event_add
- event_delete
- event_generate
- event_info
- image_names
- image_types
- tkinter.Pack
- pack_configure
- forget
- pack_info
- info
- tkinter.Place
- place_configure
- place_info
- tkinter.Grid
- grid_configure
- grid_remove
- grid_info
- location
262class IntermediateFrameAdaptive(ctk.CTkFrame): 263 """A custom frame for intermediate adaptive testing. 264 265 This frame is used to display the intermediate adaptive testing interface. 266 It contains widgets for entering the next sentence set, starting the test, 267 and ending the test. 268 269 Parameters 270 ---------- 271 master : tk.Tk 272 The master widget. 273 test_frame : TestFrame 274 The test frame to switch to after starting the test. 275 *args : tuple 276 Additional positional arguments. 277 **kwargs : dict 278 Additional keyword arguments. 279 """ 280 def __init__(self, master, test_frame, *args, **kwargs): 281 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 282 self.test_frame = test_frame 283 self.sentence_set = str 284 self.sentence_set_label = ctk.CTkLabel(self, text='Next sentence set:') 285 self.sentence_set_entry = ctk.CTkEntry(self) 286 self.start_button = ctk.CTkButton( 287 self, 288 text='Start test', 289 command=self.button_clicked) 290 self.end_button = ctk.CTkButton( 291 self, 292 text='End test', 293 command=self.master.destroy) 294 295 self.sentence_set_label.grid(column=0, row=2, 296 padx=10, 297 pady=5, 298 sticky='e') 299 self.sentence_set_entry.grid(column=1, row=2, 300 padx=10, 301 pady=5) 302 self.start_button.grid(column=1, row=3, 303 padx=10, 304 pady=5) 305 self.end_button.grid(column=1, row=4, 306 padx=10, 307 pady=5, 308 ) 309 310 def button_clicked(self): 311 """Callback function for the start button click event. 312 313 This function is called when the start button is clicked. It retrieves 314 the sentence set entered by the user, sets it in the test frame, loads 315 the sentences for the test, and switches to the test frame. 316 """ 317 self.sentence_set = self.sentence_set_entry.get() 318 self.test_frame.set_id = self.sentence_set 319 self.test_frame.load_sentences() 320 self.master.switch_frame(self.test_frame)
A custom frame for intermediate adaptive testing.
This frame is used to display the intermediate adaptive testing interface. It contains widgets for entering the next sentence set, starting the test, and ending the test.
Parameters
- master (tk.Tk): The master widget.
- test_frame (TestFrame): The test frame to switch to after starting the test.
- *args (tuple): Additional positional arguments.
- **kwargs (dict): Additional keyword arguments.
280 def __init__(self, master, test_frame, *args, **kwargs): 281 ctk.CTkFrame.__init__(self, master, *args, **kwargs) 282 self.test_frame = test_frame 283 self.sentence_set = str 284 self.sentence_set_label = ctk.CTkLabel(self, text='Next sentence set:') 285 self.sentence_set_entry = ctk.CTkEntry(self) 286 self.start_button = ctk.CTkButton( 287 self, 288 text='Start test', 289 command=self.button_clicked) 290 self.end_button = ctk.CTkButton( 291 self, 292 text='End test', 293 command=self.master.destroy) 294 295 self.sentence_set_label.grid(column=0, row=2, 296 padx=10, 297 pady=5, 298 sticky='e') 299 self.sentence_set_entry.grid(column=1, row=2, 300 padx=10, 301 pady=5) 302 self.start_button.grid(column=1, row=3, 303 padx=10, 304 pady=5) 305 self.end_button.grid(column=1, row=4, 306 padx=10, 307 pady=5, 308 )
Construct a frame widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.
Inherited Members
- customtkinter.windows.widgets.ctk_frame.CTkFrame
- winfo_children
- configure
- cget
- bind
- unbind
- customtkinter.windows.widgets.core_widget_classes.ctk_base_class.CTkBaseClass
- destroy
- config
- unbind_all
- bind_all
- place
- place_forget
- pack
- pack_forget
- grid
- grid_forget
- tkinter.Misc
- deletecommand
- tk_strictMotif
- tk_bisque
- tk_setPalette
- wait_variable
- waitvar
- wait_window
- wait_visibility
- setvar
- getvar
- getboolean
- focus_set
- focus
- focus_force
- focus_get
- focus_displayof
- focus_lastfor
- tk_focusFollowsMouse
- tk_focusNext
- tk_focusPrev
- after
- after_idle
- after_cancel
- bell
- clipboard_get
- clipboard_clear
- clipboard_append
- grab_current
- grab_release
- grab_set
- grab_set_global
- grab_status
- option_add
- option_clear
- option_get
- option_readfile
- selection_clear
- selection_get
- selection_handle
- selection_own
- selection_own_get
- send
- lower
- tkraise
- lift
- winfo_atom
- winfo_atomname
- winfo_cells
- winfo_class
- winfo_colormapfull
- winfo_containing
- winfo_depth
- winfo_exists
- winfo_fpixels
- winfo_geometry
- winfo_height
- winfo_id
- winfo_interps
- winfo_ismapped
- winfo_manager
- winfo_name
- winfo_parent
- winfo_pathname
- winfo_pixels
- winfo_pointerx
- winfo_pointerxy
- winfo_pointery
- winfo_reqheight
- winfo_reqwidth
- winfo_rgb
- winfo_rootx
- winfo_rooty
- winfo_screen
- winfo_screencells
- winfo_screendepth
- winfo_screenheight
- winfo_screenmmheight
- winfo_screenmmwidth
- winfo_screenvisual
- winfo_screenwidth
- winfo_server
- winfo_toplevel
- winfo_viewable
- winfo_visual
- winfo_visualid
- winfo_visualsavailable
- winfo_vrootheight
- winfo_vrootwidth
- winfo_vrootx
- winfo_vrooty
- winfo_width
- winfo_x
- winfo_y
- update
- update_idletasks
- bind_class
- unbind_class
- mainloop
- quit
- nametowidget
- register
- keys
- pack_propagate
- propagate
- pack_slaves
- slaves
- place_slaves
- grid_anchor
- anchor
- grid_bbox
- bbox
- grid_columnconfigure
- columnconfigure
- grid_location
- grid_propagate
- grid_rowconfigure
- rowconfigure
- grid_size
- size
- grid_slaves
- event_add
- event_delete
- event_generate
- event_info
- image_names
- image_types
- tkinter.Pack
- pack_configure
- forget
- pack_info
- info
- tkinter.Place
- place_configure
- place_info
- tkinter.Grid
- grid_configure
- grid_remove
- grid_info
- location
322def count_add(button: PlayButton): 323 '''Adds 1 to click counter attribute of a PlayButton 324 325 Parameters 326 ---------- 327 button : PlayButton 328 ''' 329 button.click_count += 1
Adds 1 to click counter attribute of a PlayButton
Parameters
- button (PlayButton):
331def first_clicked(button: ctk.CTkButton): 332 '''Checks whether the button is clicked for the first time. In case 333 it is, the current time is stored for future duration evaluation. 334 335 Parameters 336 ---------- 337 button : ctk.CTkButton 338 ''' 339 if not hasattr(button, 'time') or button.time == 0: 340 button.time = time.time() 341 logging.info("clicked!")
Checks whether the button is clicked for the first time. In case it is, the current time is stored for future duration evaluation.
Parameters
- button (ctk.CTkButton):
343def stopwatch( 344 button_start: PlayButton, 345 button_end: ctk.CTkButton 346 ) -> float: 347 '''Calculates the time needed for the completion of current set. 348 349 Parameters 350 ---------- 351 button_start : PlayButton 352 first button clicked 353 button_end : ctk.CTkButton 354 last button clicked ('Next') 355 Returns 356 ------- 357 t : float 358 time between first and last click 359 ''' 360 t = button_end.time-button_start.time 361 button_start.time = 0 362 button_end.time = 0 363 return t
Calculates the time needed for the completion of current set.
Parameters
- button_start (PlayButton): first button clicked
- button_end (ctk.CTkButton): last button clicked ('Next')
Returns
- t (float): time between first and last click
365def play_click( 366 stimuli_path: str, 367 button: PlayButton, 368 next_buttons: list[ctk.CTkButton, ctk.CTkRadioButton], 369 processing_func: Callable[[ndarray, int], ndarray]=straight, 370 **kwargs 371 ) -> None: 372 '''Defines actions for playback buttons. 373 374 - adding 1 to button.click_count 375 - playing stimuli 376 - enables next button 377 378 Parameters 379 ---------- 380 stimuli_path : str 381 path to stimuli 382 button : PlayButton 383 button just clicked (for counter) 384 next_buttons : list[ctk.CTkButton, ctk.CTkRadioButton] 385 list of buttons to be enabled after click 386 ''' 387 count_add(button) 388 first_clicked(button) 389 logging.info(f"Playing {stimuli_path}") 390 play_sound(path=stimuli_path, processing_func=processing_func, **kwargs) 391 for n in next_buttons: 392 n.configure(state=ctk.NORMAL)
Defines actions for playback buttons.
- adding 1 to button.click_count
- playing stimuli
- enables next button
Parameters
- stimuli_path (str): path to stimuli
- button (PlayButton): button just clicked (for counter)
- next_buttons (list[ctk.CTkButton, ctk.CTkRadioButton]): list of buttons to be enabled after click
394def check_choice( 395 last_played: PlayButton, 396 button_end: ctk.CTkButton 397 ): 398 '''Enables the 'Next' button. Checks whether all stimuli were played and 399 one chosen. 400 401 Parameters 402 ---------- 403 last_played : PlayButton 404 last enabled PlayButton 405 button_end : ctk.CTkButton 406 'Next' button 407 ''' 408 if last_played.cget("state") == ctk.NORMAL: 409 button_end.configure(state=ctk.NORMAL)
Enables the 'Next' button. Checks whether all stimuli were played and one chosen.
Parameters
- last_played (PlayButton): last enabled PlayButton
- button_end (ctk.CTkButton): 'Next' button