class UITester(TkApplication): def __init__(self, uifile, rootwidget, rootmenu=None, master=None): self.uifile = uifile self.rootwidget = rootwidget self.rootmenu = rootmenu TkApplication.__init__(self, master) def _create_ui(self): self.builder = Builder() self.builder.add_from_file(self.uifile) self.builder.get_object(self.rootwidget, self.master) if self.rootmenu: menu = self.builder.get_object(self.rootmenu, top) self.set_menu(menu) #show callbacks defined bag = {} callbacks = self.builder.connect_callbacks({}) if callbacks is not None: for cb in callbacks: def create_cb(cbname): def dummy_cb(event=None): print('on:', cbname) return dummy_cb bag[cb] = create_cb(cb) self.builder.connect_callbacks(bag) self.set_title('Pygubu UI Tester') self.set_resizable()
class UITester(TkApplication): def __init__(self, uifile, rootwidget, rootmenu=None, master=None): self.uifile = uifile self.rootwidget = rootwidget self.rootmenu = rootmenu TkApplication.__init__(self, master) def _create_ui(self): self.builder = Builder() self.builder.add_from_file(self.uifile) self.builder.get_object(self.rootwidget, self.master) if self.rootmenu: menu = self.builder.get_object(self.rootmenu, top) self.set_menu(menu) #show callbacks defined bag = {} callbacks = self.builder.connect_callbacks({}) if callbacks is not None: for cb in callbacks: def create_cb(cbname): def dummy_cb(event=None): print('on:', cbname) return dummy_cb bag[cb] = create_cb(cb) self.builder.connect_callbacks(bag) self.set_title('Pygubu UI Tester') self.set_resizable()
class UITester(TkApplication): def _create_ui(self): self.builder = Builder() self.builder.add_from_file(sys.argv[1]) self.builder.get_object('mainwindow', self.master) try: menu = self.builder.get_object('mainmenu', top) self.set_menu(menu) except: pass #show callbacks defined self.builder.connect_callbacks({}) self.set_title('Pygubu UI tester') self.set_resizable()
class UITester(TkApplication): def _create_ui(self): self.builder = Builder() self.builder.add_from_file(sys.argv[1]) self.builder.get_object('mainwindow', self.master) try: menu = self.builder.get_object('mainmenu', top) self.set_menu(menu) except: pass #show callbacks defined self.builder.connect_callbacks({}) self.set_title('Pygubu UI tester') self.set_resizable()
class MainWindow(TkApplication): def _create_ui(self): self.pygubu_builder = Builder() self.pygubu_builder.add_from_file(path.join(SCRIPT_DIR, "forms", "main_window.ui")) self.secondary_window = SecondaryWindow(Toplevel()) # self.secondary_window.master.withdraw() self.predator = [None, None, None, None] self.drawer = PredatorDrawer(None) self.current_tab = 0 self.tabs = list() self.remaining_secs = 0 self.all_tab = None self.after_id = 0 self.isDrawOnAllScreenActive = [True, True, True, True] self.predator_factory = PredatorFactory() self.setup() def setup(self): self.set_title(PISCIS_TITLE) self.pygubu_builder.get_object('main_frame', self.master) self.set_menu(self.pygubu_builder.get_object('main_menu', self.master)) self.create_tabs() self.pygubu_builder.connect_callbacks(self) for i, item in enumerate(self.predator): draw_all_outlines(self.tabs[i], self.all_tab, self.secondary_window, i) def create_tabs(self): self.all_tab = self._create_canvas_tab('tab_all_screens') self.tabs.append(self._create_canvas_tab('tab_single_tab_one')) self.tabs.append(self._create_canvas_tab('tab_single_tab_two')) self.tabs.append(self._create_canvas_tab('tab_single_tab_three')) self.tabs.append(self._create_canvas_tab('tab_single_tab_four')) def _create_canvas_tab(self, identifier): if identifier == 'tab_all_screens': return AllCanvasTab(self.pygubu_builder.get_object(identifier, self.master)) else: self.current_tab += 1 return SingleCanvasTab(self.pygubu_builder.get_object(identifier, self.master), self.current_tab - 1, self) @staticmethod def on_about(): showinfo(PISCIS_TITLE, PISCIS_TITLE + " - " + PISCIS_VERSION + "\n" + PISCIS_CONTACT) def on_exit(self): self.stop_all_simulations() self.master.quit() def stop_all_simulations(self): for i, item in enumerate(self.predator): self.tabs[i].on_stop() def on_fullscreen(self): self.secondary_window.set_fullscreen() def on_change_fullscreen(self): new_color = askcolor(color=self.secondary_window.current_background_color, title="Change Background-Color")[1] self.secondary_window.change_background_color(new_color) def create_predator(self, color, target_diameter, scaling_velocity, starting_position=None): if starting_position is None: starting_position = .5, .5 self.predator_factory.starting_position = starting_position self.predator_factory.target_diameter = target_diameter self.predator_factory.scaling_velocity = scaling_velocity self.predator_factory.color = color return self.predator_factory.create() def get_predator_color(self): return self.predator_factory.color def start_predator(self, predator, id_number): if predator is None: showinfo("No Predator found", "Please place a stimuli first!") return self.isDrawOnAllScreenActive[id_number] = True predator.start_scaling(int(time.time() * 1000)) self.predator[id_number] = predator self.drawer.start() self.start_update() def start_update(self): self.after_id = self.master.after(25, self.update) def update(self): self.after_id = self.master.after(25, self.update) self.render() def render(self): for i, item in enumerate(self.predator): self.draw_predators(i, item) # self.drawer.draw_all_outlines(self.tabs[i], self.all_tab, self.secondary_window, i) def draw_predators(self, i, item): if item is not None: self.drawer.predator = item self.draw_predators_on_all_screens(i) def draw_predators_on_all_screens(self, i): if self.isDrawOnAllScreenActive[i]: self.drawer.draw_predator(self.tabs[i], self.all_tab, self.secondary_window, i) def change_background_color_of_all_canvas(self, id_number, color): self.all_tab.change_background(id_number, color) self.secondary_window.change_canvas_background(id_number, color) def stop_drawing(self): self.drawer.stop()
class SingleCanvasTab(TkApplication): def __init__(self, master, id_number, parent=None): TkApplication.__init__(self, master) self.id_number = id_number self.parent = parent self.change_background_color(self.current_background_color) self.target_diameter = 0 self.scaling_velocity = 0 self.remaining_secs_run = 0 self.remaining_secs_pause = 0 self.predator = None self.predator_draw_object = None self.starting_position = None self.run_timer = None self.pause_timer = None def _create_ui(self): self.pygubu_builder = Builder() self.pygubu_builder.add_from_file(path.join(SCRIPT_DIR, "forms", "single_canvas_tab.ui")) self.setup() def setup(self): self.canvas = self.pygubu_builder.get_object('canvas', self.master) self.canvas.bind("<Button-1>", self.set_starting_position) self.current_background_color = BACKGROUND_COLOR self.color = PREDATOR_COLOR self._create_scale_slider() self._create_speed_slider() self._create_interval_controls() self._create_buttons() self.pygubu_builder.connect_callbacks(self) def _create_scale_slider(self): self.pygubu_builder.get_object('scale', self.master) def _create_speed_slider(self): self.pygubu_builder.get_object('speed', self.master) def _create_interval_controls(self): self.pygubu_builder.get_object('interval', self.master) self.pygubu_builder.get_object('interval_run', self.master) self.pygubu_builder.get_object('interval_pause', self.master) self._create_running_interval_settings() self._create_pausing_interval_settings() def _create_pausing_interval_settings(self): self.interval_seconds_pause = self.pygubu_builder.get_object('spin_seconds_pause', self.master) self.interval_minutes_pause = self.pygubu_builder.get_object('spin_minutes_pause', self.master) self.remaining_secs_label_pause = self.pygubu_builder.get_object('remaining_secs_pause', self.master) def _create_running_interval_settings(self): self.interval_seconds_run = self.pygubu_builder.get_object('spin_seconds_run', self.master) self.interval_minutes_run = self.pygubu_builder.get_object('spin_minutes_run', self.master) self.remaining_secs_label_run = self.pygubu_builder.get_object('remaining_secs_run', self.master) def _create_buttons(self): self.pygubu_builder.get_object('background', self.master) self.pygubu_builder.get_object('stimuli_color', self.master) self.pygubu_builder.get_object('generate', self.master) self.pygubu_builder.get_object('simulate', self.master) def on_generate(self): self.canvas.delete(self.predator_draw_object) self.predator = self.parent.create_predator(self.color, self.target_diameter, self.scaling_velocity, self.starting_position) self.draw_preview_predator() self.parent.isDrawOnAllScreenActive[self.id_number] = False self.starting_position = None def draw_preview_predator(self): drawer = PredatorDrawer(self.predator) width, height = self.canvas.winfo_width(), self.canvas.winfo_height() begin_x, begin_y, end_x, end_y = drawer.calculate_coordinates(width, height, self.target_diameter) self.predator_draw_object = self.canvas.create_oval(begin_x, begin_y, end_x, end_y, fill=self.color, outline=self.color) def on_background(self): new_color = askcolor(color=self.current_background_color, title="Change Background-Color")[1] self.change_background_color(new_color) def on_stimuli_color(self): new_color = askcolor(color=self.parent.get_predator_color(), title="Change Predator-Color")[1] self.color = new_color if self.predator is not None: self.predator.color = self.color def on_scale_slider(self, value): self.target_diameter = float(value) if self.predator is not None: self.predator.set_target_diameter(self.target_diameter) def on_speed_slider(self, value): self.scaling_velocity = float(value) / 5 if self.predator is not None: self.predator.set_scaling_velocity(self.scaling_velocity) def on_start(self): self.parent.start_predator(self.predator, self.id_number) if self.remaining_secs_run > 0: self.update_pause_remaining_seconds_label() self.start_run_timer() def start_run_timer(self): self.run_timer = Timer(1.0, self.reduce_run_remaining_seconds) self.run_timer.start() def reduce_run_remaining_seconds(self): self.remaining_secs_run -= 1 self.update_run_remaining_seconds_label() if int(self.remaining_secs_run) > 0: self.start_run_timer() else: self.on_stop() self.update_run_remaining_seconds_label() self.set_run_remaining_seconds() self.start_pause_timer() def start_pause_timer(self): self.pause_timer = Timer(1.0, self.reduce_pause_remaining_seconds) self.pause_timer.start() def reduce_pause_remaining_seconds(self): self.remaining_secs_pause -= 1 self.update_pause_remaining_seconds_label() if int(self.remaining_secs_pause) > 0: self.start_pause_timer() else: self.update_pause_remaining_seconds_label() self.set_pause_remaining_seconds() self.on_start() def on_stop(self): self.stop_pause_timer() self.stop_run_timer() self.parent.stop_drawing() def stop_pause_timer(self): if self.pause_timer is not None: self.pause_timer.cancel() self.set_pause_remaining_seconds() def stop_run_timer(self): if self.run_timer is not None: self.run_timer.cancel() self.set_run_remaining_seconds() def on_pause_seconds_changed(self): self.set_pause_remaining_seconds() self.update_pause_remaining_seconds_label() def on_pause_minutes_changed(self): self.set_pause_remaining_seconds() self.update_pause_remaining_seconds_label() def set_pause_remaining_seconds(self): self.remaining_secs_pause = self.minutes_to_seconds(self.interval_minutes_pause.get()) + int( self.interval_seconds_pause.get()) def update_pause_remaining_seconds_label(self): self.remaining_secs_label_pause.configure(text=self.remaining_secs_pause) def on_run_seconds_changed(self): self.set_run_remaining_seconds() self.update_run_remaining_seconds_label() def on_run_minutes_changed(self): self.set_run_remaining_seconds() self.update_run_remaining_seconds_label() def set_run_remaining_seconds(self): self.remaining_secs_run = self.minutes_to_seconds(self.interval_minutes_run.get()) + int( self.interval_seconds_run.get()) def update_run_remaining_seconds_label(self): self.remaining_secs_label_run.configure(text=self.remaining_secs_run) def minutes_to_seconds(self, value): return int(value) * MIN_TO_SEC def change_background_color(self, color): self.canvas.configure(background=color) self.parent.change_background_color_of_all_canvas(color, self.id_number) self.current_background_color = color def set_starting_position(self, event): self.starting_position = event.x / self.canvas.winfo_width(), event.y / self.canvas.winfo_height() self.on_generate()
class MacronSetupWizard: def __init__(self): self.root = root = Tk() root.withdraw() root.title('Setup Wizard') root.geometry('500x360') root.iconbitmap(RESOURCE_PATH + 'icon.ico') # Center window root.update_idletasks() width = root.winfo_width() height = root.winfo_height() x = (root.winfo_screenwidth() // 2) - (width // 2) y = (root.winfo_screenheight() // 2) - (height // 2) root.geometry('{}x{}+{}+{}'.format(width, height, x, y)) root.deiconify() root.resizable(width=False, height=False) self.settings = { 'app_name': 'MacronApp', 'install_path': 'C:\Program Files', # TODO: Get default install path 'create_shortcut': True, 'start_after_setup': True } with open(RESOURCE_PATH + '.setupdata') as f: setupData = load(f) self.settings['app_name'] = setupData['app_name'] self.settings['app_repo_url'] = setupData['app_repo_url'] with open(RESOURCE_PATH + 'LICENSE') as f: self.settings['app_license'] = f.read() with open(RESOURCE_PATH + 'intro-view.xml') as f: self.navigate(f.read()) self.mainwindow = self.builder.get_object('Frame_0', root) self.root.title(self.settings['app_name'] + ' Setup Wizard') self.builder.get_object('WelcomeLabel').config( text='Welcome to the {} Setup Wizard'.format( self.settings['app_name'])) self.builder.get_object('IntroLabel').config( text='''This wizard will install {} on your computer. It is recommended that you close all other applications before continuing. Click Next to continue, or Cancel to exit Setup.'''.format( self.settings['app_name'])) # self.set_image( # (160, 310), # self.settings['setup_banner'], # self.builder.get_object('SetupBanner') # ) root.mainloop() def on_intro_next(self): with open(RESOURCE_PATH + 'license-view.xml') as f: self.navigate(f.read()) # self.set_image( # (60, 60), # self.settings['setup_logo'], # self.builder.get_object('SetupLogo') # ) self.builder.get_object('LicenseInput').delete('1.0', END) self.builder.get_object('LicenseInput').insert( '1.0', self.settings['app_license']) self.builder.get_object('LicenseInput').config(state=DISABLED) self.builder.get_object('Radiobutton_5').select() self.builder.get_object('Button_2').configure(state=DISABLED) def on_license_next(self): with open(RESOURCE_PATH + 'settings-view.xml') as f: self.navigate(f.read()) # self.set_image( # (60, 60), # self.settings['setup_logo'], # self.builder.get_object('SetupLogo') # ) self.builder.get_object('SetupReadyLabel').config( text='Setup is ready to download and install {} on your computer.'. format(self.settings['app_name'])) self.builder.get_object('Entry_2').insert( 0, self.settings['install_path']) self.builder.get_object('Checkbutton_3').select() self.builder.get_object('Checkbutton_4').select() def on_settings_next(self): self.settings['create_shortcut'] = self.builder.create_variable( 'boolean:create_shortcut').get() self.settings['start_after_setup'] = self.builder.create_variable( 'boolean:start_after_setup').get() with open(RESOURCE_PATH + 'download-view.xml') as f: self.navigate(f.read()) # self.set_image( # (60, 60), # self.settings['setup_logo'], # self.builder.get_object('SetupLogo') # ) self.builder.get_object('FinishButton').config(state=DISABLED) self.downloadThread = threading.Thread(target=self.download) self.downloadThread.start() def on_license_back(self): with open(RESOURCE_PATH + 'intro-view.xml') as f: self.navigate(f.read()) def on_settings_back(self): with open(RESOURCE_PATH + 'license-view.xml') as f: self.navigate(f.read()) def on_not_accept(self): self.builder.get_object('Button_2').configure(state=DISABLED) def on_accept(self): self.builder.get_object('Button_2').configure(state=NORMAL) def on_browse_dir(self): response = filedialog.askdirectory( title='Please select installation path...') self.settings['install_path'] = response entry = self.builder.get_object('Entry_2') entry.delete(0, END) entry.insert(0, response) def download(self): self.builder.get_object('DownloadStatusLabel').config( text="Obtaining latest release...") def reporthook(blocknum, blocksize, totalsize): self.builder.get_object('DownloadStatusLabel').config( text="Downloading...") readsofar = blocknum * blocksize if totalsize > 0: percent = readsofar * 1e2 / totalsize self.builder.create_variable('double:download_progress').set( percent) self.builder.get_object('DownloadRatio').config( # text='{:.1} %'.format(percent) text="{:.1f} / {:.1f} MB".format(readsofar / 1048576, totalsize / 1048576)) if readsofar >= totalsize: # near the end self.builder.get_object('DownloadStatusLabel').config( text="Download complete") self.builder.get_object('RetryButton').config( state=DISABLED) else: # total size is unknown pass try: repoURL = urlopen(self.settings['app_repo_url'] + '/.setupdata') data = repoURL.read() encoding = repoURL.info().get_content_charset('utf-8') latestSetupData = loads(data.decode(encoding)) try: # download filehandle, _ = urlretrieve( url=latestSetupData['app_repo_url'] + latestSetupData['latest_windows_dist_url'], reporthook=reporthook) try: # install self.builder.get_object('InstallStatusLabel').config( text="Installing...") ZipFile(filehandle).extractall( self.settings['install_path']) if self.settings['create_shortcut']: CoInitialize() appPath = '{}\\{}\\{}.exe'.format( self.settings['install_path'], self.settings['app_name'], self.settings['app_name']) self.createShortcut(path=os.path.join( desktop(), self.settings['app_name'].replace('_', ' ') + '.lnk'), target=appPath, wDir='{}\\{}'.format( self.settings['install_path'], self.settings['app_name']), icon=appPath) self.builder.get_object('InstallStatusLabel').config( text="Installation complete!") self.builder.get_object('FinishButton').config( state=NORMAL) except: messagebox.showwarning( title='{} Setup Wizard'.format( self.settings['app_name']), message= 'Setup is unable to install additional files. Please try again.' ) except: messagebox.showwarning( title='{} Setup Wizard'.format(self.settings['app_name']), message= 'Setup is unable to download additional files. Please make sure that you have an internet connection, then click Retry.' ) except: messagebox.showwarning( title='{} Setup Wizard'.format(self.settings['app_name']), message= 'An unexpected error occured. Setup wizard is unable to obtain additional files. Click Retry.' ) def on_finish(self): if self.settings['start_after_setup']: startfile('{}\\{}\\{}.exe'.format(self.settings['install_path'], self.settings['app_name'], self.settings['app_name'])) self.root.destroy() def on_retry_download(self): response = messagebox.showwarning( type=messagebox.YESNO, title='{} Setup Wizard'.format(self.settings['app_name']), message='Are you sure you want to retry downloading?') if response == 'yes': self.downloadThread = threading.Thread(target=self.download) self.downloadThread.start() def on_cancel(self): response = messagebox.showwarning( type=messagebox.OKCANCEL, title='{} Setup Wizard'.format(self.settings['app_name']), message='Are you sure you want to cancel the installation process?' ) if response == 'ok': # if self.downloadThread: self.downloadThread._Thread_stop() self.root.destroy() # Helpers def navigate(self, next_view_ui): self.builder = Builder() self.builder.add_from_string(next_view_ui) self.mainwindow = self.builder.get_object('Frame_0', self.root) self.builder.connect_callbacks(self) # convert bytes to MB.... GB... etc... def human_bytes(self, num): step_unit = 1000.0 #1024 bad the size for x in ['bytes', 'KB', 'MB', 'GB', 'TB']: if num < step_unit: return "%3.1f %s" % (num, x) num /= step_unit def createShortcut(self, path, target='', wDir='', icon=''): ext = path[-3:] if ext == 'url': shortcut = file(path, 'w') shortcut.write('[InternetShortcut]\n') shortcut.write('URL=%s' % target) shortcut.close() else: shell = Dispatch('WScript.Shell') shortcut = shell.CreateShortCut(path) shortcut.Targetpath = target shortcut.WorkingDirectory = wDir if icon == '': pass else: shortcut.IconLocation = icon shortcut.save()