def __init__(self, root): ''' ----------------------------------------------------- | main button toolbar | ----------------------------------------------------- | < ma | in content area > | | | | | left | right | | control | details frame | | tree | / output viewer | | area | | ----------------------------------------------------- | status bar area | ----------------------------------------------------- ''' self._project = None self.executor = None # Root window self.root = root self.root.title('Cricket') self.root.geometry('1024x768') # Prevent the menus from having the empty tearoff entry self.root.option_add('*tearOff', FALSE) # Catch the close button self.root.protocol("WM_DELETE_WINDOW", self.cmd_quit) # Catch the "quit" event. self.root.createcommand('exit', self.cmd_quit) # Setup the menu self._setup_menubar() # Set up the main content for the window. self._setup_button_toolbar() self._setup_main_content() self._setup_status_bar() # Now configure the weights for the root frame self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=0) self.root.rowconfigure(1, weight=1) self.root.rowconfigure(2, weight=0) # Set up listeners for runner events. Executor.bind('test_status_update', self.on_executorStatusUpdate) Executor.bind('test_start', self.on_executorTestStart) Executor.bind('test_end', self.on_executorTestEnd) Executor.bind('suite_end', self.on_executorSuiteEnd) Executor.bind('suite_error', self.on_executorSuiteError) # Now that we've laid out the grid, hide the error and output text # until we actually have an error/output to display self._hide_test_output() self._hide_test_errors()
def __init__(self, root): self._project = None self.executor = None # Root window self.root = root self.root.title('Cricket') self.root.geometry('1024x768') # Prevent the menus from having the empty tearoff entry self.root.option_add('*tearOff', FALSE) # Catch the close button self.root.protocol("WM_DELETE_WINDOW", self.on_quit) # Catch the "quit" event. self.root.createcommand('exit', self.on_quit) # Menubar self.menubar = Menu(self.root) # self.menu_Apple = Menu(self.menubar, name='Apple') # self.menubar.add_cascade(menu=self.menu_Apple) self.menu_file = Menu(self.menubar) self.menubar.add_cascade(menu=self.menu_file, label='File') self.menu_edit = Menu(self.menubar) self.menubar.add_cascade(menu=self.menu_edit, label='Edit') # self.menu_help = Menu(self.menubar, name='help') # self.menubar.add_cascade(menu=self.menu_help) # self.menu_Apple.add_command(label='Test', command=self.cmd_dummy) # self.menu_file.add_command(label='New', command=self.cmd_dummy, accelerator="Command-N") # self.menu_file.add_command(label='Open...', command=self.cmd_dummy) # self.menu_file.add_command(label='Close', command=self.cmd_dummy) # self.menu_edit.add_command(label='New', command=self.cmd_dummy) # self.menu_edit.add_command(label='Open...', command=self.cmd_dummy) # self.menu_edit.add_command(label='Close', command=self.cmd_dummy) # self.menu_help.add_command(label='Test', command=self.cmd_dummy) # last step - configure the menubar self.root['menu'] = self.menubar # Main toolbar self.toolbar = Frame(self.root) self.toolbar.grid(column=0, row=0, sticky=(W, E)) # Buttons on the toolbar self.stop_button = Button(self.toolbar, text='Stop', command=self.on_stop, state=DISABLED) self.stop_button.grid(column=0, row=0) self.run_all_button = Button(self.toolbar, text='Run all', command=self.on_run_all) self.run_all_button.grid(column=1, row=0) self.run_selected_button = Button(self.toolbar, text='Run selected', command=self.on_run_selected, state=DISABLED) self.run_selected_button.grid(column=2, row=0) self.rerun_button = Button(self.toolbar, text='Re-run', command=self.on_rerun, state=DISABLED) self.rerun_button.grid(column=3, row=0) # Main content area self.content = PanedWindow(self.root, orient=HORIZONTAL) self.content.grid(column=0, row=1, sticky=(N, S, E, W)) # The left-hand side frame on the main content area # The tabs for the two trees self.tree_notebook = Notebook(self.content, padding=(0, 5, 0, 5)) self.content.add(self.tree_notebook) # The tree for all tests self.all_tests_tree_frame = Frame(self.content) self.all_tests_tree_frame.grid(column=0, row=0, sticky=(N, S, E, W)) self.tree_notebook.add(self.all_tests_tree_frame, text='All tests') self.all_tests_tree = Treeview(self.all_tests_tree_frame) self.all_tests_tree.grid(column=0, row=0, sticky=(N, S, E, W)) # Set up the tag colors for tree nodes. for status, config in STATUS.items(): self.all_tests_tree.tag_configure(config['tag'], foreground=config['color']) self.all_tests_tree.tag_configure('inactive', foreground='lightgray') # Listen for button clicks on tree nodes self.all_tests_tree.tag_bind('TestModule', '<Double-Button-1>', self.on_testModuleClicked) self.all_tests_tree.tag_bind('TestCase', '<Double-Button-1>', self.on_testCaseClicked) self.all_tests_tree.tag_bind('TestMethod', '<Double-Button-1>', self.on_testMethodClicked) self.all_tests_tree.tag_bind('TestModule', '<<TreeviewSelect>>', self.on_testModuleSelected) self.all_tests_tree.tag_bind('TestCase', '<<TreeviewSelect>>', self.on_testCaseSelected) self.all_tests_tree.tag_bind('TestMethod', '<<TreeviewSelect>>', self.on_testMethodSelected) # The tree's vertical scrollbar self.all_tests_tree_scrollbar = Scrollbar(self.all_tests_tree_frame, orient=VERTICAL) self.all_tests_tree_scrollbar.grid(column=1, row=0, sticky=(N, S)) # Tie the scrollbar to the text views, and the text views # to each other. self.all_tests_tree.config(yscrollcommand=self.all_tests_tree_scrollbar.set) self.all_tests_tree_scrollbar.config(command=self.all_tests_tree.yview) # The tree for problem tests self.problems_tree_frame = Frame(self.content) self.problems_tree_frame.grid(column=0, row=0, sticky=(N, S, E, W)) self.tree_notebook.add(self.problems_tree_frame, text='Problems') self.problems_tree = Treeview(self.problems_tree_frame) self.problems_tree.grid(column=0, row=0, sticky=(N, S, E, W)) # Set up the tag colors for tree nodes. for status, config in STATUS.items(): self.problems_tree.tag_configure(config['tag'], foreground=config['color']) self.problems_tree.tag_configure('inactive', foreground='lightgray') # Problem tree only deals with selection, not clicks. self.problems_tree.tag_bind('TestModule', '<<TreeviewSelect>>', self.on_testModuleSelected) self.problems_tree.tag_bind('TestCase', '<<TreeviewSelect>>', self.on_testCaseSelected) self.problems_tree.tag_bind('TestMethod', '<<TreeviewSelect>>', self.on_testMethodSelected) # The tree's vertical scrollbar self.problems_tree_scrollbar = Scrollbar(self.problems_tree_frame, orient=VERTICAL) self.problems_tree_scrollbar.grid(column=1, row=0, sticky=(N, S)) # Tie the scrollbar to the text views, and the text views # to each other. self.problems_tree.config(yscrollcommand=self.problems_tree_scrollbar.set) self.problems_tree_scrollbar.config(command=self.all_tests_tree.yview) # The right-hand side frame on the main content area self.details_frame = Frame(self.content) self.details_frame.grid(column=0, row=0, sticky=(N, S, E, W)) self.content.add(self.details_frame) # Set up the content in the details panel # Test Name self.name_label = Label(self.details_frame, text='Name:') self.name_label.grid(column=0, row=0, pady=5, sticky=(E,)) self.name = StringVar() self.name_widget = Entry(self.details_frame, textvariable=self.name) self.name_widget.configure(state='readonly') self.name_widget.grid(column=1, row=0, pady=5, sticky=(W, E)) # Test status self.test_status = StringVar() self.test_status_widget = Label(self.details_frame, textvariable=self.test_status, width=1, anchor=CENTER) f = Font(font=self.test_status_widget['font']) f['weight'] = 'bold' f['size'] = 50 self.test_status_widget.config(font=f) self.test_status_widget.grid(column=2, row=0, padx=15, pady=5, rowspan=2, sticky=(N, W, E, S)) # Test duration self.duration_label = Label(self.details_frame, text='Duration:') self.duration_label.grid(column=0, row=1, pady=5, sticky=(E,)) self.duration = StringVar() self.duration_widget = Entry(self.details_frame, textvariable=self.duration) self.duration_widget.grid(column=1, row=1, pady=5, sticky=(E, W,)) # Test description self.description_label = Label(self.details_frame, text='Description:') self.description_label.grid(column=0, row=2, pady=5, sticky=(N, E,)) self.description = ReadOnlyText(self.details_frame, width=80, height=4) self.description.grid(column=1, row=2, pady=5, columnspan=2, sticky=(N, S, E, W,)) self.description_scrollbar = Scrollbar(self.details_frame, orient=VERTICAL) self.description_scrollbar.grid(column=3, row=2, pady=5, sticky=(N, S)) self.description.config(yscrollcommand=self.description_scrollbar.set) self.description_scrollbar.config(command=self.description.yview) # Test output self.output_label = Label(self.details_frame, text='Output:') self.output_label.grid(column=0, row=3, pady=5, sticky=(N, E,)) self.output = ReadOnlyText(self.details_frame, width=80, height=4) self.output.grid(column=1, row=3, pady=5, columnspan=2, sticky=(N, S, E, W,)) self.output_scrollbar = Scrollbar(self.details_frame, orient=VERTICAL) self.output_scrollbar.grid(column=3, row=3, pady=5, sticky=(N, S)) self.output.config(yscrollcommand=self.output_scrollbar.set) self.output_scrollbar.config(command=self.description.yview) # Error message self.error_label = Label(self.details_frame, text='Error:') self.error_label.grid(column=0, row=4, pady=5, sticky=(N, E,)) self.error = ReadOnlyText(self.details_frame, width=80) self.error.grid(column=1, row=4, pady=5, columnspan=2, sticky=(N, S, E, W)) self.error_scrollbar = Scrollbar(self.details_frame, orient=VERTICAL) self.error_scrollbar.grid(column=3, row=4, pady=5, sticky=(N, S)) self.error.config(yscrollcommand=self.error_scrollbar.set) self.error_scrollbar.config(command=self.error.yview) # Status bar self.statusbar = Frame(self.root) self.statusbar.grid(column=0, row=2, sticky=(W, E)) # Current status self.run_status = StringVar() self.run_status_label = Label(self.statusbar, textvariable=self.run_status) self.run_status_label.grid(column=0, row=0, sticky=(W, E)) self.run_status.set('Not running') # Test result summary self.run_summary = StringVar() self.run_summary_label = Label(self.statusbar, textvariable=self.run_summary) self.run_summary_label.grid(column=1, row=0, sticky=(W, E)) self.run_summary.set('P:0 F:0 E:0 X:0 U:0 S:0') # Test progress self.progress_value = IntVar() self.progress = Progressbar(self.statusbar, orient=HORIZONTAL, length=200, mode='determinate', maximum=100, variable=self.progress_value) self.progress.grid(column=2, row=0, sticky=(W, E)) # Set up listeners for runner events. Executor.bind('test_status_update', self.on_executorStatusUpdate) Executor.bind('test_start', self.on_executorTestStart) Executor.bind('test_end', self.on_executorTestEnd) Executor.bind('suite_end', self.on_executorSuiteEnd) Executor.bind('suite_error', self.on_executorSuiteError) # Main window resize handle self.grip = Sizegrip(self.statusbar) self.grip.grid(column=3, row=0, sticky=(S, E)) # Now configure the weights for the frame grids self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=0) self.root.rowconfigure(1, weight=1) self.root.rowconfigure(2, weight=0) self.toolbar.columnconfigure(0, weight=0) self.toolbar.rowconfigure(0, weight=1) self.content.columnconfigure(0, weight=1) self.content.rowconfigure(0, weight=1) self.content.pane(0, weight=1) self.content.pane(1, weight=2) self.statusbar.columnconfigure(0, weight=1) self.statusbar.columnconfigure(1, weight=0) self.statusbar.columnconfigure(2, weight=0) self.statusbar.columnconfigure(3, weight=0) self.statusbar.rowconfigure(0, weight=1) self.all_tests_tree_frame.columnconfigure(0, weight=1) self.all_tests_tree_frame.columnconfigure(1, weight=0) self.all_tests_tree_frame.rowconfigure(0, weight=1) self.problems_tree_frame.columnconfigure(0, weight=1) self.problems_tree_frame.columnconfigure(1, weight=0) self.problems_tree_frame.rowconfigure(0, weight=1) self.details_frame.columnconfigure(0, weight=0) self.details_frame.columnconfigure(1, weight=1) self.details_frame.columnconfigure(2, weight=0) self.details_frame.columnconfigure(3, weight=0) self.details_frame.columnconfigure(4, weight=0) self.details_frame.rowconfigure(0, weight=0) self.details_frame.rowconfigure(1, weight=0) self.details_frame.rowconfigure(2, weight=1) self.details_frame.rowconfigure(3, weight=5) self.details_frame.rowconfigure(4, weight=10) # Now that we've laid out the grid, hide the error and output text # until we actually have an error/output to display self._hide_test_output() self._hide_test_errors()
def __init__(self, root): ''' ----------------------------------------------------- | main button toolbar | ----------------------------------------------------- | < ma | in content area > | | | | | left | right | | control | details frame | | tree | / output viewer | | area | | ----------------------------------------------------- | status bar area | ----------------------------------------------------- ''' self._project = None self.executor = None self.finder = None # Root window self.root = root self.root.title('Cricket') self.root.geometry('1024x768') # Prevent the menus from having the empty tearoff entry self.root.option_add('*tearOff', FALSE) # Catch the close button self.root.protocol("WM_DELETE_WINDOW", self.on_quit) # Catch the "quit" event. self.root.createcommand('exit', self.on_quit) # Menubar self.menubar = Menu(self.root) # self.menu_Apple = Menu(self.menubar, name='Apple') # self.menubar.add_cascade(menu=self.menu_Apple) self.menu_file = Menu(self.menubar) self.menubar.add_cascade(menu=self.menu_file, label='File') self.menu_edit = Menu(self.menubar) self.menubar.add_cascade(menu=self.menu_edit, label='Edit') # self.menu_help = Menu(self.menubar, name='help') # self.menubar.add_cascade(menu=self.menu_help) # self.menu_Apple.add_command(label='Test', command=self.cmd_dummy) # self.menu_file.add_command(label='New', command=self.cmd_dummy, accelerator="Command-N") # self.menu_file.add_command(label='Open...', command=self.cmd_dummy) # self.menu_file.add_command(label='Close', command=self.cmd_dummy) # self.menu_edit.add_command(label='New', command=self.cmd_dummy) # self.menu_edit.add_command(label='Open...', command=self.cmd_dummy) # self.menu_edit.add_command(label='Close', command=self.cmd_dummy) # self.menu_help.add_command(label='Test', command=self.cmd_dummy) # last step - configure the menubar self.root['menu'] = self.menubar self._setup_btn_toolbar() self._setup_main_content() # Create the tree/control area on the left frame self._setup_left_frame() # Create the output/viewer area on the right frame self._setup_right_frame() # Create the status bar area at the bottom self._setup_status_bar() # Test progress self.progress_value = IntVar() self.progress = Progressbar(self.statusbar, orient=HORIZONTAL, length=200, mode='determinate', maximum=100, variable=self.progress_value) self.progress.grid(column=2, row=0, sticky=(W, E)) # Set up listeners for runner events. Executor.bind('test_status_update', self.on_executorStatusUpdate) Executor.bind('test_start', self.on_executorTestStart) Executor.bind('test_end', self.on_executorTestEnd) Executor.bind('suite_end', self.on_executorSuiteEnd) Executor.bind('suite_error', self.on_executorSuiteError) # Main window resize handle self.grip = Sizegrip(self.statusbar) self.grip.grid(column=3, row=0, sticky=(S, E)) # Configure the weights of the frame grids self._configure_gui_weights() # Now that we've laid out the grid, hide the error and output text # until we actually have an error/output to display self._hide_test_output() self._hide_test_errors()