def setup_hms_input(screen_frame, input_content_wrapper): validate_command = (screen_frame.register(validate_hms_input), "%d", "%S") screen_frame.hour_label = PLabel(input_content_wrapper, text="H: ") screen_frame.hour_input = Entry(input_content_wrapper, width=ENTRY_WIDTH, justify=CENTER, validate="key", validatecommand=validate_command) screen_frame.hour_input.insert(0, 0) screen_frame.hour_label.grid(row=0, column=0) screen_frame.hour_input.grid(row=0, column=1) screen_frame.minute_label = PLabel(input_content_wrapper, text="M: ") screen_frame.minute_input = Entry(input_content_wrapper, width=ENTRY_WIDTH, justify=CENTER, validate="key", validatecommand=validate_command) screen_frame.minute_input.insert(0, 0) screen_frame.minute_label.grid(row=0, column=2) screen_frame.minute_input.grid(row=0, column=3) screen_frame.seconds_label = PLabel(input_content_wrapper, text="S: ") screen_frame.seconds_input = Entry(input_content_wrapper, width=ENTRY_WIDTH, justify=CENTER, validate="key", validatecommand=validate_command) screen_frame.seconds_input.insert(0, 0) screen_frame.seconds_label.grid(row=0, column=4) screen_frame.seconds_input.grid(row=0, column=5) return screen_frame.hour_input, screen_frame.minute_input, screen_frame.seconds_input
def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=SR_FRAME_SELECTION_TITLE) self.screen_description = PLabel(self.content_wrapper, text="Please select frames that have a satisfactory " "checkerboard result.") self.next_button = Button(self.content_wrapper, text="Next", command=lambda: self.on_next_button())
def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=SR_FRAME_SELECTION_TITLE) self.screen_description = PLabel( self.content_wrapper, text="Please select a frame that has a satisfactory " "stereo rectification result.")
def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=self.screen_title) self.screen_description_label = PLabel( self.content_wrapper, text=("\n\n".join(self.process_description_message_list))) self.button_wrapper = Frame(self.content_wrapper) self.next_button = Button(self.button_wrapper, text="Next", command=lambda: self.on_next_button())
class AbstractTitleDescriptionMultipleButtonsScreen(GuiBaseFrame): def __init__(self, parent, controller, title, process_description_message_list, button_text_list, button_command_list, **kw): self.screen_title = title self.process_description_message_list = process_description_message_list self.button_text_list = button_text_list self.button_command_list = button_command_list GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=self.screen_title) self.screen_description_label = PLabel( self.content_wrapper, text=("\n\n".join(self.process_description_message_list))) self.button_wrapper = Frame(self.content_wrapper) if len(self.button_text_list) != len(self.button_command_list): raise ValueError( "Button text list and command list must have the same length " "(each text must correspond with a command in both lists).") self.buttons = [] for i in range(0, len(self.button_text_list)): self.buttons.append((Button(self.button_wrapper, text=self.button_text_list[i], command=self.button_command_list[i]))) def add_widgets_to_frame(self): self.screen_title.pack() self.screen_description_label.pack() self.button_wrapper.pack() for button in self.buttons: button.pack() self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_47, anchor=CENTER) def on_show_frame(self): pass def update_frame(self, data): pass def on_hide_frame(self): pass
class AbstractTimeSelectionStartScreen(AbstractTimeSelectionBaseScreen): def __init__(self, parent, controller, **kw): AbstractTimeSelectionBaseScreen.__init__(self, parent, controller, **kw) def init_widgets(self): AbstractTimeSelectionBaseScreen.init_widgets(self) self.screen_instruction_1_filename_label = PLabel(self.content_wrapper) self.screen_instruction_2_label = PLabel(self.content_wrapper) self.empty_label_1 = PLabel(self.content_wrapper) def add_widgets_to_frame(self): self.pack_title_and_instruction_widgets() self.empty_label_1.pack() self.screen_instruction_1_filename_label.pack() self.screen_instruction_2_label.pack() self.pack_lower_half_widgets() self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): self.set_instruction_1_filename(self.controller.get_filename_of_video_with_0_offset() + "\n") self.set_error_message("") def update_frame(self, data): AbstractTimeSelectionBaseScreen.update_frame(self, data) def on_hide_frame(self): pass def set_input_checks(self): AbstractTimeSelectionBaseScreen.set_input_checks(self) def on_input_check_success(self): AbstractTimeSelectionBaseScreen.on_input_check_success(self) def prev_button_command(self): AbstractTimeSelectionBaseScreen.prev_button_command(self) def next_button_command(self): AbstractTimeSelectionBaseScreen.next_button_command(self) def set_instruction_1_filename(self, file_of_video_to_open): self.screen_instruction_1_filename_label.configure(text=file_of_video_to_open) def set_instruction_2_text(self, timestamp_instr_text): self.screen_instruction_2_label.configure(text=timestamp_instr_text)
def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper) self.screen_instruction_1_label = PLabel(self.content_wrapper) self.input_content_wrapper = Frame(self.content_wrapper) self.hour_input, self.minute_input, self.seconds_input = setup_hms_input( self, self.input_content_wrapper) self.error_message_label = PLabel(self.content_wrapper, fg="red") self.button_wrapper = Frame(self.content_wrapper) self.back_button = Button(self.button_wrapper, text="Back", command=lambda: self.prev_button_command()) self.next_button = Button(self.button_wrapper, text="Next", command=lambda: self.next_button_command())
def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=self.screen_title) self.screen_description_label = PLabel( self.content_wrapper, text=("\n\n".join(self.process_description_message_list))) self.button_wrapper = Frame(self.content_wrapper) if len(self.button_text_list) != len(self.button_command_list): raise ValueError( "Button text list and command list must have the same length " "(each text must correspond with a command in both lists).") self.buttons = [] for i in range(0, len(self.button_text_list)): self.buttons.append((Button(self.button_wrapper, text=self.button_text_list[i], command=self.button_command_list[i])))
def init_widgets(self): self.content_wrapper = Frame(self) self.init_video_info() self.screen_title_label = Header1Label(self.content_wrapper, text="Video Selection") self.instruction_label = PLabel( self.content_wrapper, text="Please choose your left and right video files. " "Press Next when finished.\n" "(Files must be in MKV format).") self.left_video_filename_preview_label = PLabel( self.content_wrapper, text="No Video Selected") self.left_video_button = Button( self.content_wrapper, text="Choose Left Video", command=lambda: self.select_video_through_button_press(LEFT)) self.right_video_filename_preview_label = PLabel( self.content_wrapper, text="No Video Selected") self.right_video_button = Button( self.content_wrapper, text="Choose Right Video", command=lambda: self.select_video_through_button_press(RIGHT)) self.next_button = Button(self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.next_screen()) self.add_img_previews()
class AbstractTitleDescriptionNextScreen(GuiBaseFrame): def __init__(self, parent, controller, title, process_description_message_list, **kw): self.screen_title = title self.process_description_message_list = process_description_message_list GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=self.screen_title) self.screen_description_label = PLabel( self.content_wrapper, text=("\n\n".join(self.process_description_message_list))) self.button_wrapper = Frame(self.content_wrapper) self.next_button = Button(self.button_wrapper, text="Next", command=lambda: self.on_next_button()) def add_widgets_to_frame(self): self.screen_title.pack() self.screen_description_label.pack() self.button_wrapper.pack() self.next_button.pack() self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): pass def update_frame(self, data): pass def on_hide_frame(self): pass def on_next_button(self): raise NotImplementedError
def init_widgets(self): self.content_wrapper = Frame(self) self.content_wrapper.configure(background="white") self.screen_title = Header1Label( self.content_wrapper, text="Scanning video for information...\n") self.progress_bar = Progressbar(self.content_wrapper, orient=HORIZONTAL, mode="indeterminate", length=WINDOW_WIDTH / 2) self.wait_text = PLabel( self.content_wrapper, text="\nThis might take a few minutes." "\nPlease do not change the video files while this is running.\n") self.left_frames_count = PLabel(self.content_wrapper, text=LEFT_FRAMES_COUNT_PREFIX + "0") self.right_frames_count = PLabel(self.content_wrapper, text=RIGHT_FRAMES_COUNT_PREFIX + "0") self.elapsed_time_label = PLabel(self.content_wrapper) self.empty_space = PLabel(self.content_wrapper, text=" ") self.next_button = Button( self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.controller.show_next_frame())
def init_widgets(self): self.content_wrapper = Frame(self) self.content_wrapper.configure(bg="white") self.screen_title = Header1Label(self.content_wrapper) self.empty_space_1 = PLabel(self.content_wrapper) self.progress_bar_control_var = DoubleVar() self.progress_bar = Progressbar(self.content_wrapper, orient=HORIZONTAL, mode="determinate", length=WINDOW_WIDTH / 2, variable=self.progress_bar_control_var) self.wait_text = PLabel(self.content_wrapper) self.information_display = PLabel(self.content_wrapper) self.empty_space_2 = PLabel(self.content_wrapper) self.next_button = Button(self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.on_next_button())
class FinalScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.text_container = Frame(self) self.screen_title = Header1Label(self.text_container, text="Stereo Rectification Complete!") self.text_1 = PLabel(self.text_container, text=("\n".join([ "Your videos have been stereo rectified!", "You can find them in the follow " "paths on your system:" ]))) self.filenames = PLabel(self.text_container) self.thanks_label = PLabel(self.text_container, text="Thank you for your patience!") self.finish_button = Button(self.text_container, text="Finish and Close Window", command=lambda: sys.exit()) def add_widgets_to_frame(self): self.screen_title.pack() self.text_1.pack() self.filenames.pack() self.thanks_label.pack() self.finish_button.pack() self.text_container.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): self.filenames.configure(text=("\n".join([ "Left video:", self.controller.left_video_filename_sr, "", "Right video:", self.controller.right_video_filename_sr ]))) def on_hide_frame(self): pass
def init_widgets(self): self.text_container = Frame(self) self.screen_title = Header1Label(self.text_container, text="Stereo Rectification Complete!") self.text_1 = PLabel(self.text_container, text=("\n".join([ "Your videos have been stereo rectified!", "You can find them in the follow " "paths on your system:" ]))) self.filenames = PLabel(self.text_container) self.thanks_label = PLabel(self.text_container, text="Thank you for your patience!") self.finish_button = Button(self.text_container, text="Finish and Close Window", command=lambda: sys.exit())
def init_widgets(self): self.text_container = Frame(self) self.welcome_label = Header1Label( self.text_container, text="Welcome to the full WALL-E footage processing experience!!") self.description_label = PLabel( self.text_container, text="This process helps you perform the following in order:\n" "\t1) Frame matching the videos\n" "\t2) Finding and generating the best SR map\n" "\t3) Stereo rectifying the videos", justify=LEFT) self.advisory_label = PLabel( self.text_container, text="(Note: the GUI experience looks best on a Mac)") self.good_luck_label = PLabel(self.text_container, text="Good Luck!") self.next_button = Button( self.text_container, text="Get Started", command=lambda: self.controller.show_next_frame())
class WelcomeScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.text_container = Frame(self) self.welcome_label = Header1Label( self.text_container, text="Welcome to the full WALL-E footage processing experience!!") self.description_label = PLabel( self.text_container, text="This process helps you perform the following in order:\n" "\t1) Frame matching the videos\n" "\t2) Finding and generating the best SR map\n" "\t3) Stereo rectifying the videos", justify=LEFT) self.advisory_label = PLabel( self.text_container, text="(Note: the GUI experience looks best on a Mac)") self.good_luck_label = PLabel(self.text_container, text="Good Luck!") self.next_button = Button( self.text_container, text="Get Started", command=lambda: self.controller.show_next_frame()) def add_widgets_to_frame(self): self.welcome_label.pack() self.description_label.pack() self.advisory_label.pack() self.good_luck_label.pack() self.next_button.pack() self.text_container.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): pass def on_hide_frame(self): pass
class AbstractProgressScreen(GuiBaseFrame): # Backend logic thread should be making calls to controller.update_frame() to update the UI while logic runs. def __init__(self, parent, controller, backend_logic_function, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) self.backend_logic_function = backend_logic_function def init_widgets(self): self.content_wrapper = Frame(self) self.content_wrapper.configure(bg="white") self.screen_title = Header1Label(self.content_wrapper) self.empty_space_1 = PLabel(self.content_wrapper) self.progress_bar_control_var = DoubleVar() self.progress_bar = Progressbar(self.content_wrapper, orient=HORIZONTAL, mode="determinate", length=WINDOW_WIDTH / 2, variable=self.progress_bar_control_var) self.wait_text = PLabel(self.content_wrapper) self.information_display = PLabel(self.content_wrapper) self.empty_space_2 = PLabel(self.content_wrapper) self.next_button = Button(self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.on_next_button()) def add_widgets_to_frame(self): self.screen_title.pack() self.empty_space_1.pack() self.progress_bar.pack() self.wait_text.pack() self.information_display.pack() self.empty_space_2.pack() self.next_button.pack() self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): self.wait_text.configure( text="\nThis might take a few minutes." "\nPlease do not change the video files while this is " "running.\n") self.start_time = time.time() self.backend_logic_thread = threading.Thread( target=self.backend_logic_function, kwargs={"controller": self.controller}) self.backend_logic_thread.start() self.master.after(THREAD_CHECK_ALIVE_INTERVAL_MS, self.check_thread) # Data should be a dictionary with keys "percent_done" and "message_list". def update_frame(self, data): percent_done = data[PROGRESS_SCREEN_PERCENT_DONE] message_list = data[PROGRESS_SCREEN_MESSAGE_LIST] self.progress_bar_control_var.set(percent_done) elapsed_time_seconds = int(time.time() - self.start_time) elapsed_time_message = ELAPSED_TIME_PREFIX + str( datetime.timedelta(seconds=elapsed_time_seconds)) if elapsed_time_seconds == 0: estimated_time_left_string = ESTIMATED_TIME_LEFT_PREFIX + "Calculating..." else: estimated_time_left_seconds = int( elapsed_time_seconds / percent_done * 100.0) - elapsed_time_seconds estimated_time_left_string = ESTIMATED_TIME_LEFT_PREFIX + \ str(datetime.timedelta(seconds=estimated_time_left_seconds)) message_list.append(elapsed_time_message) message_list.append(estimated_time_left_string) self.set_information_display_text(message_list) def on_hide_frame(self): self.progress_bar.stop() def set_title(self, title): self.screen_title.configure(text=title) def set_information_display_text(self, message_list): self.information_display.configure(text=("\n".join(message_list))) def check_thread(self): if self.backend_logic_thread.is_alive(): self.master.after(THREAD_CHECK_ALIVE_INTERVAL_MS, self.check_thread) else: self.progress_bar.stop() self.wait_text.configure(text="\nDone!\nPress Next to continue.\n") self.next_button.configure(state=NORMAL) def on_next_button(self): self.controller.show_next_frame()
class VideoSelectionScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.content_wrapper = Frame(self) self.init_video_info() self.screen_title_label = Header1Label(self.content_wrapper, text="Video Selection") self.instruction_label = PLabel( self.content_wrapper, text="Please choose your left and right video files. " "Press Next when finished.\n" "(Files must be in MKV format).") self.left_video_filename_preview_label = PLabel( self.content_wrapper, text="No Video Selected") self.left_video_button = Button( self.content_wrapper, text="Choose Left Video", command=lambda: self.select_video_through_button_press(LEFT)) self.right_video_filename_preview_label = PLabel( self.content_wrapper, text="No Video Selected") self.right_video_button = Button( self.content_wrapper, text="Choose Right Video", command=lambda: self.select_video_through_button_press(RIGHT)) self.next_button = Button(self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.next_screen()) self.add_img_previews() def add_widgets_to_frame(self): self.content_wrapper.grid_columnconfigure(0, weight=1) self.content_wrapper.grid_columnconfigure(1, weight=1) self.screen_title_label.grid(row=SCREEN_TITLE_ROW, column=0, columnspan=CENTER_SCREEN_COLSPAN) self.instruction_label.grid(row=INSTRUCTION_ROW, column=LEFT_VIDEO_THUMBNAIL_COL, columnspan=CENTER_SCREEN_COLSPAN) self.left_video_thumbnail.grid(row=THUMBNAIL_ROW, column=LEFT_VIDEO_THUMBNAIL_COL) self.left_video_filename_preview_label.grid( row=FILENAME_PREVIEW_ROW, column=LEFT_VIDEO_THUMBNAIL_COL) self.left_video_button.grid(row=CHOOSE_VIDEO_BUTTON_ROW, column=LEFT_VIDEO_THUMBNAIL_COL) self.right_video_thumbnail.grid(row=THUMBNAIL_ROW, column=RIGHT_VIDEO_THUMBNAIL_COL) self.right_video_filename_preview_label.grid( row=FILENAME_PREVIEW_ROW, column=RIGHT_VIDEO_THUMBNAIL_COL) self.right_video_button.grid(row=CHOOSE_VIDEO_BUTTON_ROW, column=RIGHT_VIDEO_THUMBNAIL_COL) self.next_button.grid(row=NEXT_BUTTON_ROW, column=0, columnspan=CENTER_SCREEN_COLSPAN) self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_47, anchor=CENTER) def init_video_info(self): self.left_video_selected = False self.right_video_selected = False self.left_video_filename = None self.right_video_filename = None def next_screen(self): self.controller.set_video_filenames(self.left_video_filename, self.right_video_filename) self.controller.show_next_frame() def add_img_previews(self): img_not_available = cv2.imread( get_asset_filename(IMG_NOT_AVAILABLE_FILENAME)) img_not_available = cv2_bgr_image_to_tkinter_with_resize( img_not_available, VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT) self.left_video_thumbnail = Label(self.content_wrapper, image=img_not_available) self.left_video_thumbnail.image = img_not_available self.right_video_thumbnail = Label(self.content_wrapper, image=img_not_available) self.right_video_thumbnail.image = img_not_available def select_video_through_button_press(self, video_side=LEFT): selected_video_filename = select_video_filename() self.set_video_thumbnail_based_on_filename(selected_video_filename, video_side) def set_next_button_state(self): if self.left_video_selected and self.right_video_selected: self.next_button.configure(state=NORMAL) def on_show_frame(self): if does_tmp_file_exist_basename(VIDEOS_SELECTED_TMP_FILENAME): video_filenames = read_tmp_file(VIDEOS_SELECTED_TMP_FILENAME) video_filenames = ast.literal_eval(video_filenames) self.set_video_thumbnail_based_on_filename(video_filenames[LEFT], LEFT) self.set_video_thumbnail_based_on_filename(video_filenames[RIGHT], RIGHT) def on_hide_frame(self): video_filenames_used = { LEFT: self.left_video_filename, RIGHT: self.right_video_filename } write_to_tmp_file(VIDEOS_SELECTED_TMP_FILENAME, str(video_filenames_used)) def set_video_thumbnail_based_on_filename(self, video_filename, video_side=LEFT): if os.path.isfile( os.path.join(os.path.dirname(video_filename), os.path.basename(video_filename))): vc_object = cv2.VideoCapture(video_filename) _, img = vc_object.read() vc_object.release() img = cv2_bgr_image_to_tkinter_with_resize(img, VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT) self.update_ui(video_filename, img, True, video_side) def update_ui(self, filename, img, video_selected, video_side=LEFT): if video_selected and video_side == LEFT: self.left_video_selected = True self.left_video_filename = filename self.left_video_filename_preview_label.config( text=os.path.basename(os.path.normpath(filename))) self.set_next_button_state() self.left_video_thumbnail.configure(image=img) self.left_video_thumbnail.image = img elif video_selected and video_side == RIGHT: self.right_video_selected = True self.right_video_filename = filename self.right_video_filename_preview_label.config( text=os.path.basename(os.path.normpath(filename))) self.set_next_button_state() self.right_video_thumbnail.configure(image=img) self.right_video_thumbnail.image = img
class VideoScanProgressScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) self.counting_left_frames = None def init_widgets(self): self.content_wrapper = Frame(self) self.content_wrapper.configure(background="white") self.screen_title = Header1Label( self.content_wrapper, text="Scanning video for information...\n") self.progress_bar = Progressbar(self.content_wrapper, orient=HORIZONTAL, mode="indeterminate", length=WINDOW_WIDTH / 2) self.wait_text = PLabel( self.content_wrapper, text="\nThis might take a few minutes." "\nPlease do not change the video files while this is running.\n") self.left_frames_count = PLabel(self.content_wrapper, text=LEFT_FRAMES_COUNT_PREFIX + "0") self.right_frames_count = PLabel(self.content_wrapper, text=RIGHT_FRAMES_COUNT_PREFIX + "0") self.elapsed_time_label = PLabel(self.content_wrapper) self.empty_space = PLabel(self.content_wrapper, text=" ") self.next_button = Button( self.content_wrapper, text="Next", state=DISABLED, command=lambda: self.controller.show_next_frame()) def add_widgets_to_frame(self): self.screen_title.pack() self.progress_bar.pack() self.wait_text.pack() self.left_frames_count.pack() self.right_frames_count.pack() self.elapsed_time_label.pack() self.empty_space.pack() self.next_button.pack() self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_45, anchor=CENTER) def on_show_frame(self): self.start_time = time.time() self.progress_bar.start() self.frame_count_thread = threading.Thread( target=self.controller.video_frame_loader.count_frames_in_videos, kwargs={"controller": self.controller}) self.frame_count_thread.start() self.master.after(50, self.check_thread) def update_frame(self, data): if LEFT_FRAMES_COUNT_PREFIX in data: self.left_frames_count.configure(text=data) if RIGHT_FRAMES_COUNT_PREFIX in data: self.right_frames_count.configure(text=data) self.elapsed_time_label.configure( text=ELAPSED_TIME_PREFIX + str(datetime.timedelta(seconds=int(time.time() - self.start_time)))) def on_hide_frame(self): self.progress_bar.stop() def check_thread(self): if self.frame_count_thread.is_alive(): self.master.after(50, self.check_thread) else: self.progress_bar.stop() self.wait_text.configure(text="\nDone!\nPress Next to continue.\n") self.next_button.configure(state=NORMAL)
class AbstractTimeSelectionBaseScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) self.input_checks = [] self.set_input_checks() def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper) self.screen_instruction_1_label = PLabel(self.content_wrapper) self.input_content_wrapper = Frame(self.content_wrapper) self.hour_input, self.minute_input, self.seconds_input = setup_hms_input( self, self.input_content_wrapper) self.error_message_label = PLabel(self.content_wrapper, fg="red") self.button_wrapper = Frame(self.content_wrapper) self.back_button = Button(self.button_wrapper, text="Back", command=lambda: self.prev_button_command()) self.next_button = Button(self.button_wrapper, text="Next", command=lambda: self.next_button_command()) def add_widgets_to_frame(self): GuiBaseFrame.add_widgets_to_frame(self) def on_show_frame(self): GuiBaseFrame.on_show_frame(self) def update_frame(self, data): GuiBaseFrame.update_frame(self, data) def on_hide_frame(self): GuiBaseFrame.on_hide_frame(self) def set_input_checks(self): raise NotImplementedError def on_input_check_success(self): raise NotImplementedError def next_button_command(self): if self.perform_input_checks(): self.set_error_message("") self.on_input_check_success() self.controller.show_next_frame() def prev_button_command(self): self.controller.show_prev_frame() def perform_input_checks(self): for input_check in self.input_checks: if not input_check(self): return False return True def pack_title_and_instruction_widgets(self): self.screen_title.pack() self.screen_instruction_1_label.pack() # Packs inputs, error message labels, and buttons def pack_lower_half_widgets(self): self.input_content_wrapper.pack() self.error_message_label.pack() self.back_button.grid(row=0, column=0) self.next_button.grid(row=0, column=1) self.button_wrapper.pack() def set_title(self, title): self.screen_title.configure(text=title) def set_instruction_1_text(self, text): self.screen_instruction_1_label.configure(text=text) def set_error_message(self, error_message): self.error_message_label.configure(text=error_message) def add_input_check(self, input_check_lambda): self.input_checks.append(input_check_lambda)
def init_widgets(self): self.buttons = [] self.content_wrapper = Frame(self) self.title_label = Header1Label(self.content_wrapper, text="Frame Offset Validation") self.subtitle_label = PLabel( self.content_wrapper, text= "Use the buttons below to ensure that the video frame offset is valid. Press Next when finished." ) self.left_frame_num_label = PLabel(self.content_wrapper) self.right_frame_num_label = PLabel(self.content_wrapper) self.left_video_label = PLabel(self.content_wrapper) self.right_video_label = PLabel(self.content_wrapper) self.left_offset_label = PLabel(self.content_wrapper) self.right_offset_label = PLabel(self.content_wrapper) self.left_offset_inc_instr = PLabel( self.content_wrapper, text="Increase left video offset by:") self.right_offset_inc_instr = PLabel( self.content_wrapper, text="Increase right video offset by:") self.left_offset_inc_10_button = Button( self.content_wrapper, text="+10", command=lambda: self.adjust_left_offset(10)) self.left_offset_inc_5_button = Button( self.content_wrapper, text="+5", command=lambda: self.adjust_left_offset(5)) self.left_offset_inc_1_button = Button( self.content_wrapper, text="+1", command=lambda: self.adjust_left_offset(1)) self.right_offset_inc_1_button = Button( self.content_wrapper, text="+1", command=lambda: self.adjust_right_offset(1)) self.right_offset_inc_5_button = Button( self.content_wrapper, text="+5", command=lambda: self.adjust_right_offset(5)) self.right_offset_inc_10_button = Button( self.content_wrapper, text="+10", command=lambda: self.adjust_right_offset(10)) self.buttons.extend([ self.left_offset_inc_10_button, self.left_offset_inc_5_button, self.left_offset_inc_1_button, self.right_offset_inc_1_button, self.right_offset_inc_5_button, self.right_offset_inc_10_button ]) self.video_navigation_label = PLabel(self.content_wrapper, text="Video frame navigation:") self.left_video_frame_inc_10_button = Button( self.content_wrapper, text=BACK_10_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-10)) self.left_video_frame_inc_5_button = Button( self.content_wrapper, text=BACK_5_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-5)) self.left_video_frame_inc_1_button = Button( self.content_wrapper, text=BACK_1_FRAME_TEXT, command=lambda: self.adjust_frame_num(-1)) self.right_video_frame_inc_1_button = Button( self.content_wrapper, text=FORWARD_1_FRAME_TEXT, command=lambda: self.adjust_frame_num(1)) self.right_video_frame_inc_5_button = Button( self.content_wrapper, text=FORWARD_5_FRAMES_TEXT, command=lambda: self.adjust_frame_num(5)) self.right_video_frame_inc_10_button = Button( self.content_wrapper, text=FORWARD_10_FRAMES_TEXT, command=lambda: self.adjust_frame_num(10)) self.buttons.extend([ self.left_video_frame_inc_10_button, self.left_video_frame_inc_5_button, self.left_video_frame_inc_1_button, self.right_video_frame_inc_1_button, self.right_video_frame_inc_5_button, self.right_video_frame_inc_10_button ]) self.left_video_frame_inc_300_button = Button( self.content_wrapper, text=BACK_300_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-300)) self.left_video_frame_inc_150_button = Button( self.content_wrapper, text=BACK_150_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-150)) self.left_video_frame_inc_30_button = Button( self.content_wrapper, text=BACK_30_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-30)) self.right_video_frame_inc_30_button = Button( self.content_wrapper, text=FORWARD_30_FRAMES_TEXT, command=lambda: self.adjust_frame_num(30)) self.right_video_frame_inc_150_button = Button( self.content_wrapper, text=FORWARD_150_FRAMES_TEXT, command=lambda: self.adjust_frame_num(150)) self.right_video_frame_inc_300_button = Button( self.content_wrapper, text=FORWARD_300_FRAMES_TEXT, command=lambda: self.adjust_frame_num(300)) self.buttons.extend([ self.left_video_frame_inc_300_button, self.left_video_frame_inc_150_button, self.left_video_frame_inc_30_button, self.right_video_frame_inc_30_button, self.right_video_frame_inc_150_button, self.right_video_frame_inc_300_button ]) self.next_button = Button( self.content_wrapper, text="Next", command=lambda: self.controller.show_next_frame())
class FrameMatchingValidationScreen(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) self.left_video_filename = None self.right_video_filename = None self.video_frame_loader = None self.frame_num = 0 def init_widgets(self): self.buttons = [] self.content_wrapper = Frame(self) self.title_label = Header1Label(self.content_wrapper, text="Frame Offset Validation") self.subtitle_label = PLabel( self.content_wrapper, text= "Use the buttons below to ensure that the video frame offset is valid. Press Next when finished." ) self.left_frame_num_label = PLabel(self.content_wrapper) self.right_frame_num_label = PLabel(self.content_wrapper) self.left_video_label = PLabel(self.content_wrapper) self.right_video_label = PLabel(self.content_wrapper) self.left_offset_label = PLabel(self.content_wrapper) self.right_offset_label = PLabel(self.content_wrapper) self.left_offset_inc_instr = PLabel( self.content_wrapper, text="Increase left video offset by:") self.right_offset_inc_instr = PLabel( self.content_wrapper, text="Increase right video offset by:") self.left_offset_inc_10_button = Button( self.content_wrapper, text="+10", command=lambda: self.adjust_left_offset(10)) self.left_offset_inc_5_button = Button( self.content_wrapper, text="+5", command=lambda: self.adjust_left_offset(5)) self.left_offset_inc_1_button = Button( self.content_wrapper, text="+1", command=lambda: self.adjust_left_offset(1)) self.right_offset_inc_1_button = Button( self.content_wrapper, text="+1", command=lambda: self.adjust_right_offset(1)) self.right_offset_inc_5_button = Button( self.content_wrapper, text="+5", command=lambda: self.adjust_right_offset(5)) self.right_offset_inc_10_button = Button( self.content_wrapper, text="+10", command=lambda: self.adjust_right_offset(10)) self.buttons.extend([ self.left_offset_inc_10_button, self.left_offset_inc_5_button, self.left_offset_inc_1_button, self.right_offset_inc_1_button, self.right_offset_inc_5_button, self.right_offset_inc_10_button ]) self.video_navigation_label = PLabel(self.content_wrapper, text="Video frame navigation:") self.left_video_frame_inc_10_button = Button( self.content_wrapper, text=BACK_10_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-10)) self.left_video_frame_inc_5_button = Button( self.content_wrapper, text=BACK_5_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-5)) self.left_video_frame_inc_1_button = Button( self.content_wrapper, text=BACK_1_FRAME_TEXT, command=lambda: self.adjust_frame_num(-1)) self.right_video_frame_inc_1_button = Button( self.content_wrapper, text=FORWARD_1_FRAME_TEXT, command=lambda: self.adjust_frame_num(1)) self.right_video_frame_inc_5_button = Button( self.content_wrapper, text=FORWARD_5_FRAMES_TEXT, command=lambda: self.adjust_frame_num(5)) self.right_video_frame_inc_10_button = Button( self.content_wrapper, text=FORWARD_10_FRAMES_TEXT, command=lambda: self.adjust_frame_num(10)) self.buttons.extend([ self.left_video_frame_inc_10_button, self.left_video_frame_inc_5_button, self.left_video_frame_inc_1_button, self.right_video_frame_inc_1_button, self.right_video_frame_inc_5_button, self.right_video_frame_inc_10_button ]) self.left_video_frame_inc_300_button = Button( self.content_wrapper, text=BACK_300_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-300)) self.left_video_frame_inc_150_button = Button( self.content_wrapper, text=BACK_150_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-150)) self.left_video_frame_inc_30_button = Button( self.content_wrapper, text=BACK_30_FRAMEs_TEXT, command=lambda: self.adjust_frame_num(-30)) self.right_video_frame_inc_30_button = Button( self.content_wrapper, text=FORWARD_30_FRAMES_TEXT, command=lambda: self.adjust_frame_num(30)) self.right_video_frame_inc_150_button = Button( self.content_wrapper, text=FORWARD_150_FRAMES_TEXT, command=lambda: self.adjust_frame_num(150)) self.right_video_frame_inc_300_button = Button( self.content_wrapper, text=FORWARD_300_FRAMES_TEXT, command=lambda: self.adjust_frame_num(300)) self.buttons.extend([ self.left_video_frame_inc_300_button, self.left_video_frame_inc_150_button, self.left_video_frame_inc_30_button, self.right_video_frame_inc_30_button, self.right_video_frame_inc_150_button, self.right_video_frame_inc_300_button ]) self.next_button = Button( self.content_wrapper, text="Next", command=lambda: self.controller.show_next_frame()) def add_widgets_to_frame(self): self.title_label.grid(row=TITLE_ROW, column=0, columnspan=12) self.subtitle_label.grid(row=SUBTITLE_ROW, column=0, columnspan=12) self.left_frame_num_label.grid(row=FRAME_NUM_ROW, column=0, columnspan=6) self.right_frame_num_label.grid(row=FRAME_NUM_ROW, column=6, columnspan=6) self.left_video_label.grid(row=VIDEO_FRAMES_ROW, column=0, columnspan=6) self.right_video_label.grid(row=VIDEO_FRAMES_ROW, column=6, columnspan=6) self.left_offset_label.grid(row=OFFSET_INC_INSTR_ROW, column=0, columnspan=2) self.right_offset_label.grid(row=OFFSET_INC_INSTR_ROW, column=10, columnspan=2) self.left_offset_inc_instr.grid(row=OFFSET_INC_INSTR_ROW, column=3, columnspan=3) self.right_offset_inc_instr.grid(row=OFFSET_INC_INSTR_ROW, column=6, columnspan=3) self.left_offset_inc_10_button.grid(row=OFFSET_INC_BUTTONS, column=3) self.left_offset_inc_5_button.grid(row=OFFSET_INC_BUTTONS, column=4) self.left_offset_inc_1_button.grid(row=OFFSET_INC_BUTTONS, column=5) self.right_offset_inc_1_button.grid(row=OFFSET_INC_BUTTONS, column=6) self.right_offset_inc_5_button.grid(row=OFFSET_INC_BUTTONS, column=7) self.right_offset_inc_10_button.grid(row=OFFSET_INC_BUTTONS, column=8) self.video_navigation_label.grid(row=VIDEO_NAVIGATION_ROW, column=0, columnspan=12) self.left_video_frame_inc_10_button.grid(row=VIDEO_BUTTONS_ROW_1, column=0, columnspan=2) self.left_video_frame_inc_5_button.grid(row=VIDEO_BUTTONS_ROW_1, column=2, columnspan=2) self.left_video_frame_inc_1_button.grid(row=VIDEO_BUTTONS_ROW_1, column=4, columnspan=2) self.right_video_frame_inc_1_button.grid(row=VIDEO_BUTTONS_ROW_1, column=6, columnspan=2) self.right_video_frame_inc_5_button.grid(row=VIDEO_BUTTONS_ROW_1, column=8, columnspan=2) self.right_video_frame_inc_10_button.grid(row=VIDEO_BUTTONS_ROW_1, column=10, columnspan=2) self.left_video_frame_inc_300_button.grid(row=VIDEO_BUTTONS_ROW_2, column=0, columnspan=2) self.left_video_frame_inc_150_button.grid(row=VIDEO_BUTTONS_ROW_2, column=2, columnspan=2) self.left_video_frame_inc_30_button.grid(row=VIDEO_BUTTONS_ROW_2, column=4, columnspan=2) self.right_video_frame_inc_30_button.grid(row=VIDEO_BUTTONS_ROW_2, column=6, columnspan=2) self.right_video_frame_inc_150_button.grid(row=VIDEO_BUTTONS_ROW_2, column=8, columnspan=2) self.right_video_frame_inc_300_button.grid(row=VIDEO_BUTTONS_ROW_2, column=10, columnspan=2) self.next_button.grid(row=NEXT_BUTTON_ROW, column=0, columnspan=12) self.content_wrapper.place(relx=SCREENS_REL_X, rely=SCREEN_REL_Y_50, anchor=CENTER) def set_video_frame(self, frame_num, left_offset, right_offset): _, left_img = \ self.controller.video_frame_loader.get_left_frame_tkinter_with_resize(frame_num + left_offset, VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT) _, right_img = \ self.controller.video_frame_loader.get_right_frame_tkinter_with_resize(frame_num + right_offset, VIDEO_PREVIEW_WIDTH, VIDEO_PREVIEW_HEIGHT) self.left_video_label.configure(image=left_img) self.left_video_label.image = left_img self.right_video_label.configure(image=right_img) self.right_video_label.image = right_img def on_show_frame(self): self.update_UI() def update_frame(self, data): pass def on_hide_frame(self): pass def update_UI(self): self.ensure_frame_num_is_valid() self.set_video_frame(self.frame_num, self.controller.video_offsets.left_offset, self.controller.video_offsets.right_offset) self.left_frame_num_label.configure( text=LEFT_FRAME_NUM_PREFIX + str(self.frame_num + self.controller.video_offsets.left_offset)) self.right_frame_num_label.configure( text=RIGHT_FRAME_NUM_PREFIX + str(self.frame_num + self.controller.video_offsets.right_offset)) self.left_offset_label.configure( text=LEFT_OFFSET_PREFIX + str(self.controller.video_offsets.left_offset)) self.right_offset_label.configure( text=RIGHT_OFFSET_PREFIX + str(self.controller.video_offsets.right_offset)) def ensure_frame_num_is_valid(self): if self.frame_num < 0: self.frame_num = 0 left_offset = self.controller.video_offsets.left_offset right_offset = self.controller.video_offsets.right_offset last_frame_left = self.controller.video_frame_loader.last_frame_num_left last_frame_right = self.controller.video_frame_loader.last_frame_num_right if self.frame_num + left_offset > last_frame_left: self.frame_num = last_frame_left - left_offset if self.frame_num + right_offset > last_frame_right: self.frame_num = last_frame_left - right_offset def adjust_frame_num(self, value): self.frame_num += value self.update_UI() def adjust_left_offset(self, value): self.controller.video_offsets.left_offset += value self.normalize_offsets() self.update_UI() def adjust_right_offset(self, value): self.controller.video_offsets.right_offset += value self.normalize_offsets() self.update_UI() def normalize_offsets(self): if self.controller.video_offsets.left_offset > self.controller.video_offsets.right_offset: self.controller.video_offsets.left_offset -= self.controller.video_offsets.right_offset self.controller.video_offsets.right_offset = 0 elif self.controller.video_offsets.left_offset < self.controller.video_offsets.right_offset: self.controller.video_offsets.right_offset -= self.controller.video_offsets.left_offset self.controller.video_offsets.left_offset = 0 else: self.controller.video_offsets.left_offset = 0 self.controller.video_offsets.right_offset = 0
def init_widgets(self): AbstractTimeSelectionBaseScreen.init_widgets(self) self.screen_instruction_1_filename_label = PLabel(self.content_wrapper) self.screen_instruction_2_label = PLabel(self.content_wrapper) self.empty_label_1 = PLabel(self.content_wrapper)
def on_show_frame(self): self.canvas_wrappers = [] self.canvases = [] self.page_num = 0 if len(self.controller.sr_results) == 0: self.controller.show_frame(SrNoFramesFoundScreen) else: pages = int(ceil(len(self.controller.sr_results) / 10.0)) for page in range(0, pages): canvas_wrapper = Frame(self.content_wrapper, borderwidth="1", relief="solid") canvas = Canvas(canvas_wrapper, width=int(WINDOW_WIDTH * 7 / 8), height=(WINDOW_HEIGHT * 2 / 3)) scroll_bar = Scrollbar(canvas_wrapper, orient=VERTICAL, command=canvas.yview) results_list_frame = Frame(canvas) canvas.configure(yscrollcommand=scroll_bar.set) canvas.create_window(0, 0, window=results_list_frame) canvas.bind_all("<Up>", self.on_up_key) canvas.bind_all("<Down>", self.on_down_key) canvas.bind_all("<Left>", self.on_left_key) canvas.bind_all("<Right>", self.on_right_key) canvas.grid(row=0, column=0, sticky="nsew") scroll_bar.grid(row=0, column=1, sticky="ns") canvas_wrapper.grid(row=2, column=0, columnspan=3, sticky="nsew") select_buttons_on_page = [] for row in range(0, RESULTS_PER_PAGE): result_num = page * RESULTS_PER_PAGE + row if result_num < len(self.controller.sr_results): frame_num = self.controller.sr_results[result_num][ FRAME_NUM_LABEL] result_entry = Frame(results_list_frame, borderwidth="1", relief="solid") description = PLabel( result_entry, text="Frame #" + str(int(frame_num)) + ", Time: " + str(datetime.timedelta(seconds=frame_num / 30))) preview_wrapper = Frame(result_entry) left_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num][LEFT]) right_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num] [RIGHT]) select_button = SrSelectButton( preview_wrapper, self.controller, self.controller.sr_results[result_num] [SR_MAP_LABEL], text="Select") select_buttons_on_page.append(select_button) description.pack() left_video_preview.grid(row=row, column=0) right_video_preview.grid(row=row, column=1) select_button.grid(row=row, column=2) preview_wrapper.pack() result_entry.pack() for i in range(0, len(select_buttons_on_page)): select_buttons_on_page[i].configure( command=select_buttons_on_page[i].use_sr_map) self.master.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) canvas.yview_moveto(0) self.canvas_wrappers.append(canvas_wrapper) self.canvases.append(canvas) self.prev_result_page = Button( self.content_wrapper, text="<", command=lambda: self.prev_page_command()) self.page_info_label = PLabel( self.content_wrapper, text=get_page_info_label_message(self.page_num, len(self.canvases), RESULTS_PER_PAGE)) self.next_result_page = Button( self.content_wrapper, text=">", command=lambda: self.next_page_command()) self.prev_result_page.grid(row=3, column=0) self.page_info_label.grid(row=3, column=1) self.next_result_page.grid(row=3, column=2) self.canvas_wrappers[self.page_num].tkraise()
class SrFrameSelection(GuiBaseFrame): def __init__(self, parent, controller, **kw): GuiBaseFrame.__init__(self, parent, controller, **kw) def init_widgets(self): self.content_wrapper = Frame(self) self.screen_title = Header1Label(self.content_wrapper, text=SR_FRAME_SELECTION_TITLE) self.screen_description = PLabel( self.content_wrapper, text="Please select a frame that has a satisfactory " "stereo rectification result.") def add_widgets_to_frame(self): self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.screen_title.grid(row=0, column=0, columnspan=3) self.screen_description.grid(row=1, columnspan=3) self.content_wrapper.place(relx=SCREENS_REL_X, rely=0.48, anchor=CENTER) def on_show_frame(self): self.canvas_wrappers = [] self.canvases = [] self.page_num = 0 if len(self.controller.sr_results) == 0: self.controller.show_frame(SrNoFramesFoundScreen) else: pages = int(ceil(len(self.controller.sr_results) / 10.0)) for page in range(0, pages): canvas_wrapper = Frame(self.content_wrapper, borderwidth="1", relief="solid") canvas = Canvas(canvas_wrapper, width=int(WINDOW_WIDTH * 7 / 8), height=(WINDOW_HEIGHT * 2 / 3)) scroll_bar = Scrollbar(canvas_wrapper, orient=VERTICAL, command=canvas.yview) results_list_frame = Frame(canvas) canvas.configure(yscrollcommand=scroll_bar.set) canvas.create_window(0, 0, window=results_list_frame) canvas.bind_all("<Up>", self.on_up_key) canvas.bind_all("<Down>", self.on_down_key) canvas.bind_all("<Left>", self.on_left_key) canvas.bind_all("<Right>", self.on_right_key) canvas.grid(row=0, column=0, sticky="nsew") scroll_bar.grid(row=0, column=1, sticky="ns") canvas_wrapper.grid(row=2, column=0, columnspan=3, sticky="nsew") select_buttons_on_page = [] for row in range(0, RESULTS_PER_PAGE): result_num = page * RESULTS_PER_PAGE + row if result_num < len(self.controller.sr_results): frame_num = self.controller.sr_results[result_num][ FRAME_NUM_LABEL] result_entry = Frame(results_list_frame, borderwidth="1", relief="solid") description = PLabel( result_entry, text="Frame #" + str(int(frame_num)) + ", Time: " + str(datetime.timedelta(seconds=frame_num / 30))) preview_wrapper = Frame(result_entry) left_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num][LEFT]) right_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num] [RIGHT]) select_button = SrSelectButton( preview_wrapper, self.controller, self.controller.sr_results[result_num] [SR_MAP_LABEL], text="Select") select_buttons_on_page.append(select_button) description.pack() left_video_preview.grid(row=row, column=0) right_video_preview.grid(row=row, column=1) select_button.grid(row=row, column=2) preview_wrapper.pack() result_entry.pack() for i in range(0, len(select_buttons_on_page)): select_buttons_on_page[i].configure( command=select_buttons_on_page[i].use_sr_map) self.master.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) canvas.yview_moveto(0) self.canvas_wrappers.append(canvas_wrapper) self.canvases.append(canvas) self.prev_result_page = Button( self.content_wrapper, text="<", command=lambda: self.prev_page_command()) self.page_info_label = PLabel( self.content_wrapper, text=get_page_info_label_message(self.page_num, len(self.canvases), RESULTS_PER_PAGE)) self.next_result_page = Button( self.content_wrapper, text=">", command=lambda: self.next_page_command()) self.prev_result_page.grid(row=3, column=0) self.page_info_label.grid(row=3, column=1) self.next_result_page.grid(row=3, column=2) self.canvas_wrappers[self.page_num].tkraise() def update_frame(self, data): pass def on_hide_frame(self): pass def on_up_key(self, event): self.canvases[self.page_num].yview_scroll(-7, 'units') def on_down_key(self, event): self.canvases[self.page_num].yview_scroll(7, 'units') def on_left_key(self, event): self.prev_page_command() def on_right_key(self, event): self.next_page_command() def prev_page_command(self): if self.page_num > 0: self.page_num -= 1 self.canvas_wrappers[self.page_num].tkraise() self.page_info_label.configure(text=get_page_info_label_message( self.page_num, len(self.canvases), RESULTS_PER_PAGE)) def next_page_command(self): if self.page_num < len(self.canvas_wrappers) - 1: self.page_num += 1 self.canvas_wrappers[self.page_num].tkraise() self.page_info_label.configure(text=get_page_info_label_message( self.page_num, len(self.canvases), RESULTS_PER_PAGE))