class GameGUI: def __init__(self): self.app = Tk() self.app.title('Tic Tac Toe A.I') self.app.resizable(width=False, height=False) self.board = GameAI() self.font = Font(family = "Arial", size = 28) self.buttons = {} for x,y in self.board.fields: handler = lambda x = x, y = y: self.move(x,y) button = Button(self.app, command = handler, font = self.font, width = 2,height = 1) button.grid(row = y, column = x) self.buttons[x,y] = button handler = lambda: self.reset() button = Button(self.app,text = 'reset',command = handler) button.grid(row = self.board.dim+1, column = 0, columnspan = self.board.dim,sticky="WE") self.quit = Button(self.app,text = 'quit', command = self.app.quit) self.quit.grid(row = self.board.dim+2, column = 0, columnspan = self.board.dim,sticky="WE") print "Dear Player, to mave a move click on any button and wait for A.I..." def reset(self): self.board = GameAI() self.update() def move(self,x,y): self.app.config(cursor = "watch") self.app.update() self.board = self.board.move(x,y) self.update() move = self.board.best() if move: self.board = self.board.move(*move) self.update() self.app.config(cursor = "") def update(self): for (x,y) in self.board.fields: text = self.board.fields[x,y] self.buttons[x,y]['text'] = text self.buttons[x,y]['disabledforeground'] = 'black' if text == self.board.empty: self.buttons[x,y]['state'] = 'normal' else: self.buttons[x,y]['state'] = 'disabled' winning = self.board.won() if winning: for x,y in winning: self.buttons[x,y]['disabledforeground'] = 'red' for x,y in self.buttons: self.buttons[x,y]['state']= 'disabled' for (x,y) in self.board.fields: self.buttons[x,y].update() def mainloop(self): self.app.mainloop()
class GUI: def __init__(self): self.app = Tk() self.app.title('TicTacToe') self.app.resizable(width=False, height=False) self.board = Board() self.font = Font(family="Helvetica", size=32) self.buttons = {} for x,y in self.board.fields: handler = lambda x=x,y=y: self.move(x,y) button = Button(self.app, command=handler, font=self.font, width=2, height=1) button.grid(row=y, column=x) self.buttons[x,y] = button handler = lambda: self.reset() button = Button(self.app, text='reset', command=handler) button.grid(row=self.board.size+1, column=0, columnspan=self.board.size, sticky="WE") self.update() def reset(self): self.board = Board() self.update() def move(self,x,y): self.app.config(cursor="watch") self.app.update() self.board = self.board.move(x,y) self.update() move = self.board.best() if move: self.board = self.board.move(*move) self.update() self.app.config(cursor="") def update(self): for (x,y) in self.board.fields: text = self.board.fields[x,y] self.buttons[x,y]['text'] = text self.buttons[x,y]['disabledforeground'] = 'black' if text==self.board.empty: self.buttons[x,y]['state'] = 'normal' else: self.buttons[x,y]['state'] = 'disabled' winning = self.board.won() if winning: for x,y in winning: self.buttons[x,y]['disabledforeground'] = 'red' for x,y in self.buttons: self.buttons[x,y]['state'] = 'disabled' for (x,y) in self.board.fields: self.buttons[x,y].update() def mainloop(self): self.app.mainloop()
def main(): note_sample_window_size = 75 training_time = 10 number_of_keys = 4 if len(sys.argv) > 1: note_sample_window_size = int(sys.argv[1]) if len(sys.argv) > 2: training_time = int(sys.argv[2]) if len(sys.argv) > 3: number_of_keys = int(sys.argv[3]) # first, run the training function (clf, mb) = train(note_sample_window_size, train_time_sec=training_time, n_keys=number_of_keys) root = Tk() root.geometry("1000x400") MainWindow(root, clf, mb, note_sample_window_size) menubar = Menu(root) menubar.add_command(label="Quit", command=root.quit) # display the menu root.config(menu=menubar) root.mainloop()
currentMove = self.v self.top.destroy() class GameButton(): def __init__(self, i, master=None): self.numara = i self.satir = i / 3 self.sutun = i % 3 self.metin = StringVar() self.metin.set("") def clicked(): player(self.numara) self.gorunum = Button(root, command=clicked, bg='gray', width=200, height=150, image=renksizAdam) self.gorunum.grid(row=self.satir, column=self.sutun) root = Tk() root.wait_window(WhichColor(root).top) root.title('XOX Graphical Interface') menubar = Menu(root) menubar.add_command(label="NEW GAME", command=startGame) menubar.add_command(label="POINTS", command=points) menubar.add_command(label="EXIT", command=root.quit) root.config(menu=menubar) renksizAdam = ImageTk.PhotoImage(file="RenksizAdam.png") yesilAdam = ImageTk.PhotoImage(file="YesilAdam.png") sariAdam = ImageTk.PhotoImage(file="SariAdam.png") startGame() mainloop()
def main(): root = Tk() root.config(width=WINDOW_W, height=WINDOW_H) root.propagate(0) frame = Frame(root) main_menu = MainMenu(root) root.mainloop()
def build_root(): ui_root = Tk() # Build root drop-down menu and immediate child menus. main_menu = Menu(ui_root) file_submenu = Menu(main_menu, title="File") settings_submenu = Menu(main_menu, title="Settings") help_submenu = Menu(main_menu, title="Help") # File file_submenu.add_command(label="New Dataset...", command=dummy) file_submenu.add_command(label="Open...", command=dummy) file_submenu.add_command(label="Export...", command=dummy) file_submenu.add_separator() file_submenu.add_command(label="Quit", command=dummy) # Settings settings_submenu.add_command(label="PyNewhall Settings...", command=dummy) # Help help_submenu.add_command(label="About...", command=dummy) help_submenu.add_command(label="Documentation...", command=dummy) # Wrap up building main drop down menubar. main_menu.add_cascade(label="File", menu=file_submenu) main_menu.add_cascade(label="Settings", menu=settings_submenu) main_menu.add_cascade(label="Help", menu=help_submenu) ui_root.config(menu=main_menu) ui_root.mainloop()
class GUI: def __init__(self): self.app = Tk() self.app.title('TicTacToe') self.app.resizable(width=False, height=False) self.board = Board() self.font = Font(family="Helvetica", size=32) self.buttons = {} for x, y in self.board.fields: handler = lambda x=x, y=y: self.move(x, y) button = Button(self.app, command=handler, font=self.font, width=2, height=1) button.grid(row=y, column=x) self.buttons[x, y] = button handler = lambda: self.reset() button = Button(self.app, text='reset', command=handler) button.grid(row=self.board.size + 1, column=0, columnspan=self.board.size, sticky="WE") self.update() def reset(self): self.board = Board() self.update() def move(self, x, y): self.app.config(cursor="watch") self.app.update() self.board = self.board.move(x, y) self.update() move = self.board.best() if move: self.board = self.board.move(*move) self.update() self.app.config(cursor="") def update(self): for (x, y) in self.board.fields: text = self.board.fields[x, y] self.buttons[x, y]['text'] = text self.buttons[x, y]['disabledforeground'] = 'black' if text == self.board.empty: self.buttons[x, y]['state'] = 'normal' else: self.buttons[x, y]['state'] = 'disabled' winning = self.board.won() if winning: for x, y in winning: self.buttons[x, y]['disabledforeground'] = 'red' for x, y in self.buttons: self.buttons[x, y]['state'] = 'disabled' for (x, y) in self.board.fields: self.buttons[x, y].update() def mainloop(self): self.app.mainloop()
def main(): root = Tk() root.geometry("800x480") root.wm_title('faigh ar ais as an fharraige') if len(sys.argv) > 1 and sys.argv[1] == 'fs': root.wm_attributes('-fullscreen', True) faaaaf_item(root) root.config(cursor='none') root.mainloop()
def __init__(self): root = Tk() root.title("split data") root.geometry("200x200") menu = Menu(root) root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Load data",command = self.load_data) self.notifcation = Label(root,text="") self.notifcation.grid(row=0,column=0) root.mainloop()
class GUI: def __init__(self): self.app = Tk() self.app.title('War Game') self.app.resizable(width=False, height=False) self.font = Font(family="Helvetica", size=32) self.buttons = {} self.board = Board('./boards/Smolensk.txt') self.size = SIZE for y in xrange(1, self.size + 1): for x in xrange(1, self.size + 1): handler = lambda x=x, y=y: self.move(x, y) button = Button(self.app, command=handler, font=self.font, width=3, height=1, text=self.board.values[y, x], background='gray') button.grid(row=y, column=x) self.buttons[x, y] = button handler = lambda: self.auto_move() button = Button(self.app, text='Start AI', command=handler) button.grid(row=self.size + 1, column=1, columnspan=self.size, sticky="WE") def auto_move(self): while self.board.nodes_left > 0: if self.board.player == 1: cost, (y, x) = self.board.root_negalphabeta() else: cost, (y, x) = self.board.root_negalphabeta() print 'Player: {} Heuristic {}'.format(self.board.player, cost) self.move(x, y) print 'Score: {}'.format(self.board.score) def move(self, x, y): self.app.config(cursor="watch") self.app.update() self.board.move(x, y) self.update(x, y) self.app.config(cursor="") def update(self, x, y): self.buttons[x, y]['state'] = 'disabled' for y in xrange(1, self.size + 1): for x in xrange(1, self.size + 1): self.buttons[x, y]['background'] = COLORS[self.board.colors[y, x]] self.buttons[x, y].update() def mainloop(self): self.app.mainloop()
def __init__(self): root = Tk() root.title("Fractal Dimension") root.geometry("200x200") menu = Menu(root) root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Load data",command = self.load_data) self.ca=[] max_size = 128 while max_size>0: self.ca.append(CaGrid(max_size,max_size)) max_size = max_size/2 root.mainloop()
def __init__(self): root = Tk() root.title("Fractal Dimension") root.geometry("200x200") menu = Menu(root) root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="Load data", command=self.load_data) self.ca = [] max_size = 128 while max_size > 0: self.ca.append(CaGrid(max_size, max_size)) max_size = max_size / 2 root.mainloop()
def __init__(self): master = Tk() master.style = ttk.Style() master.style.theme_use("default") master.config(bg=background_colour) master.resizable( 0, 0 ) # Disable resizing the UI to prevent having to make widget placing dynamic master.winfo_toplevel().title(frame_title) master.iconbitmap("bitcoin.ico") # Create pumper assistant to store data on the current BTC and alt holdings. self.pumper = pumper() self.create_title(master) self.create_api_info(master, previous_row=0) self.create_auto_sell(master, previous_row=3) self.create_stop_loss(master, previous_row=4) self.create_order_type(master, previous_row=6) self.create_fee_type(master, previous_row=7) self.create_btc_balance_picker(master, previous_row=8) self.create_alt_ticker(master, previous_row=10) self.create_pump_and_sell_buttons(master, previous_row=11) self.create_current_profit(master, previous_row=12) self.create_output_box(master, rightmost_column=1) # Can hardcode API key and Secret #self.api_key_entry.delete(0,END) #self.api_key_entry.insert(0,"KEY") #self.api_key_entry.config(state=DISABLED) #self.api_secret_entry.delete(0, END) #self.api_secret_entry.insert(0, "SECRET") #self.api_secret_entry.config(state=DISABLED) # Display the UI, this can only be called once per program. # Nothing in the main Python script will be run after creating the UI because of this. master.mainloop()
class PiPresents(object): def __init__(self): gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS | gc.DEBUG_SAVEALL) self.pipresents_issue = "1.3" self.pipresents_minorissue = '1.3.1g' # position and size of window without -f command line option self.nonfull_window_width = 0.45 # proportion of width self.nonfull_window_height = 0.7 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y = 0 # position of top left corner self.pp_background = 'black' StopWatch.global_enable = False # set up the handler for SIGTERM signal.signal(signal.SIGTERM, self.handle_sigterm) # **************************************** # Initialisation # *************************************** # get command line options self.options = command_options() # get Pi Presents code directory pp_dir = sys.path[0] self.pp_dir = pp_dir if not os.path.exists(pp_dir + "/pipresents.py"): if self.options['manager'] is False: tkMessageBox.showwarning( "Pi Presents", "Bad Application Directory:\n{0}".format(pp_dir)) exit(103) # Initialise logging and tracing Monitor.log_path = pp_dir self.mon = Monitor() # Init in PiPresents only self.mon.init() # uncomment to enable control of logging from within a class # Monitor.enable_in_code = True # enables control of log level in the code for a class - self.mon.set_log_level() # make a shorter list to log/trace only some classes without using enable_in_code. Monitor.classes = [ 'PiPresents', 'pp_paths', 'HyperlinkShow', 'RadioButtonShow', 'ArtLiveShow', 'ArtMediaShow', 'MediaShow', 'LiveShow', 'MenuShow', 'PathManager', 'ControlsManager', 'ShowManager', 'PluginManager', 'MplayerDriver', 'OMXDriver', 'UZBLDriver', 'KbdDriver', 'GPIODriver', 'TimeOfDay', 'ScreenDriver', 'Animate', 'OSCDriver' ] # Monitor.classes=['PiPresents','ArtMediaShow','VideoPlayer','OMXDriver'] # get global log level from command line Monitor.log_level = int(self.options['debug']) Monitor.manager = self.options['manager'] # print self.options['manager'] self.mon.newline(3) self.mon.log( self, "Pi Presents is starting, Version:" + self.pipresents_minorissue) # self.mon.log (self," OS and separator:" + os.name +' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: " + sys.path[0]) if os.geteuid() != 0: user = os.getenv('USER') else: user = os.getenv('SUDO_USER') self.mon.log(self, 'User is: ' + user) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # does not work # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # does not work # optional other classes used self.root = None self.ppio = None self.tod = None self.animate = None self.gpiodriver = None self.oscdriver = None self.osc_enabled = False self.gpio_enabled = False self.tod_enabled = False # get home path from -o option self.pp_home = pp_paths.get_home(self.options['home']) if self.pp_home is None: self.end('error', 'Failed to find pp_home') # get profile path from -p option # pp_profile is the full path to the directory that contains # pp_showlist.json and other files for the profile self.pp_profile = pp_paths.get_profile_dir(self.pp_home, self.options['profile']) if self.pp_profile is None: self.end('error', 'Failed to find profile') # check profile exists if os.path.exists(self.pp_profile): self.mon.log( self, "Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.mon.err( self, "Failed to find requested profile: " + self.pp_profile) self.end('error', 'Failed to find profile') self.mon.start_stats(self.options['profile']) # check 'verify' option if self.options['verify'] is True: val = Validator() if val.validate_profile(None, pp_dir, self.pp_home, self.pp_profile, self.pipresents_issue, False) is False: self.mon.err(self, "Validation Failed") self.end('error', 'Validation Failed') # initialise and read the showlist in the profile self.showlist = ShowList() self.showlist_file = self.pp_profile + "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self, "showlist not found at " + self.showlist_file) self.end('error', 'showlist not found') # check profile and Pi Presents issues are compatible if float(self.showlist.sissue()) != float(self.pipresents_issue): self.mon.err( self, "Version of profile " + self.showlist.sissue() + " is not same as Pi Presents, must exit") self.end('error', 'wrong version of profile') # get the 'start' show from the showlist index = self.showlist.index_of_show('start') if index >= 0: self.showlist.select(index) self.starter_show = self.showlist.selected_show() else: self.mon.err(self, "Show [start] not found in showlist") self.end('error', 'start show not found') if self.starter_show['start-show'] == '': self.mon.warn(self, "No Start Shows in Start Show") # ******************** # SET UP THE GUI # ******************** # turn off the screenblanking and saver if self.options['noblank'] is True: call(["xset", "s", "off"]) call(["xset", "s", "-dpms"]) self.root = Tk() self.title = 'Pi Presents - ' + self.pp_profile self.icon_text = 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg=self.pp_background) self.mon.log( self, 'native screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixcels') if self.options['screensize'] == '': self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() else: reason, message, self.screen_width, self.screen_height = self.parse_screen( self.options['screensize']) if reason == 'error': self.mon.err(self, message) self.end('error', message) self.mon.log( self, 'commanded screen dimensions are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixcels') # set window dimensions and decorations if self.options['fullscreen'] is False: self.window_width = int(self.root.winfo_screenwidth() * self.nonfull_window_width) self.window_height = int(self.root.winfo_screenheight() * self.nonfull_window_height) self.window_x = self.nonfull_window_x self.window_y = self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width, self.window_height, self.window_x, self.window_y)) else: self.window_width = self.screen_width self.window_height = self.screen_height self.root.attributes('-fullscreen', True) os.system( 'unclutter 1>&- 2>&- &' ) # Suppress 'someone created a subwindow' complaints from unclutter self.window_x = 0 self.window_y = 0 self.root.geometry("%dx%d%+d%+d" % (self.window_width, self.window_height, self.window_x, self.window_y)) self.root.attributes('-zoomed', '1') # canvs cover the whole screen whatever the size of the window. self.canvas_height = self.screen_height self.canvas_width = self.screen_width # make sure focus is set. self.root.focus_set() # define response to main window closing. self.root.protocol("WM_DELETE_WINDOW", self.handle_user_abort) # setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg=self.pp_background) if self.options['fullscreen'] is True: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) else: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=1, highlightcolor='yellow') self.canvas.place(x=0, y=0) # self.canvas.config(bg='black') self.canvas.focus_set() # **************************************** # INITIALISE THE INPUT DRIVERS # **************************************** # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs/ # use keyboard driver to bind keys to symbolic names and to set up callback kbd = KbdDriver() if kbd.read(pp_dir, self.pp_home, self.pp_profile) is False: self.end('error', 'cannot find or error in keys.cfg') kbd.bind_keys(self.root, self.handle_input_event) self.sr = ScreenDriver() # read the screen click area config file reason, message = self.sr.read(pp_dir, self.pp_home, self.pp_profile) if reason == 'error': self.end('error', 'cannot find screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes # click areas are made on the Pi Presents canvas not the show canvases. reason, message = self.sr.make_click_areas(self.canvas, self.handle_input_event) if reason == 'error': self.mon.err(self, message) self.end('error', message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required = False self.exitpipresents_required = False # kick off GPIO if enabled by command line option self.gpio_enabled = False if os.path.exists(self.pp_profile + os.sep + 'pp_io_config' + os.sep + 'gpio.cfg'): # initialise the GPIO self.gpiodriver = GPIODriver() reason, message = self.gpiodriver.init(pp_dir, self.pp_home, self.pp_profile, self.canvas, 50, self.handle_input_event) if reason == 'error': self.end('error', message) else: self.gpio_enabled = True # and start polling gpio self.gpiodriver.poll() # kick off animation sequencer self.animate = Animate() self.animate.init(pp_dir, self.pp_home, self.pp_profile, self.canvas, 200, self.handle_output_event) self.animate.poll() #create a showmanager ready for time of day scheduler and osc server show_id = -1 self.show_manager = ShowManager(show_id, self.showlist, self.starter_show, self.root, self.canvas, self.pp_dir, self.pp_profile, self.pp_home) # first time through set callback to terminate Pi Presents if all shows have ended. self.show_manager.init(self.canvas, self.all_shows_ended_callback, self.handle_command, self.showlist) # Register all the shows in the showlist reason, message = self.show_manager.register_shows() if reason == 'error': self.mon.err(self, message) self.end('error', message) # Init OSCDriver, read config and start OSC server self.osc_enabled = False if os.path.exists(self.pp_profile + os.sep + 'pp_io_config' + os.sep + 'osc.cfg'): self.oscdriver = OSCDriver() reason, message = self.oscdriver.init( self.pp_profile, self.handle_command, self.handle_input_event, self.e_osc_handle_output_event) if reason == 'error': self.end('error', message) else: self.osc_enabled = True self.root.after(1000, self.oscdriver.start_server()) # and run the start shows self.run_start_shows() # set up the time of day scheduler including catchup self.tod_enabled = False if os.path.exists(self.pp_profile + os.sep + 'schedule.json'): # kick off the time of day scheduler which may run additional shows self.tod = TimeOfDay() self.tod.init(pp_dir, self.pp_home, self.pp_profile, self.root, self.handle_command) self.tod_enabled = True # then start the time of day scheduler if self.tod_enabled is True: self.tod.poll() # start Tkinters event loop self.root.mainloop() def parse_screen(self, size_text): fields = size_text.split('*') if len(fields) != 2: return 'error', 'do not understand --fullscreen comand option', 0, 0 elif fields[0].isdigit() is False or fields[1].isdigit() is False: return 'error', 'dimensions are not positive integers in ---fullscreen', 0, 0 else: return 'normal', '', int(fields[0]), int(fields[1]) # ********************* # RUN START SHOWS # ******************** def run_start_shows(self): self.mon.trace(self, 'run start shows') # parse the start shows field and start the initial shows show_refs = self.starter_show['start-show'].split() for show_ref in show_refs: reason, message = self.show_manager.control_a_show( show_ref, 'open') if reason == 'error': self.mon.err(self, message) # ********************* # User inputs # ******************** # handles one command provided as a line of text def handle_command(self, command_text): self.mon.log(self, "command received: " + command_text) if command_text.strip() == "": return if command_text[0] == '/': if self.osc_enabled is True: self.oscdriver.send_command(command_text) return fields = command_text.split() show_command = fields[0] if len(fields) > 1: show_ref = fields[1] else: show_ref = '' if show_command in ('open', 'close'): if self.shutdown_required is False: reason, message = self.show_manager.control_a_show( show_ref, show_command) else: return elif show_command == 'exitpipresents': self.exitpipresents_required = True if self.show_manager.all_shows_exited() is True: # need root.after to get out of st thread self.root.after(1, self.e_all_shows_ended_callback) return else: reason, message = self.show_manager.exit_all_shows() elif show_command == 'shutdownnow': # need root.after to get out of st thread self.root.after(1, self.e_shutdown_pressed) return else: reason = 'error' message = 'command not recognised: ' + show_command if reason == 'error': self.mon.err(self, message) return def e_all_shows_ended_callback(self): self.all_shows_ended_callback('normal', 'no shows running') def e_shutdown_pressed(self): self.shutdown_pressed('now') def e_osc_handle_output_event(self, line): #jump out of server thread self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg)) def osc_handle_output_event(self, line): self.mon.log(self, "output event received: " + line) #osc sends output events as a string reason, message, delay, name, param_type, param_values = self.animate.parse_animate_fields( line) if reason == 'error': self.mon.err(self, message) self.end(reason, message) self.handle_output_event(name, param_type, param_values, 0) def handle_output_event(self, symbol, param_type, param_values, req_time): if self.gpio_enabled is True: reason, message = self.gpiodriver.handle_output_event( symbol, param_type, param_values, req_time) if reason == 'error': self.mon.err(self, message) self.end(reason, message) else: self.mon.warn(self, 'GPIO not enabled') # all input events call this callback with a symbolic name. # handle events that affect PP overall, otherwise pass to all active shows def handle_input_event(self, symbol, source): self.mon.log(self, "event received: " + symbol + ' from ' + source) if symbol == 'pp-terminate': self.handle_user_abort() elif symbol == 'pp-shutdown': self.shutdown_pressed('delay') elif symbol == 'pp-shutdownnow': # need root.after to grt out of st thread self.root.after(1, self.e_shutdown_pressed) return elif symbol == 'pp-exitpipresents': self.exitpipresents_required = True if self.show_manager.all_shows_exited() is True: # need root.after to grt out of st thread self.root.after(1, self.e_all_shows_ended_callback) return reason, message = self.show_manager.exit_all_shows() else: # events for shows affect the show and could cause it to exit. for show in self.show_manager.shows: show_obj = show[ShowManager.SHOW_OBJ] if show_obj is not None: show_obj.handle_input_event(symbol) def shutdown_pressed(self, when): if when == 'delay': self.root.after(5000, self.on_shutdown_delay) else: self.shutdown_required = True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal', 'no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def on_shutdown_delay(self): # 5 second delay is up, if shutdown button still pressed then shutdown if self.gpiodriver.shutdown_pressed() is True: self.shutdown_required = True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal', 'no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def handle_sigterm(self, signum, frame): self.mon.log(self, 'SIGTERM received - ' + str(signum)) self.terminate() def handle_user_abort(self): self.mon.log(self, 'User abort received') self.terminate() def terminate(self): self.mon.log(self, "terminate received") needs_termination = False for show in self.show_manager.shows: # print show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF] if show[ShowManager.SHOW_OBJ] is not None: needs_termination = True self.mon.log( self, "Sent terminate to show " + show[ShowManager.SHOW_REF]) # call shows terminate method # eventually the show will exit and after all shows have exited all_shows_callback will be executed. show[ShowManager.SHOW_OBJ].terminate() if needs_termination is False: self.end('killed', 'killed - no termination of shows required') # ****************************** # Ending Pi Presents after all the showers and players are closed # ************************** # callback from ShowManager when all shows have ended def all_shows_ended_callback(self, reason, message): self.canvas.config(bg=self.pp_background) if reason in ( 'killed', 'error' ) or self.shutdown_required is True or self.exitpipresents_required is True: self.end(reason, message) def end(self, reason, message): self.mon.log(self, "Pi Presents ending with reason: " + reason) if self.root is not None: self.root.destroy() self.tidy_up() # gc.collect() # print gc.garbage if reason == 'killed': self.mon.log(self, "Pi Presents Aborted, au revoir") # close logging files self.mon.finish() sys.exit(101) elif reason == 'error': self.mon.log(self, "Pi Presents closing because of error, sorry") # close logging files self.mon.finish() sys.exit(102) else: self.mon.log(self, "Pi Presents exiting normally, bye") # close logging files self.mon.finish() if self.shutdown_required is True: # print 'SHUTDOWN' call(['sudo', 'shutdown', '-h', '-t 5', 'now']) sys.exit(100) else: sys.exit(100) # tidy up all the peripheral bits of Pi Presents def tidy_up(self): self.mon.log(self, "Tidying Up") # turn screen blanking back on if self.options['noblank'] is True: call(["xset", "s", "on"]) call(["xset", "s", "+dpms"]) # tidy up animation and gpio if self.animate is not None: self.animate.terminate() if self.gpio_enabled == True: self.gpiodriver.terminate() if self.osc_enabled is True: self.oscdriver.terminate() # tidy up time of day scheduler if self.tod_enabled is True: self.tod.terminate()
class GUI: def __init__(self): self.app = Tk() self.app.title('Connect4') self.app.resizable(width=False, height=False) self.board = Board() self.buttons = {} self.frame = Frame(self.app, borderwidth=1, relief="raised") self.tiles = {} for x in range(self.board.width): handler = lambda x=x: self.move(x) button = Button(self.app, command=handler, font=Font(family="Helvetica", size=14), text=x + 1) button.grid(row=0, column=x, sticky="WE") self.buttons[x] = button self.frame.grid(row=1, column=0, columnspan=self.board.width) for x, y in self.board.fields: tile = Canvas(self.frame, width=60, height=50, bg="navy", highlightthickness=0) tile.grid(row=self.board.height - 1 - y, column=x) self.tiles[x, y] = tile handler = lambda: self.reset() self.restart = Button(self.app, command=handler, text='reset') self.restart.grid(row=2, column=0, columnspan=self.board.width, sticky="WE") self.update() def reset(self): self.board = Board() self.update() def move(self, x): self.app.config(cursor="watch") self.app.update() self.board = self.board.move(x) self.update() move = self.board.best() if move != None: self.board = self.board.move(move) self.update() self.app.config(cursor="") def update(self): for (x, y) in self.board.fields: text = self.board.fields[x, y] if (text == '.'): self.tiles[x, y].create_oval(10, 5, 50, 45, fill="black", outline="blue", width=1) if (text == 'X'): self.tiles[x, y].create_oval(10, 5, 50, 45, fill="yellow", outline="blue", width=1) if (text == 'O'): self.tiles[x, y].create_oval(10, 5, 50, 45, fill="red", outline="blue", width=1) for x in range(self.board.width): if self.board.fields[x, self.board.height - 1] == self.board.empty: self.buttons[x]['state'] = 'normal' else: self.buttons[x]['state'] = 'disabled' winning = self.board.won() if winning: for x, y in winning: self.tiles[x, y].create_oval(25, 20, 35, 30, fill="black") for x in range(self.board.width): self.buttons[x]['state'] = 'disabled' def mainloop(self): self.app.mainloop()
import sys from Tkinter import Tk from GUI import * if __name__ == '__main__': root = Tk() #WIDTH=int(sys.argv[1]) #HEIGHT=int(sys.argv[2]) WIDTH = 500 HEIGHT = 500 root.config(height=HEIGHT, width=WIDTH) app = NET_GUI(root, WIDTH, HEIGHT) #app = GUI(root, sys.argv[1], sys.argv[2]) app.master.title('NETWORK GRAPHICAL INTERFACE') app.master.after(0, app.gui_loop) #Run ~30FPS (Wich we could do 60... PCMR) root.mainloop()
class PokerMachine(): """Implements a video poker machine class.""" def __init__(self): """Instance initialization function.""" # Set up variables self.deck = pcards.Deck() self.cardimg = [] self.hand = None self.game_start = True self.game_postdeal = False self.game_easy = True self.game_over = False self.gifdir = "./images/" self.pot = 100 self.defaultbet = 5 self.bet = 5 self._set_up_gui() def button_clicked(self): """Event handler for button click. Callback method called by tk. """ if self.game_over: self._start_new_game() elif not self.game_postdeal: self._process_bet() elif self.game_postdeal: self._evaluate_hand() def flip(self, event): """Event handler which flips a clicked card. Callback method called by tk. """ if not self.game_postdeal: return if event.widget.flipped: event.widget.flipped = False event.widget.configure(image=event.widget.cardimage) else: event.widget.flipped = True event.widget.configure(image=self.backimg) def _start_new_game(self): """Returns the game an interface to its starting point.""" for cardimg in self.cardimg: cardimg.configure(image=self.backimg) cardimg.flipped = True self.game_over = False self.game_postdeal = False self.pot = 100 self.defaultbet = 5 self.bet = 5 self._update_pot() self.bet_amt_fld.configure(state=NORMAL) self.bet_str.set(str(self.defaultbet)) self.button.configure(text="Deal") self.status_lbl.configure(text="Click 'Deal' to play.") def _process_bet(self): """Processes the player's bet and deals a new hand if the bet is valid. """ # First check if played made a valid bet, # and return with no change in state (other # than resetting the bet field) if they did # not. b_str = self.bet_str.get() try: self.bet = int(b_str) except ValueError: self._show_bet_error("Bad bet!", "You must bet a whole number!") return if self.bet > self.pot: self._show_bet_error("Don't be greedy!", "You don't have that much money!") return elif self.bet < 1: self._show_bet_error("Don't get clever!", "You must bet a positive whole number!") return # We have a valid bet, so shuffle the deck # and get a new poker hand. self.deck.shuffle() self.hand = pcards.PokerHand(self.deck) self._show_cards() # Update game variables and GUI self.pot -= self.bet self._update_pot() self.button.configure(text="Exchange / skip") self.status_lbl.configure(text="Choose cards to exchange by " + "clicking on them.") self.bet_amt_fld.configure(state=DISABLED) self.game_postdeal = True def _evaluate_hand(self): """Evalutes a player's hand after any exchanges have been made and we have the final hand. Process winnings if we have any. """ # Player has flipped their cards if we're here, # so figure out which ones they flipped and # exchange them and show the new cards. xchg_str = "" for cardimg in self.cardimg: if cardimg.flipped: xchg_str += cardimg.pos self.hand.exchange(xchg_str) self._show_cards() # Calculate winnings and show status winnings = self.hand.video_winnings(self.bet, easy=self.game_easy) win_str = self.hand.show_value() + ". " if winnings: self.pot += winnings win_str += "You won ${0:}!".format(winnings) self._update_pot() else: win_str += "Sorry, no win!" if self.pot == 0: win_str += " Out of money - game over!" self.game_over = True self.status_lbl.configure(text=win_str) # Update game variables and GUI if self.game_over: self.button.configure(text="New game") else: self.button.configure(text="Deal again") self.bet_amt_fld.configure(state=NORMAL) # Reset the bet amount field with the default bet. Check # here to make sure the default bet is not more money that # is in the pot, and limit it to that amount if it is. self.defaultbet = self.bet if self.bet <= self.pot else self.pot self.bet_str.set(str(self.defaultbet)) self.game_postdeal = False # Discard and then drop the current hand self.hand.discard() self.hand = [] def _show_bet_error(self, title, message): """Shows a message box and resets the bet field in response to an invalid bet. """ tkMessageBox.showerror(title, message) self.bet = self.defaultbet self.bet_str.set(str(self.defaultbet)) def _update_pot(self): """Updates the pot amount label with the current pot.""" txt_str = "${0:}".format(self.pot) self.pot_amt_lbl.configure(text=txt_str) def _show_cards(self): """Shows the cards in the poker hand on the screen.""" for cardimg, idx in zip(self.cardimg, self.hand.index_list()): cardfile = "{0}{1}.gif".format(self.gifdir, str(idx + 1)) img = PhotoImage(file=cardfile) cardimg.configure(image=img) cardimg.cardimage = img cardimg.flipped = False def _set_up_gui(self): """Sets up the Tkinter user interface.""" # Disable pylint warning for instance attributes defined outside # __init__(), since this method is called by __init__() # # pylint: disable=W0201 self.root = Tk() self.root.title('Video Poker') # Set up menubar self.menubar = Menu(self.root) self.gamemenu = Menu(self.menubar, tearoff=0) self.gamemenu.add_command(label="Quit", command=sys.exit) self.menubar.add_cascade(label="Game", menu=self.gamemenu) self.helpmenu = Menu(self.menubar, tearoff=0) self.helpmenu.add_command(label="About", command=self.help_about) self.menubar.add_cascade(label="Help", menu=self.helpmenu) self.root.config(menu=self.menubar) # Set up card images self.backimg = PhotoImage(file="{0}b.gif".format(self.gifdir)) for num in range(5): lbl = Label(self.root, image=self.backimg) lbl.grid(row=0, column=num, padx=10, pady=10) lbl.bind("<Button-1>", self.flip) lbl.flipped = True lbl.pos = str(num + 1) self.cardimg.append(lbl) # Set up labels, fields and buttons self.pot_lbl = Label(self.root, text="Pot:") self.pot_lbl.grid(row=1, column=0, padx=10, pady=2, sticky=W) self.pot_amt_lbl = Label(self.root, text="") self.pot_amt_lbl.grid(row=1, column=1, columnspan=2, padx=10, pady=2, sticky=W) self._update_pot() self.bet_lbl = Label(self.root, text="Bet ($):") self.bet_lbl.grid(row=2, column=0, padx=10, pady=2, sticky=W) self.bet_str = StringVar() self.bet_str.set(str(self.defaultbet)) self.bet_amt_fld = Entry(self.root, textvariable=self.bet_str) self.bet_amt_fld.grid(row=2, column=1, columnspan=2, padx=10, pady=2, sticky=W) self.button = Button(self.root, text="Deal", command=self.button_clicked) self.button.grid(row=1, column=3, rowspan=2, columnspan=2, sticky=W + E + S + N, padx=10) self.status_lbl = Label(self.root, bd=1, relief=SUNKEN, text="Welcome to the casino! " + "Click 'Deal' to play!") self.status_lbl.grid(row=3, column=0, columnspan=5, padx=10, pady=10, ipadx=10, ipady=10, sticky=W + E + S + N) # Show winnings table lbl = Label(self.root, text="Winnings Table", relief=RAISED) lbl.grid(row=4, column=1, columnspan=3, pady=15, ipadx=10, ipady=10, sticky=W + E) # Two different tables, one for easy mode, one for normal # mode, so be prepared to show either one. wte = {2500: "Royal Flush", 250: "Straight Flush", 100: "Four of a Kind", 50: "Full House", 20: "Flush", 15: "Straight", 4: "Three of a Kind", 3: "Two Pair", 2: "Jacks or Higher"} wtn = {800: "Royal Flush", 50: "Straight Flush", 25: "Four of a Kind", 9: "Full House", 6: "Flush", 4: "Straight", 3: "Three of a Kind", 2: "Two Pair", 1: "Jacks or Higher"} wtxt = wte if self.game_easy else wtn row = 5 for key in sorted(wtxt.keys(), reverse=True): lbl = Label(self.root, text=wtxt[key]) lbl.grid(row=row, column=1, columnspan=2, sticky=W) lbl = Label(self.root, text="{0} : 1".format(key)) lbl.grid(row=row, column=3, sticky=E) row += 1 lbl = Label(self.root, text="") lbl.grid(row=row, column=0, columnspan=5, pady=15) # pylint: enable=W0201 def help_about(self): """Shows an 'about' modal dialog. Callback method called by tk. """ about_win = Toplevel(self.root) # Set up dialog lbl = Label(about_win, text="Video Poker") lbl.grid(row=0, column=0, padx=10, pady=(10, 0), sticky=W + N) lbl = Label(about_win, text="by Paul Griffiths") lbl.grid(row=1, column=0, padx=10, pady=(0, 7), sticky=W + N) lbl = Label(about_win, text="Written in Python, with tkinter.") lbl.grid(row=2, column=0, padx=10, pady=7, sticky=W + N) lbl = Label(about_win, text="Copyright 2013 Paul Griffiths") lbl.grid(row=4, column=0, padx=10, pady=(7, 0), sticky=W + N) lbl = Label(about_win, text="Email: [email protected]") lbl.grid(row=5, column=0, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="This program is free software: you can " + "redistribute it and/or modify it under the terms") lbl.grid(row=6, column=0, columnspan=2, padx=10, pady=0, sticky=W + N) lbl = Label(about_win, text="of the GNU General Public License as " + "published by the Free Software Foundation, either") lbl.grid(row=7, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="version 3 of the License, or " + "(at your option) any later version.") lbl.grid(row=8, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="This program is distributed in " + "the hope that it will be useful, but WITHOUT ANY WARRANTY;") lbl.grid(row=9, column=0, columnspan=2, padx=10, pady=0, sticky=W + N) lbl = Label(about_win, text="without even the implied " + "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR") lbl.grid(row=10, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="PURPOSE. See the " + "GNU General Public License for more details.") lbl.grid(row=11, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="You should have received a " + "copy of the GNU General Public License along with this") lbl.grid(row=12, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="program. If not, see " + "<http://www.gnu.org/licenses/>.") lbl.grid(row=13, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) img = PhotoImage(file="{0}27.gif".format(self.gifdir)) lbl = Label(about_win, image=img) lbl.grid(row=0, column=1, rowspan=5, padx=10, pady=10, sticky=N + E) btn = Button(about_win, text="OK", command=about_win.quit) btn.grid(row=14, column=0, columnspan=2, padx=0, pady=(0, 10), ipadx=30, ipady=3) # Show dialog about_win.transient(self.root) about_win.parent = self.root about_win.protocol("WM_DELETE_WINDOW", about_win.destroy) about_win.geometry("+{0}+{1}".format(self.root.winfo_rootx() + 50, self.root.winfo_rooty() + 50)) about_win.title("About Video Poker") about_win.focus_set() about_win.grab_set() about_win.mainloop() about_win.destroy()
class App_Runner: """ App runner that uses a Board and a Palette. """ def __init__(self, on_init, app_name, dev_stage, file_extension, deserializers, board_width, board_height, palette_height, directed_wires, label_tooltips_enabled, same_label_per_connector, init_file=None): """ |on_init|: method called every time a new board of this app's type is created. |app_name|: name of this app. |dev_stage|: development stage of this app. |file_extension|: the file extension used for boards of this app's type. |deserializers|: drawabel types to open files of this app's type. |board_width|, |board_height|: board dimensions. |palette_height|: height of palette, width will be the same as board width. |directed_wires|: True if the board is to have directed wires, False otherwise. |label_tooltips_enabled|: if True, show wire and drawable label tooltips. |same_label_per_connector|: if True, all wires from a connector will have the same label. If False, this will only be true for wire connectors. |init_file|: file to open at init time. """ self._on_init = on_init self._app_name = app_name self._dev_stage = dev_stage self._file_extension = file_extension self._deserializers = deserializers self._board_width = board_width self._board_height = board_height self._palette_height = palette_height self._directed_wires = directed_wires self._label_tooltips_enabled = label_tooltips_enabled self._same_label_per_connector = same_label_per_connector self._init_file = init_file self._init() self._setup_menu() self._setup_shortcuts() def _switch_cursor_to_draw(self, *args): """ Switches board cursor state to 'draw'. """ self._draw_display.highlight() self._drag_display.unhighlight() self.board.set_cursor_state('draw') def _switch_cursor_to_drag(self, *args): """ Switches board cursor state to 'drag'. """ self._draw_display.unhighlight() self._drag_display.highlight() self.board.set_cursor_state('drag') def _toggle_cursor(self): """ Toggles board cursor state. """ if self.board.get_cursor_state() == 'draw': self._switch_cursor_to_drag() else: self._switch_cursor_to_draw() def _init(self): """ Creates the board and palette. """ self._file_name = None self._root = Tk() self._root.resizable(0, 0) self._menu = Menu(self._root, tearoff=0) self.board = Board( self._root, self._menu, width=self._board_width, height=self._board_height, directed_wires=self._directed_wires, label_tooltips_enabled=self._label_tooltips_enabled, same_label_per_connector=self._same_label_per_connector, on_changed=self._on_changed, on_exit=self._request_save) self._init_board() self.palette = Palette(self._root, self.board, width=self._board_width, height=self._palette_height) # buttons to change board cursor state self.palette.current_left_x -= PALETTE_PADDING self._draw_display = self.palette.add_drawable_type( Image_Run_Drawable, LEFT, self._switch_cursor_to_draw, image_file=PENCIL_IMAGE) self.palette.current_left_x -= PALETTE_PADDING self._drag_display = self.palette.add_drawable_type( Image_Run_Drawable, LEFT, self._switch_cursor_to_drag, image_file=HAND_IMAGE) self.palette.draw_separator() self._switch_cursor_to_draw() def _setup_menu(self): """ Creates the menu. """ file_menu = Menu(self._menu, tearoff=0) file_menu.add_command(label='New', command=self._new_file, accelerator='Ctrl+N') file_menu.add_command(label='Open', command=self._open_file, accelerator='Ctrl+O') file_menu.add_command(label='Save', command=self._save_file, accelerator='Ctrl+S') file_menu.add_command(label='Save as', command=self._save_as) file_menu.add_separator() file_menu.add_command(label='Quit', command=self.board.quit, accelerator='Ctrl+Q') self._menu.add_cascade(label='File', menu=file_menu) edit_menu = Menu(self._menu, tearoff=0) edit_menu.add_command(label='Undo', command=self.board.undo, accelerator='Ctrl+Z') edit_menu.add_command(label='Redo', command=self.board.redo, accelerator='Ctrl+Y') edit_menu.add_command(label='Delete selected', command=self.board._delete_selected_items, accelerator='Delete') edit_menu.add_command(label='Rotate selected', command=self.board._rotate_selected_item, accelerator='r') edit_menu.add_command(label='Toggle cursor', command=self._toggle_cursor, accelerator='D') self._menu.add_cascade(label='Edit', menu=edit_menu) self._root.config(menu=self._menu) def _setup_shortcuts(self): """ Adds basic shortcuts. """ self.board.parent.bind('<Control-n>', lambda event: self._new_file()) self.board.parent.bind('<Control-N>', lambda event: self._new_file()) self.board.parent.bind('<Control-o>', lambda event: self._open_file()) self.board.parent.bind('<Control-O>', lambda event: self._open_file()) self.board.parent.bind('<Control-q>', lambda event: self.board.quit()) self.board.parent.bind('<Control-Q>', lambda event: self.board.quit()) self.board.parent.bind('<Control-s>', lambda event: self._save_file()) self.board.parent.bind('<Control-S>', lambda event: self._save_file()) self.board.parent.bind('<Control-y>', lambda event: self.board.redo()) self.board.parent.bind('<Control-Y>', lambda event: self.board.redo()) self.board.parent.bind('<Control-z>', lambda event: self.board.undo()) self.board.parent.bind('<Control-Z>', lambda event: self.board.undo()) self.board.add_key_binding('d', self._toggle_cursor) def _init_board(self): """ (Re)Initializes the board based on this app's specific needs, as per self._on_init. """ self.board.clear() self._on_init(self.board) self.board.reset() def _on_changed(self, board_changed): """ Callback for when the board is changed. Updates the title of the app window to indicate whether we need to save the file. """ self._root.title( '%s (%s) %s %s' % (self._app_name, self._dev_stage, strip_file_name( self._file_name), '*' if board_changed else '')) def _save_as(self, file_name=None): """ Saves the current state of the app with the given |file_name|. """ saved_file_name = save_board(self.board, file_name, self._app_name, self._file_extension) if saved_file_name: self._file_name = saved_file_name self.board.set_changed(False) def _save_file(self): """ Saves the current state of the app with its current file name (asks for a a file path if it currently does not have one). """ self._save_as(self._file_name) def _request_save(self): """ Requests for a file save if necessary. Returns True if there isn't anything to save or, in the case that there is something to save, if the user either decides to save the file (will be presented with a dialog to do so) or decides not to save the file. Returns False if the user cancels the request for save (i.e. does neither). """ if self.board.changed(): save = request_save_board() if save == 'yes': self._save_file() return True elif save == 'no': return True else: return False else: return True def _open_file(self, new_file_name=None): """ Opens a saved file of this app's type. """ if self._request_save(): new_file_name = new_file_name or get_board_file_name( self._file_name, self._app_name, self._file_extension) if open_board_from_file(self.board, new_file_name, self._deserializers, self._file_extension): self._file_name = new_file_name self._on_changed(False) self.board.reset_cursor_state() def _new_file(self): """ Opens a new file of this app's type. """ if self._request_save(): self._file_name = None self._init_board() def run(self): """ Runs this app. """ self.board.clear_action_history() self._root.title('%s (%s)' % (self._app_name, self._dev_stage)) if self._init_file: self._open_file(self._init_file) self._root.mainloop()
class ConcordanceSearchView(object): _BACKGROUND_COLOUR = '#FFF' #white #Colour of highlighted results _HIGHLIGHT_WORD_COLOUR = '#F00' #red _HIGHLIGHT_WORD_TAG = 'HL_WRD_TAG' _HIGHLIGHT_LABEL_COLOUR = '#C0C0C0' # dark grey _HIGHLIGHT_LABEL_TAG = 'HL_LBL_TAG' #Percentage of text left of the scrollbar position _FRACTION_LEFT_TEXT = 0.30 def __init__(self): self.model = ConcordanceSearchModel() self.model.add_listener(self) self.top = Tk() self._init_top(self.top) self._init_menubar() self._init_widgets(self.top) self._bind_event_handlers() self.load_corpus(self.model.DEFAULT_CORPUS) def _init_top(self, top): top.geometry('950x680+50+50') top.title('NLTK Concordance Search') top.bind('<Control-q>', self.destroy) top.minsize(950, 680) def _init_widgets(self, parent): self.main_frame = Frame( parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1)) self._init_corpus_select(self.main_frame) self._init_query_box(self.main_frame) self._init_results_box(self.main_frame) self._init_paging(self.main_frame) self._init_status(self.main_frame) self.main_frame.pack(fill='both', expand=True) def _init_menubar(self): self._result_size = IntVar(self.top) self._cntx_bf_len = IntVar(self.top) self._cntx_af_len = IntVar(self.top) menubar = Menu(self.top) filemenu = Menu(menubar, tearoff=0, borderwidth=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-q') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) rescntmenu = Menu(editmenu, tearoff=0) rescntmenu.add_radiobutton(label='20', variable=self._result_size, underline=0, value=20, command=self.set_result_size) rescntmenu.add_radiobutton(label='50', variable=self._result_size, underline=0, value=50, command=self.set_result_size) rescntmenu.add_radiobutton(label='100', variable=self._result_size, underline=0, value=100, command=self.set_result_size) rescntmenu.invoke(1) editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu) cntxmenu = Menu(editmenu, tearoff=0) cntxbfmenu = Menu(cntxmenu, tearoff=0) cntxbfmenu.add_radiobutton(label='60 characters', variable=self._cntx_bf_len, underline=0, value=60, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='80 characters', variable=self._cntx_bf_len, underline=0, value=80, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='100 characters', variable=self._cntx_bf_len, underline=0, value=100, command=self.set_cntx_bf_len) cntxbfmenu.invoke(1) cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu) cntxafmenu = Menu(cntxmenu, tearoff=0) cntxafmenu.add_radiobutton(label='70 characters', variable=self._cntx_af_len, underline=0, value=70, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='90 characters', variable=self._cntx_af_len, underline=0, value=90, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='110 characters', variable=self._cntx_af_len, underline=0, value=110, command=self.set_cntx_af_len) cntxafmenu.invoke(1) cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu) editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu) menubar.add_cascade(label='Edit', underline=0, menu=editmenu) self.top.config(menu=menubar) def set_result_size(self, **kwargs): self.model.result_count = self._result_size.get() def set_cntx_af_len(self, **kwargs): self._char_after = self._cntx_af_len.get() def set_cntx_bf_len(self, **kwargs): self._char_before = self._cntx_bf_len.get() def _init_corpus_select(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.var = StringVar(innerframe) self.var.set(self.model.DEFAULT_CORPUS) Label(innerframe, justify=LEFT, text=' Corpus: ', background=self._BACKGROUND_COLOUR, padx=2, pady=1, border=0).pack(side='left') other_corpora = self.model.CORPORA.keys().remove( self.model.DEFAULT_CORPUS) om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora()) om['borderwidth'] = 0 om['highlightthickness'] = 1 om.pack(side='left') innerframe.pack(side='top', fill='x', anchor='n') def _init_status(self, parent): self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx=1, pady=0) self.status.pack(side='top', anchor='sw') def _init_query_box(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) another = Frame(innerframe, background=self._BACKGROUND_COLOUR) self.query_box = Entry(another, width=60) self.query_box.pack(side='left', fill='x', pady=25, anchor='center') self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1) self.search_button.pack(side='left', fill='x', pady=25, anchor='center') self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler) another.pack() innerframe.pack(side='top', fill='x', anchor='n') def search_enter_keypress_handler(self, *event): self.search() def _init_results_box(self, parent): innerframe = Frame(parent) i1 = Frame(innerframe) i2 = Frame(innerframe) vscrollbar = Scrollbar(i1, borderwidth=1) hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz') self.results_box = Text(i1, font=tkFont.Font(family='courier', size='16'), state='disabled', borderwidth=1, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set, wrap='none', width='40', height='20', exportselection=1) self.results_box.pack(side='left', fill='both', expand=True) self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG, foreground=self._HIGHLIGHT_WORD_COLOUR) self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG, foreground=self._HIGHLIGHT_LABEL_COLOUR) vscrollbar.pack(side='left', fill='y', anchor='e') vscrollbar.config(command=self.results_box.yview) hscrollbar.pack(side='left', fill='x', expand=True, anchor='w') hscrollbar.config(command=self.results_box.xview) #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!! Label(i2, text=' ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e') i1.pack(side='top', fill='both', expand=True, anchor='n') i2.pack(side='bottom', fill='x', anchor='s') innerframe.pack(side='top', fill='both', expand=True) def _init_paging(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled') prev.pack(side='left', anchor='center') self.next = next = Button(innerframe, text='Next', command=self.next, width='10', borderwidth=1, highlightthickness=1, state='disabled') next.pack(side='right', anchor='center') innerframe.pack(side='top', fill='y') self.current_page = 0 def previous(self): self.clear_results_box() self.freeze_editable() self.model.prev(self.current_page - 1) def next(self): self.clear_results_box() self.freeze_editable() self.model.next(self.current_page + 1) def about(self, *e): ABOUT = ("NLTK Concordance Search Demo\n") TITLE = 'About: NLTK Concordance Search Demo' try: from tkMessageBox import Message Message(message=ABOUT, title=TITLE, parent=self.main_frame).show() except: ShowText(self.top, TITLE, ABOUT) def _bind_event_handlers(self): self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded) self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated) self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error) self.top.bind(ERROR_LOADING_CORPUS_EVENT, self.handle_error_loading_corpus) def handle_error_loading_corpus(self, event): self.status['text'] = 'Error in loading ' + self.var.get() self.unfreeze_editable() self.clear_all() self.freeze_editable() def handle_corpus_loaded(self, event): self.status['text'] = self.var.get() + ' is loaded' self.unfreeze_editable() self.clear_all() self.query_box.focus_set() def handle_search_terminated(self, event): #todo: refactor the model such that it is less state sensitive results = self.model.get_results() self.write_results(results) self.status['text'] = '' if len(results) == 0: self.status['text'] = 'No results found for ' + self.model.query else: self.current_page = self.model.last_requested_page self.unfreeze_editable() self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT) def handle_search_error(self, event): self.status['text'] = 'Error in query ' + self.model.query self.unfreeze_editable() def corpus_selected(self, *args): new_selection = self.var.get() self.load_corpus(new_selection) def load_corpus(self, selection): if self.model.selected_corpus != selection: self.status['text'] = 'Loading ' + selection + '...' self.freeze_editable() self.model.load_corpus(selection) def search(self): self.current_page = 0 self.clear_results_box() self.model.reset_results() query = self.query_box.get() if (len(query.strip()) == 0): return self.status['text'] = 'Searching for ' + query self.freeze_editable() self.model.search( query, self.current_page + 1, ) def write_results(self, results): self.results_box['state'] = 'normal' row = 1 for each in results: sent, pos1, pos2 = each[0].strip(), each[1], each[2] if len(sent) != 0: if (pos1 < self._char_before): sent, pos1, pos2 = self.pad(sent, pos1, pos2) sentence = sent[pos1 - self._char_before:pos1 + self._char_after] if not row == len(results): sentence += '\n' self.results_box.insert(str(row) + '.0', sentence) word_markers, label_markers = self.words_and_labels( sent, pos1, pos2) for marker in word_markers: self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1])) for marker in label_markers: self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1])) row += 1 self.results_box['state'] = 'disabled' def words_and_labels(self, sentence, pos1, pos2): search_exp = sentence[pos1:pos2] words, labels = [], [] labeled_words = search_exp.split(' ') index = 0 for each in labeled_words: if each == '': index += 1 else: word, label = each.split('/') words.append((self._char_before + index, self._char_before + index + len(word))) index += len(word) + 1 labels.append((self._char_before + index, self._char_before + index + len(label))) index += len(label) index += 1 return words, labels def pad(self, sent, hstart, hend): if hstart >= self._char_before: return sent, hstart, hend d = self._char_before - hstart sent = ''.join([' '] * d) + sent return sent, hstart + d, hend + d def destroy(self, *e): if self.top is None: return self.top.destroy() self.top = None def clear_all(self): self.query_box.delete(0, END) self.model.reset_query() self.clear_results_box() def clear_results_box(self): self.results_box['state'] = 'normal' self.results_box.delete("1.0", END) self.results_box['state'] = 'disabled' def freeze_editable(self): self.query_box['state'] = 'disabled' self.search_button['state'] = 'disabled' self.prev['state'] = 'disabled' self.next['state'] = 'disabled' def unfreeze_editable(self): self.query_box['state'] = 'normal' self.search_button['state'] = 'normal' self.set_paging_button_states() def set_paging_button_states(self): if self.current_page == 0 or self.current_page == 1: self.prev['state'] = 'disabled' else: self.prev['state'] = 'normal' if self.model.has_more_pages(self.current_page): self.next['state'] = 'normal' else: self.next['state'] = 'disabled' def fire_event(self, event): #Firing an event so that rendering of widgets happen in the mainloop thread self.top.event_generate(event, when='tail') def mainloop(self, *args, **kwargs): if in_idle(): return self.top.mainloop(*args, **kwargs)
class MainApp(object): """ The MainApp based on TKinter Attributes ---------- root : Tk The Tk object dbfdata : dictionary The current dbf data menubar : Menu The menu bar attibmenu : Menu The attribute menu """ def __init__(self): self.root = Tk() self.root.geometry("300x250") self.root.title("Shape file Reader") self.createMenu() self.root.mainloop() def createMenu(self): """ Creates GUI components and register events """ self.menubar = Menu(self.root) self.dbfdata = None filemenu = Menu(self.menubar, tearoff=0) filemenu.add_command(label="Open", command=self.__openShpfile) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.root.quit) self.menubar.add_cascade(label="File", menu=filemenu) self.attibmenu = Menu(self.menubar, tearoff=0) self.menubar.add_cascade(label="Attibutes", menu=self.attibmenu,state='disabled') #Sagar Jha self.menubar.add_cascade(label="Simulator",command=self.__simulate) #Added Simulator self.root.config(menu=self.menubar) def __simulate(self): """ This function will create object of SimulatorExperimence """ self.Sim = SimulatorExperimence() ## Test to check object type ## print(type(self.Sim)) self.Sim.doTest() def __openShpfile(self): """ Open a shapefile and read in the contents, pop up the attribute menu with the attributes of the shapefile """ print "open shape file!" directory="C:/Users/sjha1/Documents/GitHub/Simulator_GUI/Python-Sample/data/states/48States.shp" #tkFileDialog.askopenfilename(filetypes=[("SHAPE_FILE","*.shp")]) print directory if directory == "": return self.shapes, self.shp_type, self.bbox = shp_reader.read_shp(directory) #read corresponding dbf data dbfFile = dbf.DbfLoader(directory[:-3] + "dbf") t = dbfFile.table2list() varNames = dbfFile.get_field_names() variables = {} for variable in varNames: variables[variable] = [record[varNames.index(variable)] for record in t] if self.dbfdata!=None: self.attibmenu.delete(0, len(self.dbfdata)-1) #add attributes into menu for key in variables.keys(): self.__addAttribute(key) self.dbfdata = variables self.menubar.entryconfig(2, state=Tkconstants.NORMAL) self.__updateCanvas("STATE_NAME") def __addAttribute(self,attributeName): """ Add an attribute to the menu """ self.attibmenu.add_command(label=attributeName, command=lambda i=attributeName:self.__updateCanvas(i)) def __updateCanvas(self, attributeName): """ Updates the canvas and showing statistical information """ print "update Canvas "+attributeName data_list=self.dbfdata[attributeName] print "attribute values: ", data_list try: n, min_max, mean, var, skew, kurt = stats.describe(data_list) print "============================" print "attribute statistics\n" print("Number of units: {0:d}".format(n)) print("Minimum: {0:8.6f} Maximum: {1:8.6f}".format(min_max[0], min_max[1])) print("Mean: {0:8.6f}".format(mean)) print("Standard deviation: {0:8.6f}".format(math.sqrt(var))) print("Skew : {0:8.6f}".format(skew)) print("Kurtosis: {0:8.6f}".format(kurt)) print "\n============================" high=max(data_list) low=min(data_list) dif=float(high-low) for i in range(len(data_list)): #map colors to 0-200, 0-200, 0-200 (avoid pure white for display purpose) index=float(data_list[i]-low)/dif*200 index=str(hex(200-int(index)).split('x')[1]) color="#"+index+index+index self.shapes[i].color=color except: print "non-numeric attribute" self.canvas=MainCanvas(self.shapes,self.bbox,self.shp_type,self.root,attributeName,data_list)
class Troop: @classmethod def init_troop(cls, name, nation): strength = random.randint(1, 3) health = random.randint(1, 3) ranged = random.choice([False, True]) #Starting troops are always melee random.choice([False, True]) speed = random.randint(2, 4) discipline = random.randint(1, 2) rank_size = random.randint(4, 15) ranks = random.randint(4, 6) elite = random.randint(2, 6) if ranged: weapons = [random.choice(nation.basic_ranged_weapon_list), random.choice(nation.sidearm_list)] else: weapons = [random.choice(nation.basic_weapon_list), random.choice(nation.basic_weapon_list)] #weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)] armor = random.choice(nation.basic_armor_list) mount = nation.mount_none if random.randint(0, 100) < elite + 5: mount = random.choice(nation.basic_mount_list) tier = 1 # print "Unknown nation has created a new unit: " + str(name) + ", armed with: " + str(weapons[0].name) +", " + str(weapons[1].name) + ", "+str(armor.name)+", "+str(mount.name)+" elite: "+str(elite) return cls(name, strength, health, 0, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, tier, [], mount, troop_nation=nation) def __init__(self, name, strength, health, number, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, tier, upgrades, mount, stats_history=None, arms_history=None, troop_nation=None): if arms_history is None: arms_history = [] if stats_history is None: stats_history = [] self.name = name self.strength = strength self.health = health self.number = number self.speed = speed self.originally_ranged = ranged #This one won't change when the unit swiches to melee mode. self.ranged = ranged self.discipline = discipline self.rank_size = rank_size self.ranks = ranks self.weapons = weapons self.armor = armor self.mount = mount self.upgrades = upgrades self.elite = elite self.tier = tier self.nation = troop_nation if not arms_history: self.arms_history = [(self.weapons, self.armor)] else: self.arms_history = arms_history if not stats_history: self.stats_history = [utility.base_soldier_stats()] else: self.stats_history = stats_history self.quality = 0 if self.nation is not None: self.nation.troop_tree.append(self) self.experience = 1 #Creates another troop to add to the troop tree @classmethod def new_troop(cls, self, nation): name = nation.language.make_word(nation.language.name_length, True) ranged = random.choice([False, True]) strength = self.strength + random.randint(1, 10 if not ranged else 5) health = self.health + random.randint(1, 4 if not ranged else 2) discipline = self.discipline + random.randint(0, 1) speed = self.speed + random.randint(1, 2) rank_size = random.randint(3, 15) ranks = random.randint(3, 5) if ranged: weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)] else: weapons = [random.choice(nation.weapon_list), random.choice(nation.sidearm_list)] armor = random.choice(nation.armor_list) mount = nation.mount_none elite = random.randint(2, 6) if random.randint(0, 100) < (elite * 2) + 5: mount = random.choice(nation.mount_list) # print str(nation.name) + " created a new unit: " + str(name) + ", armed with: " + str(weapons[0].name) +", " + str(weapons[1].name) + ", "+str(armor.name)+", "+str(mount.name) #e.append(events.EventTroopCreated('TroopCreated', {'nation_a': nation.name, 'army_a': name, 'equip_a':weapons, 'armor_a':armor}, s_parent.get_current_date())) return cls(name, strength, health, 0, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, self.tier + 1, [], mount, troop_nation=nation) def get_info(self): res = {} res['name'] = self.name res['strength'] = self.strength res['health'] = self.health res['number'] = self.number res['speed'] = self.speed res['ranged'] = self.ranged res['discipline'] = self.discipline res['rank_size'] = self.rank_size res['ranks'] = self.ranks res['weapons'] = map(lambda eqp: eqp.get_info(), self.weapons) res['armor'] = self.armor.get_info() res['elite'] = self.elite res['tier'] = self.tier res['mount'] = self.mount res['upgrades'] = [] for upgrade in self.upgrades: res['upgrades'].append(upgrade.get_info()) res['arms_history'] = [] for weapons, armor in self.arms_history: res['arms_history'].append((map(lambda eqp: eqp.get_info(), weapons), armor.get_info())) res['stats_history'] = self.stats_history return res # TODO: Make these actually do something def train(self, amount): return 0 #self.elite += random.randint(0, amount) #print self.elite def upgrade_gear(self): return 0 # if self.quality > 6: # return # self.quality += 1 # #print "upgrading " + str(self.weapons[0].attack) # self.weapons[0].upgrade(1) # self.weapons[0].upgrade_skill(1) # #Sprint "upgrading to" + str(self.weapons[0].attack) # self.weapons[1].upgrade(1) # self.weapons[1].upgrade_skill(1) # self.armor.upgrade(1) # self.armor.upgrade_skill(1) def save(self, path): with open(path + 'army_structure.txt', 'w') as f: f.write(str(self.get_info())) def handle_battle_end(self, stats): self.stats_history[-1] = utility.zip_dict_with(lambda a,b: a + b, self.stats_history[-1], stats) def do_rearm(self, nation): if self.tier == 1: if self.ranged: weapons = [random.choice(nation.basic_ranged_weapon_list), random.choice(nation.sidearm_list)] else: weapons = [random.choice(nation.basic_weapon_list), random.choice(nation.basic_weapon_list)] armor = random.choice(nation.basic_armor_list) mount = nation.mount_none if random.randint(0, 100) < self.elite + 5: mount = random.choice(nation.basic_mount_list) else: if self.ranged: weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)] else: weapons = [random.choice(nation.weapon_list), random.choice(nation.sidearm_list)] armor = random.choice(nation.armor_list) mount = nation.mount_none if random.randint(0, 100) < (self.elite * 2) + 5: mount = random.choice(nation.mount_list) self.weapons = weapons self.armor = armor self.mount = mount self.arms_history.append((self.weapons, self.armor, self.mount)) self.stats_history.append(utility.base_soldier_stats()) return self def rearm(self, name, new_weapons, new_armor, new_mount): if self.name == name: self.weapons = new_weapons self.armor = new_armor self.mount = new_mount else: for upgrade in self.upgrades: upgrade.rearm(name, new_weapons, new_armor, new_mount) def show_information_gui(self): self.gui_window = Tk() self.gui_window.title(self.name) self.gui_window.geometry("400x625+0+0") self.gui_window.config(background='white') self.ranged_label = gui.Label(self.gui_window, text='Is ranged: {}'.format(self.ranged)) self.ranged_label.grid(row=0, sticky=W) self.mount_label = gui.Label(self.gui_window, text='Mount: {}'.format(self.mount.name)) self.mount_label.grid(row=1, sticky=W) self.strength_label = gui.Label(self.gui_window, text='Strength: {}'.format(self.strength)) self.strength_label.grid(row=2, sticky=W) self.health_label = gui.Label(self.gui_window, text='Health: {}'.format(self.health)) self.health_label.grid(row=3, sticky=W) self.discipline_label = gui.Label(self.gui_window, text='Discipline: {}'.format(self.discipline)) self.discipline_label.grid(row=4, sticky=W) self.discipline_label = gui.Label(self.gui_window, text='Cost: {}'.format(self.get_soldier_cost())) self.discipline_label.grid(row=5, sticky=W) self.arrangement = gui.Label(self.gui_window, text='Arrangement: {}x{}'.format(self.rank_size, self.ranks)) self.arrangement.grid(row=6, sticky=W) self.arrangement_canvas = Canvas(self.gui_window, width = (self.rank_size + 1) * (TROOP_RADIUS + 1), height= (self.ranks + 1) * (TROOP_RADIUS + 1)) self.arrangement_canvas.config(background='white') self.arrangement_canvas.grid(row=7, sticky=W) for x in xrange(1, self.rank_size + 1): for y in xrange(1, self.ranks + 1): base_x, base_y = x * (TROOP_RADIUS + 1), y * (TROOP_RADIUS + 1) self.arrangement_canvas.create_oval(base_x, base_y, base_x + TROOP_RADIUS, base_y + TROOP_RADIUS) self.upgrade_label = gui.Label(self.gui_window, text='Upgrades:') self.upgrade_label.grid(row=8, sticky=W) self.upgrade_buttons = [] for (i, upgrade) in enumerate(self.upgrades): new_upgrade_button = gui.Button(self.gui_window, text=upgrade.name, command=upgrade.show_information_gui) new_upgrade_button.grid(row=9, column=i, sticky=W) self.upgrade_buttons.append(new_upgrade_button) self.history_choice = StringVar() self.history_choice.set(self.stringify_history(0)) self.stats_label = gui.Label(self.gui_window, text='Stats:') self.stats_label.grid(row=10, column=0, sticky=W) self.stats_choice = OptionMenu(self.gui_window, self.history_choice, *map(self.stringify_history, range(len(self.arms_history)))) self.stats_choice.config(background='white') self.stats_choice['menu'].config(background='white') self.stats_choice.grid(row=10, column=1, sticky=W) self.stats_select = gui.Button(self.gui_window, text='Select', command=self.select_history) self.stats_select.grid(row=10, column=2, sticky=W) self.stats_display = Listbox(self.gui_window) self.stats_display.grid(row=11, column=0, columnspan=3, sticky=W+E) self.select_history() def get_soldier_cost(self): amount = 0 for weapon in self.weapons: amount += weapon.cost amount += self.armor.cost amount += self.mount.cost return amount def stringify_history(self, i): weapon_str = ', '.join(map(lambda i: i.name, self.arms_history[i][0])) armor_str = self.arms_history[i][1].name mount_str = self.mount.name return '{}: ({}, {}), {}'.format(i, weapon_str, armor_str, mount_str) def select_history(self): history_index = int(self.history_choice.get().split(':')[0]) self.stats_display.delete(0, END) for stat in self.stats_history[history_index]: self.stats_display.insert(END, '{}: {}'.format(utility.displayify_text(stat), self.stats_history[history_index][stat])) def add_number(self, number, nation): self.number += number #e.append(events.EventArmyRaised('ArmyRaised', {'nation_a': nation.name, 'army_a': self.name, 'raised_a':number}, s_parent.get_current_date())) if self.number > self.elite** math.sqrt(self.tier): #If we have enough troops, we will create another, better, rank of troops if len(self.upgrades) < 3: self.upgrades.append(Troop.new_troop(self, nation)) self.upgrades[-1].upgrades = [] #Because it wants to put itself as an upgrade, for some reason. TODO if self.number < 0: self.number = 0 #Upgrade troops if possible. if self.number > (self.elite * self.tier) and len(self.upgrades) > 0: upgrading = random.randint(1, self.number // self.elite) self.number -= upgrading per_upgrade = upgrading // len(self.upgrades) for upgrade in self.upgrades: total_cost = nation.get_soldier_cost(upgrade) if nation.money > total_cost: upgrade.add_number(per_upgrade, nation) #print str(nation.name) + " raised an army of " + str(number) + " " + str(self.name) else: self.number += per_upgrade #Add these people back, because they weren't actually upgraded. nation.update_tree(self) return self def reset(self): return self.zero().reset_stats() def reset_stats(self): self.stats_history = [utility.base_soldier_stats()] return self def zero(self): return self.copy().remove_number('', self.size()) def add_army(self, other): self.add_to(other.name, other.number) for i in other.upgrades: self.add_army(i) def add_to(self, type, number): if self.name == type: self.number += number return self else: for upgrade in self.upgrades: if upgrade.name == type: upgrade.number += number return self for upgrade in self.upgrades: val = upgrade.add_to(type, number) if val is not None: return self return None #Returns a list of the unit + it's upgrades def make_upgrade_list(self): return sorted([self] + reduce(lambda a, b: a + b, [i.make_upgrade_list() for i in self.upgrades], []), key=lambda a: a.strength * a.health) def copy(self): return Troop(self.name, self.strength, self.health, 0, self.ranged, self.speed, self.discipline, self.rank_size, self.ranks, [i.copy() for i in self.weapons], self.armor.copy(), self.elite, self.tier, map(lambda i: i.copy(), self.upgrades), self.mount, stats_history=map(dict, self.stats_history), arms_history=list(self.arms_history)) def is_empty(self): return all(map(lambda i: i.is_empty(), self.upgrades)) and self.number == 0 def trim_empty(self): i = 0 while i < len(self.upgrades): if self.upgrades[i].is_empty(): self.upgrades.pop(i) else: self.upgrades[i] = self.upgrades[i].trim_empty() i += 1 return self def take_number(self, number): upgrade_list = self.make_upgrade_list() result = self.copy() for upgrade in upgrade_list: upgraded_amount = 0 if upgrade.number > number: upgrade.number -= number upgraded_amount = number number = 0 else: upgraded_amount = upgrade.number number -= upgrade.number upgrade.number = 0 result.add_to(upgrade.name, upgraded_amount) if number == 0: break return result.trim_empty() def remove_number(self, type, number): if type == '': upgrade_list = self.make_upgrade_list() for upgrade in upgrade_list: if upgrade.number > number: upgrade.number -= number number = 0 return self else: number -= upgrade.number upgrade.number = 0 return self else: if type == self.name: self.number -= number return self.number for i in self.upgrades: if i.name == type: i.number -= number return i.number #If not found in any of them, let's check all the children for i in self.upgrades: val = i.remove_number(type, number) if val >= 0: return val return -1 def size(self): return self.number + sum(map(lambda t: t.size(), self.upgrades)) def merge_all(self, other): if self.name == other.name: self.number += other.number for index, upgrade in enumerate(other.upgrades): if not upgrade in self.upgrades: self.upgrades.append(upgrade.copy()) self.upgrades[-1] = self.upgrades[-1].merge_all(upgrade) else: self_upgrade = self.upgrades.index(upgrade) self.upgrades[self_upgrade] = self.upgrades[self_upgrade].merge_all(upgrade) return self def merge_structure(self, other): result = self.zero() if result.name == other.name: for index, upgrade in enumerate(other.upgrades): if not upgrade in result.upgrades: result.upgrades.append(upgrade.zero()) result.upgrades[-1] = result.upgrades[-1].merge_structure(upgrade) else: self_upgrade = self.upgrades.index(upgrade) result.upgrades[self_upgrade] = result.upgrades[self_upgrade].merge_structure(upgrade) return result def __eq__(self, other): try: return self.name == other.name except: return False def __repr__(self): return "{0}({1}, {2}): {3} {4}".format(self.name, self.strength, self.health, self.number, self.upgrades)
class Juego: # Declarar el constructor de la clase Juego. def __init__(self): self.app = Tk() self.app.title('# Gatito #') self.app.resizable(width=True, height=True) self.tablero = Tablero() self.font = Font(family="Roboto", size=34) self.botones = {} # Ciclo para crear los objetos botón para posteriormente asignarlos en el Juego. for x, y in self.tablero.casillas: manejador = lambda x=x, y=y: self.movimiento(x, y) boton = Button(self.app, command=manejador, font=self.font, width=2, height=1) boton.grid(row=y, column=x) self.botones[x, y] = boton manejador = lambda: self.reiniciar() boton = Button(self.app, text='Reiniciar', command=manejador) boton.grid(row=self.tablero.size + 1, column=0, columnspan=self.tablero.size, sticky="WE") self.actualizar() # Declarar el método Reiniciar que será asignada al botón Reiniciar en el Juego. def reiniciar(self): self.tablero = Tablero() self.actualizar() # Declarar la función movimiento que revisará los click's realizados por el usuario y los movimientos realizados por el oponente (IA). def movimiento(self, x, y): self.app.config(cursor="watch") self.app.update() self.tablero = self.tablero.movimiento(x, y) self.actualizar() movimiento = self.tablero.mejor() # Si se detecta un movimiento en el Juego, entonces el oponente realizara el siguiente movimiento en base al árbol creado en _minimax. # Después ejecutara el método actualizar y regresara el cursor al jugador para el siguiente movimiento. if movimiento: self.tablero = self.tablero.movimiento(*movimiento) self.actualizar() self.app.config(cursor="") # Declarar el método Actualizar que realizará def actualizar(self): # for (x, y) in self.tablero.casillas: text = self.tablero.casillas[x, y] self.botones[x, y]['text'] = text self.botones[x, y]['disabledforeground'] = 'black' # if text == self.tablero.vacio: self.botones[x, y]['state'] = 'normal' else: self.botones[x, y]['state'] = 'disabled' ganando = self.tablero.ganador() # if ganando: for x, y in ganando: self.botones[x, y]['disabledforeground'] = 'red' for x, y in self.botones: self.botones[x, y]['state'] = 'disabled' for (x, y) in self.tablero.casillas: self.botones[x, y].update() # Declarar el método Principal donde se inicializa el objeto app. def principal(self): self.app.mainloop()
class Display: def __init__(self, controller): # initialize the GUI self.app = Tk() self.app.title('Tic Tac Toe') self.app.resizable(width=False, height=False) self.game_controller = controller # interface to the game self.winner = None # who has won the game # make the board self.buttons = [[None for i in range(SIZE)] for j in range(SIZE)] for x in range(SIZE): for y in range(SIZE): handler = lambda x=x, y=y: self.move(x,y) # each button corresponds to making a move in that square self.buttons[x][y] = self.make_button(text='', command=handler, row=y, column=x+SIZE, width=1) # button to reset the board self.make_button(text='New Game', command=lambda:self.reset(), row=SIZE+1, column=SIZE) # button that makes the machine learn self.make_button(text='Learn', command=lambda:self.learn(), row=SIZE+1, column=SIZE+SIZE/2) # button that causes the machine to forget how to play self.make_button(text='Forget', command=lambda:self.forget(), row=SIZE+1, column=2*SIZE-1) self.update() # the score labels score = Label(self.app, text=' SCORE:', font=Font(family="Courier", weight='bold', size=32)) score.grid(row=0, column=0, columnspan=SIZE) self.score = Label(self.app, text='0', font=Font(family="Courier", weight='bold', size=32)) self.score.grid(row=1, column=1) # choose if you are X or O. X always goes first self.player_choice = StringVar() # how to keep track of the option which_player = OptionMenu(self.app, self.player_choice, *(STRINGS[X], STRINGS[O])) # options are X and O which_player.grid(row=SIZE+2, column=SIZE+2) which_player.config(font=Font(family='Courier')) self.player_choice.set('X') self.player_choice.trace('w', self.choose_player) # choose between playing against a Perfect player or Learning player self.comp_type = StringVar() # how to keep track of the option comp_type = OptionMenu(self.app, self.comp_type, *('Learning', 'Perfect')) comp_type.grid(row=SIZE+2, column=SIZE) comp_type.config(width=11, font=Font(family='Courier')) self.comp_type.set('Learning') self.comp_type.trace('w', self.choose_comp_type) def mainloop(self): self.app.mainloop() # make a new button def make_button(self, text, command, row, column, width=None): if width: button = Button(self.app, text=text, command=command, width=width, font=Font(family="Courier")) else: button = Button(self.app, text=text, command=command, font=Font(family="Courier")) button.grid(row=row, column=column, columnspan=1) return button # choose if you will be X or O player def choose_player(self, *args): if hasattr(self, 'prev_player'): # only returns false first time if self.player_choice.get() != self.prev_player: # only do something if the choice has changed self.prev_player = self.player_choice.get() # get the choice self.game_controller.set_player(self.prev_player) # set the player self.reset() # new game. Can't switch player mid game else: self.prev_player = self.player_choice.get() # get the choice if self.prev_player == STRINGS[O]: # this is the first time so only has changed if it switched to O self.game_controller.set_player(self.prev_player) self.reset() # choose between playing against a perfect player or learning player def choose_comp_type(self, *args): if hasattr(self, 'prev_comp_type'): # only returns falls first time if self.comp_type.get() != self.prev_comp_type: # only do something if the choice has changed self.prev_comp_type = self.comp_type.get() # get the choice self.game_controller.set_comp_type(self.prev_comp_type) # set the type else: self.prev_comp_type = self.comp_type.get() # get the choice if self.prev_comp_type == 'Perfect': # this is the first time so only has changed if it switched to perfect self.game_controller.set_comp_type(self.prev_comp_type) def forget(self): self.game_controller.forget() def learn(self): self.game_controller.learn() def reset(self): # clear the winner textbox if there is one if self.winner != None: self.winner.destroy() self.winner = None # reenable the board for x in range(SIZE): for y in range(SIZE): self.buttons[x][y]['state'] = 'normal' self.game_controller.reset() self.update() # make a move and update the display def move(self,x,y): self.game_controller.make_move(x,y) self.update_button(x, y) self.app.config(cursor="") # update all the buttons to reflect the game state def update(self): for x in range(SIZE): for y in range(SIZE): self.update_button(x, y) # update a single button def update_button(self, x, y): # convert the board position value to a string text = STRINGS[self.game_controller.get_position(x, y)] self.buttons[x][y]['text'] = text # game has ended. disable the board and display the results def game_over(self, winner): # disable the board for x in range(SIZE): for y in range(SIZE): self.buttons[x][y]['state'] = 'disabled' # update the score score = int(self.score['text']) # display the result of the game if winner == X: winner_str = '1' score += 2 elif winner == O: winner_str = '2' score -= 2 if winner == None: self.winner = Label(self.app, text="TIE", font=Font(family="Courier", weight='bold', size=32)) score -= 1 else: text = 'Player', winner_str, 'Wins!' self.winner = Label(self.app, text=text, font=Font(family="Courier", weight='bold', size=32)) self.winner.grid(row=1, column=3*SIZE, columnspan=SIZE, sticky="WE") # display the score self.score['text'] = str(score)
class PiPresents(object): def __init__(self): gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL) self.pipresents_issue="1.3" self.pipresents_minorissue = '1.3.1g' # position and size of window without -f command line option self.nonfull_window_width = 0.45 # proportion of width self.nonfull_window_height= 0.7 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y=0 # position of top left corner self.pp_background='black' StopWatch.global_enable=False # set up the handler for SIGTERM signal.signal(signal.SIGTERM,self.handle_sigterm) # **************************************** # Initialisation # *************************************** # get command line options self.options=command_options() # get Pi Presents code directory pp_dir=sys.path[0] self.pp_dir=pp_dir if not os.path.exists(pp_dir+"/pipresents.py"): if self.options['manager'] is False: tkMessageBox.showwarning("Pi Presents","Bad Application Directory:\n{0}".format(pp_dir)) exit(103) # Initialise logging and tracing Monitor.log_path=pp_dir self.mon=Monitor() # Init in PiPresents only self.mon.init() # uncomment to enable control of logging from within a class # Monitor.enable_in_code = True # enables control of log level in the code for a class - self.mon.set_log_level() # make a shorter list to log/trace only some classes without using enable_in_code. Monitor.classes = ['PiPresents', 'pp_paths', 'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow', 'PathManager','ControlsManager','ShowManager','PluginManager', 'MplayerDriver','OMXDriver','UZBLDriver', 'KbdDriver','GPIODriver','TimeOfDay','ScreenDriver','Animate','OSCDriver' ] # Monitor.classes=['PiPresents','ArtMediaShow','VideoPlayer','OMXDriver'] # get global log level from command line Monitor.log_level = int(self.options['debug']) Monitor.manager = self.options['manager'] # print self.options['manager'] self.mon.newline(3) self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue) # self.mon.log (self," OS and separator:" + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: "+sys.path[0]) if os.geteuid() !=0: user=os.getenv('USER') else: user = os.getenv('SUDO_USER') self.mon.log(self,'User is: '+ user) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # does not work # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # does not work # optional other classes used self.root=None self.ppio=None self.tod=None self.animate=None self.gpiodriver=None self.oscdriver=None self.osc_enabled=False self.gpio_enabled=False self.tod_enabled=False # get home path from -o option self.pp_home = pp_paths.get_home(self.options['home']) if self.pp_home is None: self.end('error','Failed to find pp_home') # get profile path from -p option # pp_profile is the full path to the directory that contains # pp_showlist.json and other files for the profile self.pp_profile = pp_paths.get_profile_dir(self.pp_home, self.options['profile']) if self.pp_profile is None: self.end('error','Failed to find profile') # check profile exists if os.path.exists(self.pp_profile): self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile) self.end('error','Failed to find profile') self.mon.start_stats(self.options['profile']) # check 'verify' option if self.options['verify'] is True: val =Validator() if val.validate_profile(None,pp_dir,self.pp_home,self.pp_profile,self.pipresents_issue,False) is False: self.mon.err(self,"Validation Failed") self.end('error','Validation Failed') # initialise and read the showlist in the profile self.showlist=ShowList() self.showlist_file= self.pp_profile+ "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self,"showlist not found at "+self.showlist_file) self.end('error','showlist not found') # check profile and Pi Presents issues are compatible if float(self.showlist.sissue()) != float(self.pipresents_issue): self.mon.err(self,"Version of profile " + self.showlist.sissue() + " is not same as Pi Presents, must exit") self.end('error','wrong version of profile') # get the 'start' show from the showlist index = self.showlist.index_of_show('start') if index >=0: self.showlist.select(index) self.starter_show=self.showlist.selected_show() else: self.mon.err(self,"Show [start] not found in showlist") self.end('error','start show not found') if self.starter_show['start-show']=='': self.mon.warn(self,"No Start Shows in Start Show") # ******************** # SET UP THE GUI # ******************** # turn off the screenblanking and saver if self.options['noblank'] is True: call(["xset","s", "off"]) call(["xset","s", "-dpms"]) self.root=Tk() self.title='Pi Presents - '+ self.pp_profile self.icon_text= 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg=self.pp_background) self.mon.log(self, 'native screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixcels') if self.options['screensize'] =='': self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() else: reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize']) if reason =='error': self.mon.err(self,message) self.end('error',message) self.mon.log(self, 'commanded screen dimensions are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixcels') # set window dimensions and decorations if self.options['fullscreen'] is False: self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width) self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height) self.window_x=self.nonfull_window_x self.window_y=self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) else: self.window_width=self.screen_width self.window_height=self.screen_height self.root.attributes('-fullscreen', True) os.system('unclutter 1>&- 2>&- &') # Suppress 'someone created a subwindow' complaints from unclutter self.window_x=0 self.window_y=0 self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) self.root.attributes('-zoomed','1') # canvs cover the whole screen whatever the size of the window. self.canvas_height=self.screen_height self.canvas_width=self.screen_width # make sure focus is set. self.root.focus_set() # define response to main window closing. self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort) # setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg=self.pp_background) if self.options['fullscreen'] is True: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) else: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=1, highlightcolor='yellow') self.canvas.place(x=0,y=0) # self.canvas.config(bg='black') self.canvas.focus_set() # **************************************** # INITIALISE THE INPUT DRIVERS # **************************************** # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs/ # use keyboard driver to bind keys to symbolic names and to set up callback kbd=KbdDriver() if kbd.read(pp_dir,self.pp_home,self.pp_profile) is False: self.end('error','cannot find or error in keys.cfg') kbd.bind_keys(self.root,self.handle_input_event) self.sr=ScreenDriver() # read the screen click area config file reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile) if reason == 'error': self.end('error','cannot find screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes # click areas are made on the Pi Presents canvas not the show canvases. reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event) if reason == 'error': self.mon.err(self,message) self.end('error',message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required=False self.exitpipresents_required=False # kick off GPIO if enabled by command line option self.gpio_enabled=False if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+os.sep+ 'gpio.cfg'): # initialise the GPIO self.gpiodriver=GPIODriver() reason,message=self.gpiodriver.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,50,self.handle_input_event) if reason == 'error': self.end('error',message) else: self.gpio_enabled=True # and start polling gpio self.gpiodriver.poll() # kick off animation sequencer self.animate = Animate() self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event) self.animate.poll() #create a showmanager ready for time of day scheduler and osc server show_id=-1 self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home) # first time through set callback to terminate Pi Presents if all shows have ended. self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist) # Register all the shows in the showlist reason,message=self.show_manager.register_shows() if reason == 'error': self.mon.err(self,message) self.end('error',message) # Init OSCDriver, read config and start OSC server self.osc_enabled=False if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'): self.oscdriver=OSCDriver() reason,message=self.oscdriver.init(self.pp_profile,self.handle_command,self.handle_input_event,self.e_osc_handle_output_event) if reason == 'error': self.end('error',message) else: self.osc_enabled=True self.root.after(1000,self.oscdriver.start_server()) # and run the start shows self.run_start_shows() # set up the time of day scheduler including catchup self.tod_enabled=False if os.path.exists(self.pp_profile + os.sep + 'schedule.json'): # kick off the time of day scheduler which may run additional shows self.tod=TimeOfDay() self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.root,self.handle_command) self.tod_enabled = True # then start the time of day scheduler if self.tod_enabled is True: self.tod.poll() # start Tkinters event loop self.root.mainloop( ) def parse_screen(self,size_text): fields=size_text.split('*') if len(fields)!=2: return 'error','do not understand --fullscreen comand option',0,0 elif fields[0].isdigit() is False or fields[1].isdigit() is False: return 'error','dimensions are not positive integers in ---fullscreen',0,0 else: return 'normal','',int(fields[0]),int(fields[1]) # ********************* # RUN START SHOWS # ******************** def run_start_shows(self): self.mon.trace(self,'run start shows') # parse the start shows field and start the initial shows show_refs=self.starter_show['start-show'].split() for show_ref in show_refs: reason,message=self.show_manager.control_a_show(show_ref,'open') if reason == 'error': self.mon.err(self,message) # ********************* # User inputs # ******************** # handles one command provided as a line of text def handle_command(self,command_text): self.mon.log(self,"command received: " + command_text) if command_text.strip()=="": return if command_text[0]=='/': if self.osc_enabled is True: self.oscdriver.send_command(command_text) return fields= command_text.split() show_command=fields[0] if len(fields)>1: show_ref=fields[1] else: show_ref='' if show_command in ('open','close'): if self.shutdown_required is False: reason,message=self.show_manager.control_a_show(show_ref,show_command) else: return elif show_command == 'exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to get out of st thread self.root.after(1,self.e_all_shows_ended_callback) return else: reason,message= self.show_manager.exit_all_shows() elif show_command == 'shutdownnow': # need root.after to get out of st thread self.root.after(1,self.e_shutdown_pressed) return else: reason='error' message = 'command not recognised: '+ show_command if reason=='error': self.mon.err(self,message) return def e_all_shows_ended_callback(self): self.all_shows_ended_callback('normal','no shows running') def e_shutdown_pressed(self): self.shutdown_pressed('now') def e_osc_handle_output_event(self,line): #jump out of server thread self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg)) def osc_handle_output_event(self,line): self.mon.log(self,"output event received: "+ line) #osc sends output events as a string reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line) if reason == 'error': self.mon.err(self,message) self.end(reason,message) self.handle_output_event(name,param_type,param_values,0) def handle_output_event(self,symbol,param_type,param_values,req_time): if self.gpio_enabled is True: reason,message=self.gpiodriver.handle_output_event(symbol,param_type,param_values,req_time) if reason =='error': self.mon.err(self,message) self.end(reason,message) else: self.mon.warn(self,'GPIO not enabled') # all input events call this callback with a symbolic name. # handle events that affect PP overall, otherwise pass to all active shows def handle_input_event(self,symbol,source): self.mon.log(self,"event received: "+symbol + ' from '+ source) if symbol == 'pp-terminate': self.handle_user_abort() elif symbol == 'pp-shutdown': self.shutdown_pressed('delay') elif symbol == 'pp-shutdownnow': # need root.after to grt out of st thread self.root.after(1,self.e_shutdown_pressed) return elif symbol == 'pp-exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to grt out of st thread self.root.after(1,self.e_all_shows_ended_callback) return reason,message= self.show_manager.exit_all_shows() else: # events for shows affect the show and could cause it to exit. for show in self.show_manager.shows: show_obj=show[ShowManager.SHOW_OBJ] if show_obj is not None: show_obj.handle_input_event(symbol) def shutdown_pressed(self, when): if when == 'delay': self.root.after(5000,self.on_shutdown_delay) else: self.shutdown_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def on_shutdown_delay(self): # 5 second delay is up, if shutdown button still pressed then shutdown if self.gpiodriver.shutdown_pressed() is True: self.shutdown_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def handle_sigterm(self,signum,frame): self.mon.log(self,'SIGTERM received - '+ str(signum)) self.terminate() def handle_user_abort(self): self.mon.log(self,'User abort received') self.terminate() def terminate(self): self.mon.log(self, "terminate received") needs_termination=False for show in self.show_manager.shows: # print show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF] if show[ShowManager.SHOW_OBJ] is not None: needs_termination=True self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF]) # call shows terminate method # eventually the show will exit and after all shows have exited all_shows_callback will be executed. show[ShowManager.SHOW_OBJ].terminate() if needs_termination is False: self.end('killed','killed - no termination of shows required') # ****************************** # Ending Pi Presents after all the showers and players are closed # ************************** # callback from ShowManager when all shows have ended def all_shows_ended_callback(self,reason,message): self.canvas.config(bg=self.pp_background) if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True: self.end(reason,message) def end(self,reason,message): self.mon.log(self,"Pi Presents ending with reason: " + reason) if self.root is not None: self.root.destroy() self.tidy_up() # gc.collect() # print gc.garbage if reason == 'killed': self.mon.log(self, "Pi Presents Aborted, au revoir") # close logging files self.mon.finish() sys.exit(101) elif reason == 'error': self.mon.log(self, "Pi Presents closing because of error, sorry") # close logging files self.mon.finish() sys.exit(102) else: self.mon.log(self,"Pi Presents exiting normally, bye") # close logging files self.mon.finish() if self.shutdown_required is True: # print 'SHUTDOWN' call(['sudo', 'shutdown', '-h', '-t 5','now']) sys.exit(100) else: sys.exit(100) # tidy up all the peripheral bits of Pi Presents def tidy_up(self): self.mon.log(self, "Tidying Up") # turn screen blanking back on if self.options['noblank'] is True: call(["xset","s", "on"]) call(["xset","s", "+dpms"]) # tidy up animation and gpio if self.animate is not None: self.animate.terminate() if self.gpio_enabled==True: self.gpiodriver.terminate() if self.osc_enabled is True: self.oscdriver.terminate() # tidy up time of day scheduler if self.tod_enabled is True: self.tod.terminate()
class OSCMonitor(object): def __init__(self): self.editor_issue = "1.3" # get command options self.command_options = remote_options() # get directory holding the code self.pp_dir = sys.path[0] if not os.path.exists(self.pp_dir + os.sep + "pipresents.py"): tkMessageBox.showwarning("Pi Presents", "Bad Application Directory") exit() # Initialise logging Monitor.log_path = self.pp_dir self.mon = Monitor() self.mon.init() Monitor.classes = ['OSCMonitor', 'OSCConfig', 'OSCEditor'] Monitor.log_level = int(self.command_options['debug']) self.mon.log(self, "Pi Presents Monitor is starting") self.mon.log(self, " OS and separator " + os.name + ' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: code " + sys.path[0]) self.setup_gui() # initialise OSC config class self.osc_config = OSCConfig() self.init() #and start the system self.root.after(1000, self.run_app) self.root.mainloop() def init(self): # read the options and allow their editing self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscmonitor.cfg' self.read_create_osc() def add_status(self, text): self.status_display.insert(END, text + '\n') self.status_display.see(END) def run_app(self): self.client = None self.server = None self.st = None # initialise OSC variables self.prefix = '/pipresents' self.this_unit = '/' + self.osc_config.this_unit_name self.add_status('this unit is: ' + self.this_unit) self.controlled_by_unit = '/' + self.osc_config.controlled_by_name self.add_status('controlled by unit : ' + self.controlled_by_unit) #connect client for replies then start server to listen for commands self.client = OSC.OSCClient() self.add_status('connecting to controlled by unit: ' + self.osc_config.controlled_by_ip + ':' + self.osc_config.controlled_by_port + ' ' + self.osc_config.controlled_by_name) self.client.connect((self.osc_config.controlled_by_ip, int(self.osc_config.controlled_by_port))) self.add_status('listening for commands on:' + self.osc_config.this_unit_ip + ':' + self.osc_config.this_unit_port) self.init_server(self.osc_config.this_unit_ip, self.osc_config.this_unit_port, self.client) self.add_initial_handlers() self.start_server() # *************************************** # OSC CLIENT TO SEND REPLIES # *************************************** def disconnect_client(self): if self.client != None: self.client.close() return # *************************************** # OSC SERVER TO LISTEN TO COMMANDS # *************************************** def init_server(self, ip, port_text, client): self.add_status('Init Server: ' + ip + ':' + port_text) self.server = myOSCServer((ip, int(port_text)), client) def start_server(self): self.add_status('Start Server') self.st = threading.Thread(target=self.server.serve_forever) self.st.start() def close_server(self): if self.server != None: self.server.close() self.mon.log(self, 'Waiting for Server-thread to finish') if self.st != None: self.st.join() ##!!! self.mon.log(self, 'server thread closed') def add_initial_handlers(self): pass self.server.addMsgHandler('default', self.no_match_handler) self.server.addMsgHandler( self.prefix + self.this_unit + "/system/server-info", self.server_info_handler) self.server.addMsgHandler( self.prefix + self.this_unit + "/system/loopback", self.loopback_handler) def no_match_handler(self, addr, tags, stuff, source): text = "Message from %s" % OSC.getUrlStr(source) + '\n' text += " %s" % addr + self.pretty_list(stuff) self.add_status(text + '\n') def server_info_handler(self, addr, tags, stuff, source): msg = OSC.OSCMessage(self.prefix + self.controlled_by_unit + '/system/server-info-reply') msg.append('Unit: ' + self.osc_config.this_unit_name) self.add_status('Server Info Request from %s:' % OSC.getUrlStr(source)) return msg def loopback_handler(self, addr, tags, stuff, source): # send a reply to the client. msg = OSC.OSCMessage(self.prefix + self.controlled_by_unit + '/system/loopback-reply') self.add_status('Loopback Request from %s:' % OSC.getUrlStr(source)) return msg def pretty_list(self, fields): text = ' ' for field in fields: text += str(field) + ' ' return text # *************************************** # INIT EXIT MISC # *************************************** def e_edit_osc(self): self.disconnect_client() self.close_server() self.edit_osc() self.init() self.add_status('\n\n\nRESTART') self.run_app() def app_exit(self): self.disconnect_client() self.close_server() if self.root is not None: self.root.destroy() self.mon.finish() sys.exit() def show_help(self): tkMessageBox.showinfo("Help", "Read 'manual.pdf'") def about(self): tkMessageBox.showinfo( "About", "Simple Remote Monitor for Pi Presents\n" + "Author: Ken Thompson" + "\nWebsite: http://pipresents.wordpress.com/") def setup_gui(self): # set up the gui # root is the Tkinter root widget self.root = Tk() self.root.title("Remote Monitor for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False, False) # define response to main window closing self.root.protocol("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = StringVar() self.display_show = StringVar() self.results = StringVar() self.status = StringVar() # define menu menubar = Menu(self.root) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu=toolsmenu) osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu=osc_configmenu) osc_configmenu.add_command(label='Edit', command=self.e_edit_osc) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu=helpmenu) helpmenu.add_command(label='Help', command=self.show_help) helpmenu.add_command(label='About', command=self.about) self.root.config(menu=menubar) # status_frame status_frame = Frame(self.root, padx=5, pady=5) status_frame.pack(side=TOP, fill=BOTH, expand=1) status_label = Label(status_frame, text="Status", font="arial 12 bold") status_label.pack(side=LEFT) scrollbar = Scrollbar(status_frame, orient=VERTICAL) self.status_display = Text(status_frame, height=10, yscrollcommand=scrollbar.set) scrollbar.config(command=self.status_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.status_display.pack(side=LEFT, fill=BOTH, expand=1) # *************************************** # OSC CONFIGURATION # *************************************** def read_create_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file, 'slave', 'Create OSC Monitor Configuration') self.osc_config.read(self.osc_config_file) def edit_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file, 'slave', 'Edit OSC Monitor Configuration')
showinfo("search command", "No results found.") else: #showinfo("search command", "searching:%s\nDifficulty: %s\nRating: %s"%text%str(query.getDifficulty())%str(query.getRating())) showinfo( "search command", "searching: " + text + "\nRating: " + query.getRating() + "\n" + "Difficulty: " + query.getDifficulty()) # def update_scene(root, milsec, filename): # self.img = ImageTk.PhotoImage(Image.open(INSTALL_DIR + filename)) # #The Label widget is a standard Tkinter widget used to display a text or image on the screen. # self.master.after(milsec, self.panel.config(image = self.img)) # self.master.update() root = Tk() root.geometry("800x600") root.title("Search") root.config(background="#bf5700") Search_Bar(root, command=command, placeholder="Search for professors...", entry_highlightthickness=0).pack(pady=6, padx=3) img = ImageTk.PhotoImage( Image.open(INSTALL_DIR + "logo.png").resize((500, 500), Image.ANTIALIAS)) panel = Label(root, image=img, background="#bf5700") panel.pack(side=TOP) root.mainloop()
class GUI: def __init__(self): self.app = Tk() self.app.title('War Game') self.app.resizable(width=False, height=False) self.font = Font(family="Helvetica", size=32) self.buttons = {} self.board_file = './boards/Westerplatte.txt' self.board = Board(self.board_file) self.size = SIZE for y in xrange(1, self.size + 1): for x in xrange(1, self.size + 1): handler = lambda x=x, y=y: self.move(x, y) button = Button(self.app, command=handler, font=self.font, width=3, height=1, text=self.board.values[y, x], background='gray') button.grid(row=y, column=x) self.buttons[x, y] = button handler = lambda: self.auto_move() button = Button(self.app, text='Start AI', command=handler) button.grid(row=self.size + 1, column=1, columnspan=self.size, sticky="WE") def auto_move(self): output_file = open('./output/alpha_mini.txt', 'a') expanded_list = [] time_list = [] while self.board.nodes_left > 0: start_time = clock() if self.board.player == 1: cost, (y, x), expanded = self.board.root_negalphabeta() else: cost, (y, x), expanded = self.board.root_negamax() elapsed_time = clock() - start_time print 'Player: {} Heuristic {} Expanded {} Time took {}'.format(self.board.player, cost, expanded, elapsed_time) self.move(x, y) print 'Score: {}'.format(self.board.score) expanded_list.append(expanded) time_list.append(elapsed_time) output_file.write(self.board_file + '\n') output_file.write(' '.join(str(x) for x in expanded_list) + '\n') output_file.write(' '.join(str(x) for x in time_list) + '\n') output_file.write((self.board.colors + 66).tostring() + '\n\n') def move(self, x, y): self.app.config(cursor="watch") self.app.update() self.board.move(x, y) self.update(x, y) self.app.config(cursor="") def update(self, x, y): self.buttons[x, y]['state'] = 'disabled' for y in xrange(1, self.size + 1): for x in xrange(1, self.size + 1): self.buttons[x, y]['background'] = COLORS[self.board.colors[y, x]] self.buttons[x, y].update() def mainloop(self): self.app.mainloop()
class PokerMachine(): """Implements a video poker machine class.""" def __init__(self): """Instance initialization function.""" # Set up variables self.deck = pcards.Deck() self.cardimg = [] self.hand = None self.game_start = True self.game_postdeal = False self.game_easy = True self.game_over = False self.gifdir = "./images/" self.pot = 100 self.defaultbet = 5 self.bet = 5 self._set_up_gui() def button_clicked(self): """Event handler for button click. Callback method called by tk. """ if self.game_over: self._start_new_game() elif not self.game_postdeal: self._process_bet() elif self.game_postdeal: self._evaluate_hand() def flip(self, event): """Event handler which flips a clicked card. Callback method called by tk. """ if not self.game_postdeal: return if event.widget.flipped: event.widget.flipped = False event.widget.configure(image=event.widget.cardimage) else: event.widget.flipped = True event.widget.configure(image=self.backimg) def _start_new_game(self): """Returns the game an interface to its starting point.""" for cardimg in self.cardimg: cardimg.configure(image=self.backimg) cardimg.flipped = True self.game_over = False self.game_postdeal = False self.pot = 100 self.defaultbet = 5 self.bet = 5 self._update_pot() self.bet_amt_fld.configure(state=NORMAL) self.bet_str.set(str(self.defaultbet)) self.button.configure(text="Deal") self.status_lbl.configure(text="Click 'Deal' to play.") def _process_bet(self): """Processes the player's bet and deals a new hand if the bet is valid. """ # First check if played made a valid bet, # and return with no change in state (other # than resetting the bet field) if they did # not. b_str = self.bet_str.get() try: self.bet = int(b_str) except ValueError: self._show_bet_error("Bad bet!", "You must bet a whole number!") return if self.bet > self.pot: self._show_bet_error("Don't be greedy!", "You don't have that much money!") return elif self.bet < 1: self._show_bet_error("Don't get clever!", "You must bet a positive whole number!") return # We have a valid bet, so shuffle the deck # and get a new poker hand. self.deck.shuffle() self.hand = pcards.PokerHand(self.deck) self._show_cards() # Update game variables and GUI self.pot -= self.bet self._update_pot() self.button.configure(text="Exchange / skip") self.status_lbl.configure(text="Choose cards to exchange by " + "clicking on them.") self.bet_amt_fld.configure(state=DISABLED) self.game_postdeal = True def _evaluate_hand(self): """Evalutes a player's hand after any exchanges have been made and we have the final hand. Process winnings if we have any. """ # Player has flipped their cards if we're here, # so figure out which ones they flipped and # exchange them and show the new cards. xchg_str = "" for cardimg in self.cardimg: if cardimg.flipped: xchg_str += cardimg.pos self.hand.exchange(xchg_str) self._show_cards() # Calculate winnings and show status winnings = self.hand.video_winnings(self.bet, easy=self.game_easy) win_str = self.hand.show_value() + ". " if winnings: self.pot += winnings win_str += "You won ${0:}!".format(winnings) self._update_pot() else: win_str += "Sorry, no win!" if self.pot == 0: win_str += " Out of money - game over!" self.game_over = True self.status_lbl.configure(text=win_str) # Update game variables and GUI if self.game_over: self.button.configure(text="New game") else: self.button.configure(text="Deal again") self.bet_amt_fld.configure(state=NORMAL) # Reset the bet amount field with the default bet. Check # here to make sure the default bet is not more money that # is in the pot, and limit it to that amount if it is. self.defaultbet = self.bet if self.bet <= self.pot else self.pot self.bet_str.set(str(self.defaultbet)) self.game_postdeal = False # Discard and then drop the current hand self.hand.discard() self.hand = [] def _show_bet_error(self, title, message): """Shows a message box and resets the bet field in response to an invalid bet. """ tkMessageBox.showerror(title, message) self.bet = self.defaultbet self.bet_str.set(str(self.defaultbet)) def _update_pot(self): """Updates the pot amount label with the current pot.""" txt_str = "${0:}".format(self.pot) self.pot_amt_lbl.configure(text=txt_str) def _show_cards(self): """Shows the cards in the poker hand on the screen.""" for cardimg, idx in zip(self.cardimg, self.hand.index_list()): cardfile = "{0}{1}.gif".format(self.gifdir, str(idx + 1)) img = PhotoImage(file=cardfile) cardimg.configure(image=img) cardimg.cardimage = img cardimg.flipped = False def _set_up_gui(self): """Sets up the Tkinter user interface.""" # Disable pylint warning for instance attributes defined outside # __init__(), since this method is called by __init__() # # pylint: disable=W0201 self.root = Tk() self.root.title('Video Poker') # Set up menubar self.menubar = Menu(self.root) self.gamemenu = Menu(self.menubar, tearoff=0) self.gamemenu.add_command(label="Quit", command=sys.exit) self.menubar.add_cascade(label="Game", menu=self.gamemenu) self.helpmenu = Menu(self.menubar, tearoff=0) self.helpmenu.add_command(label="About", command=self.help_about) self.menubar.add_cascade(label="Help", menu=self.helpmenu) self.root.config(menu=self.menubar) # Set up card images self.backimg = PhotoImage(file="{0}b.gif".format(self.gifdir)) for num in range(5): lbl = Label(self.root, image=self.backimg) lbl.grid(row=0, column=num, padx=10, pady=10) lbl.bind("<Button-1>", self.flip) lbl.flipped = True lbl.pos = str(num + 1) self.cardimg.append(lbl) # Set up labels, fields and buttons self.pot_lbl = Label(self.root, text="Pot:") self.pot_lbl.grid(row=1, column=0, padx=10, pady=2, sticky=W) self.pot_amt_lbl = Label(self.root, text="") self.pot_amt_lbl.grid(row=1, column=1, columnspan=2, padx=10, pady=2, sticky=W) self._update_pot() self.bet_lbl = Label(self.root, text="Bet ($):") self.bet_lbl.grid(row=2, column=0, padx=10, pady=2, sticky=W) self.bet_str = StringVar() self.bet_str.set(str(self.defaultbet)) self.bet_amt_fld = Entry(self.root, textvariable=self.bet_str) self.bet_amt_fld.grid(row=2, column=1, columnspan=2, padx=10, pady=2, sticky=W) self.button = Button(self.root, text="Deal", command=self.button_clicked) self.button.grid(row=1, column=3, rowspan=2, columnspan=2, sticky=W + E + S + N, padx=10) self.status_lbl = Label(self.root, bd=1, relief=SUNKEN, text="Welcome to the casino! " + "Click 'Deal' to play!") self.status_lbl.grid(row=3, column=0, columnspan=5, padx=10, pady=10, ipadx=10, ipady=10, sticky=W + E + S + N) # Show winnings table lbl = Label(self.root, text="Winnings Table", relief=RAISED) lbl.grid(row=4, column=1, columnspan=3, pady=15, ipadx=10, ipady=10, sticky=W + E) # Two different tables, one for easy mode, one for normal # mode, so be prepared to show either one. wte = {2500: "Royal Flush", 250: "Straight Flush", 100: "Four of a Kind", 50: "Full House", 20: "Flush", 15: "Straight", 4: "Three of a Kind", 3: "Two Pair", 2: "Jacks or Higher"} wtn = {800: "Royal Flush", 50: "Straight Flush", 25: "Four of a Kind", 9: "Full House", 6: "Flush", 4: "Straight", 3: "Three of a Kind", 2: "Two Pair", 1: "Jacks or Higher"} wtxt = wte if self.game_easy else wtn row = 5 for key in sorted(wtxt.keys(), reverse=True): lbl = Label(self.root, text=wtxt[key]) lbl.grid(row=row, column=1, columnspan=2, sticky=W) lbl = Label(self.root, text="{0} : 1".format(key)) lbl.grid(row=row, column=3, sticky=E) row += 1 lbl = Label(self.root, text="") lbl.grid(row=row, column=0, columnspan=5, pady=15) # pylint: enable=W0201 def help_about(self): """Shows an 'about' modal dialog. Callback method called by tk. """ about_win = Toplevel(self.root) # Set up dialog lbl = Label(about_win, text="Video Poker") lbl.grid(row=0, column=0, padx=10, pady=(10, 0), sticky=W + N) lbl = Label(about_win, text="by Charles Raymond Smith") lbl.grid(row=1, column=0, padx=10, pady=(0, 7), sticky=W + N) lbl = Label(about_win, text="Adapted from video poker by Paul Griffiths") lbl.grid(row=2, column=0, padx=10, pady=(0, 7), sticky=W + N) lbl = Label(about_win, text="Written in Python, with tkinter.") lbl.grid(row=3, column=0, padx=10, pady=7, sticky=W + N) lbl = Label(about_win, text="Copyright 2017 Charles Raymond Smith") lbl.grid(row=4, column=0, padx=10, pady=(7, 0), sticky=W + N) lbl = Label(about_win, text="Email: [email protected]") lbl.grid(row=5, column=0, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="This program is free software: you can " + "redistribute it and/or modify it under the terms") lbl.grid(row=6, column=0, columnspan=2, padx=10, pady=0, sticky=W + N) lbl = Label(about_win, text="of the GNU General Public License as " + "published by the Free Software Foundation, either") lbl.grid(row=7, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="version 3 of the License, or " + "(at your option) any later version.") lbl.grid(row=8, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="This program is distributed in " + "the hope that it will be useful, but WITHOUT ANY WARRANTY;") lbl.grid(row=9, column=0, columnspan=2, padx=10, pady=0, sticky=W + N) lbl = Label(about_win, text="without even the implied " + "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR") lbl.grid(row=10, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="PURPOSE. See the " + "GNU General Public License for more details.") lbl.grid(row=11, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) lbl = Label(about_win, text="You should have received a " + "copy of the GNU General Public License along with this") lbl.grid(row=12, column=0, columnspan=2, padx=10, pady=(0, 0), sticky=W + N) lbl = Label(about_win, text="program. If not, see " + "<http://www.gnu.org/licenses/>.") lbl.grid(row=13, column=0, columnspan=2, padx=10, pady=(0, 21), sticky=W + N) img = PhotoImage(file="{0}27.gif".format(self.gifdir)) lbl = Label(about_win, image=img) lbl.grid(row=0, column=1, rowspan=5, padx=10, pady=10, sticky=N + E) btn = Button(about_win, text="OK", command=about_win.quit) btn.grid(row=14, column=0, columnspan=2, padx=0, pady=(0, 10), ipadx=30, ipady=3) # Show dialog about_win.transient(self.root) about_win.parent = self.root about_win.protocol("WM_DELETE_WINDOW", about_win.destroy) about_win.geometry("+{0}+{1}".format(self.root.winfo_rootx() + 50, self.root.winfo_rooty() + 50)) about_win.title("About Video Poker") about_win.focus_set() about_win.grab_set() about_win.mainloop() about_win.destroy()
class Cell: def __init__(self, parent, type, x, y, height, temperature_multiplier, moisture, owner): self.parent = parent self.type = type self.x = x self.y = y self.cell_id = self.parent.get_next_id('cell') self.id = -1 self.building_capacity = 100 self.terrain = Terrain(height, moisture) self.temperature_multiplier = max(0, temperature_multiplier) self.temperature = None self.buildings = building.base_buildings(None) self.high_temp_range = random.random() / 5 self.low_temp_range = random.random() / 5 self.owner = owner self.make_id() self.can_pass = not self.terrain.is_water() # Determines whether it is legal for a group to move onto this square # Kenny - detects whether or not the cell's terrain is water. If it is water unit can't move through def can_move(self, group): return self.can_pass # For now it is always lega def save(self): self.parent.db.execute( 'db/internal/terrain/cell_insert.sql', { 'cell_id': self.cell_id, 'type': self.type, 'x': self.x, 'y': self.y, 'height': self.terrain.height, 'temperature_multiplier': self.temperature_multiplier, 'moisture': self.terrain.moisture, 'owner': self.owner.id if self.owner is not None else -1, 'building_capacity': self.building_capacity, 'high_temp_range': self.high_temp_range, 'low_temp_range': self.low_temp_range }) for building in self.buildings: if building.number > 0: building.save(self.parent.db, self.cell_id) def get_population_capacity(self): return sum([ building.get_population_capacity() for building in self.buildings ]) def get_food_output(self): result = random.randint(BASE_CELL_MIN_FOOD_PRODUCTION, BASE_CELL_FOOD_PRODUCTION) result *= self.food_production_multiplier() return result def building_count(self): return sum([building.number for building in self.buildings]) def get_total_buiding_size(self): return sum([ building.get_size() * building.number for building in self.buildings ]) def get_available_building_capacity(self): multiplier = 1.0 if self.owner is not None: best = self.owner.nation.tech.get_best_in_category( 'compact_building') if best is not None: multiplier = best.multiplier return multiplier * self.building_capacity - self.get_total_buiding_size( ) def build_buildings(self): improvement_chance = int((self.building_count() + 1) / (math.sqrt(self.owner.population) + 1)) if random.randint(0, improvement_chance + 1) == 0: available_buildings = filter( lambda b: b.get_size() <= self.get_available_building_capacity( ), self.buildings) if len(available_buildings) > 0: build_building = utility.weighted_random_choice( available_buildings, weight=lambda _, b: 1.0 / b.get_cost()) if self.owner.nation.money > build_building.get_cost(): self.owner.nation.money -= build_building.get_cost() build_building.number += 1 def get_resource_productions(self): result = {} for curBuilding in self.buildings: production = curBuilding.get_resource_productions() for resource in production: if resource in result: result[resource] += production[resource] else: result[resource] = production[resource] return result def get_tax_rate(self): return utility.product( [building.get_tax_rate() for building in self.buildings]) def get_money_output(self): return sum( [building.get_money_output() for building in self.buildings]) def get_elevation(self): return to_meters(self.terrain.height * MAX_HEIGHT) def get_high_temperature(self): return self.get_temperature( ) + self.get_temperature() * self.high_temp_range def get_low_temperature(self): return self.get_temperature( ) - self.get_temperature() * self.low_temp_range def get_temperature_range(self): return self.get_high_temperature() - self.get_low_temperature() def get_temperature(self): # The base temperature never changes, so we only need to calculate it once. if self.temperature is None: self.temperature = temperature( self.terrain.height * MAX_HEIGHT, self.y, utility.S_HEIGHT) * (1 - self.temperature_multiplier) return self.temperature # http://www.sciencedirect.com/science/article/pii/0002157177900073 def get_dew_point(self): return 0.0023 * self.get_elevation() + 0.37 * self.get_temperature( ) + 0.53 * self.get_temperature_range() - 10.9 def get_evaporation(self): amount = (self.get_temperature() + 15.0 * self.get_dew_point()) / ( 80.0 - self.get_temperature()) amount *= random.random() if self.terrain.is_water(): return amount if amount > self.terrain.moisture: amount = self.terrain.moisture self.terrain.moisture = 0 return amount else: self.terrain.moisture -= amount return amount def food_production_multiplier(self): # Higher temperature means better production. multiplier = self.get_temperature( ) / 98.0 * self.terrain.get_food_production_multiplier() for neighbor in self.neighbors(): # So does being surrounding by water if neighbor.terrain.is_water(): multiplier *= neighbor.terrain.get_food_production_multiplier() return multiplier def reset_color(self): if self.id >= 0: if self.owner is not None: self.parent.canvas.itemconfig(self.id, fill=self.owner.nation.color) else: self.parent.canvas.itemconfig(self.id, fill=self.terrain.color) def make_id(self): start_x, start_y = self.x * utility.CELL_SIZE, self.y * utility.CELL_SIZE end_x, end_y = start_x + utility.CELL_SIZE, start_y + utility.CELL_SIZE try: if self.owner is not None: self.id = self.parent.canvas.create_rectangle( start_x, start_y, end_x, end_y, width=0, fill=self.owner.nation.color) else: self.id = self.parent.canvas.create_rectangle( start_x, start_y, end_x, end_y, width=0, fill=self.terrain.color) except: pass def show_information_gui(self): self.gui_window = Tk() self.gui_window.title('Cell Information: ({}, {})'.format( self.x, self.y)) self.gui_window.geometry("400x300+0+0") self.gui_window.config(background='white') self.type_label = gui.Label(self.gui_window, text='Type: {}'.format(self.type)) self.type_label.grid(row=0, sticky=W) self.owning_city_label = gui.Label(self.gui_window, text='Owning city: ') self.owning_city_label.grid(row=1, sticky=W) self.owning_nation_label = gui.Label(self.gui_window, text='Owning nation: ') self.owning_nation_label.grid(row=2, sticky=W) if self.owner is not None: self.owning_city_button = gui.Button( self.gui_window, text=self.owner.name, command=self.owner.show_information_gui) self.owning_nation_button = gui.Button( self.gui_window, text=self.owner.nation.name, command=self.owner.nation.show_information_gui) else: self.owning_city_button = gui.Button(self.gui_window, text='None') self.owning_nation_button = gui.Button(self.gui_window, text='None') self.owning_city_button.grid(row=1, column=1, sticky=W) self.owning_nation_button.grid(row=2, column=1, sticky=W) self.building_capacity_label = gui.Label( self.gui_window, text='{} of {} filled.'.format(self.get_total_buiding_size(), self.building_capacity)) self.building_capacity_label.grid(row=3) self.buildings_display = Listbox(self.gui_window) for building in self.buildings: self.buildings_display.insert( END, '{}: {}'.format(building.name, building.number)) self.buildings_display.grid(row=4, column=0, columnspan=3, sticky=W + E) def update_self(self): if self.owner is None: self.parent.canvas.itemconfig(self.id, fill=self.terrain.color) else: self.parent.canvas.itemconfig(self.id, fill=self.owner.nation.color) def change_type(self, new_type): self.type = new_type self.update_self() def change_owner(self, new_owner, new_type=None): if self.owner is not None: # Remove this cell from the list of owned cells self.owner.remove_cell(self) # This must be before .add_cell if new_type is not None: self.change_type(new_type) self.owner = new_owner if self.owner is not None: for curBuilding in self.buildings: curBuilding.city = new_owner self.owner.add_cell(self) else: self.new_type = '' # There is no cell type for an unowned cell. self.buildings = building.base_buildings(None) self.update_self() def neighbors(self): result = [] if self.x > 0: result.append(self.parent.cells[self.x - 1][self.y]) # else: # result.append(self.parent.cells[utility.S_WIDTH // utility.CELL_SIZE - 1][self.y]) if self.y > 0: result.append(self.parent.cells[self.x][self.y - 1]) # else: # result.append(self.parent.cells[self.x][utility.S_HEIGHT // utility.CELL_SIZE - 1]) if self.x < utility.S_WIDTH // utility.CELL_SIZE - 1: result.append(self.parent.cells[self.x + 1][self.y]) # else: # result.append(self.parent.cells[0][self.y]) if self.y < utility.S_HEIGHT // utility.CELL_SIZE - 1: result.append(self.parent.cells[self.x][self.y + 1]) # else: # result.append(self.parent.cells[self.x][0]) return result
class PiPresents(object): def pipresents_version(self): vitems=self.pipresents_issue.split('.') if len(vitems)==2: # cope with 2 digit version numbers before 1.3.2 return 1000*int(vitems[0])+100*int(vitems[1]) else: return 1000*int(vitems[0])+100*int(vitems[1])+int(vitems[2]) def __init__(self): gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL) self.pipresents_issue="1.3.2" self.pipresents_minorissue = '1.3.2a' # position and size of window without -f command line option self.nonfull_window_width = 0.45 # proportion of width self.nonfull_window_height= 0.7 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y=0 # position of top left corner StopWatch.global_enable=False # set up the handler for SIGTERM signal.signal(signal.SIGTERM,self.handle_sigterm) # **************************************** # Initialisation # *************************************** # get command line options self.options=command_options() # get Pi Presents code directory pp_dir=sys.path[0] self.pp_dir=pp_dir if not os.path.exists(pp_dir+"/pipresents.py"): if self.options['manager'] is False: tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit(102) # Initialise logging and tracing Monitor.log_path=pp_dir self.mon=Monitor() # Init in PiPresents only self.mon.init() # uncomment to enable control of logging from within a class # Monitor.enable_in_code = True # enables control of log level in the code for a class - self.mon.set_log_level() # make a shorter list to log/trace only some classes without using enable_in_code. Monitor.classes = ['PiPresents', 'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow', 'GapShow','Show','ArtShow', 'AudioPlayer','BrowserPlayer','ImagePlayer','MenuPlayer','MessagePlayer','VideoPlayer','Player', 'MediaList','LiveList','ShowList', 'PathManager','ControlsManager','ShowManager','PluginManager', 'MplayerDriver','OMXDriver','UZBLDriver', 'KbdDriver','GPIODriver','TimeOfDay','ScreenDriver','Animate','OSCDriver', 'Network','Mailer' ] # Monitor.classes=['PiPresents','MediaShow','GapShow','Show','VideoPlayer','Player','OMXDriver'] # get global log level from command line Monitor.log_level = int(self.options['debug']) Monitor.manager = self.options['manager'] # print self.options['manager'] self.mon.newline(3) self.mon.sched (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue + ' at '+time.strftime("%Y-%m-%d %H:%M.%S")) self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue+ ' at '+time.strftime("%Y-%m-%d %H:%M.%S")) # self.mon.log (self," OS and separator:" + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: "+sys.path[0]) # log versions of Raspbian and omxplayer, and GPU Memory with open("/boot/issue.txt") as file: self.mon.log(self,'\nRaspbian: '+file.read()) self.mon.log(self,'\n'+check_output(["omxplayer", "-v"])) self.mon.log(self,'\nGPU Memory: '+check_output(["vcgencmd", "get_mem", "gpu"])) if "DESKTOP_SESSION" not in os.environ: print 'Pi Presents must be run from the Desktop' self.mon.log(self,'Pi Presents must be run from the Desktop') self.mon.finish() sys.exit(102) else: self.mon.log(self,'Desktop is '+ os.environ['DESKTOP_SESSION']) # optional other classes used self.root=None self.ppio=None self.tod=None self.animate=None self.gpiodriver=None self.oscdriver=None self.osc_enabled=False self.gpio_enabled=False self.tod_enabled=False self.email_enabled=False if os.geteuid() == 0: self.mon.err(self,'Do not run Pi Presents with sudo') self.end('error','Do not run Pi Presents with sudo') user=os.getenv('USER') self.mon.log(self,'User is: '+ user) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # does not work # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # does not work # check network is available self.network_connected=False self.network_details=False self.interface='' self.ip='' self.unit='' # sets self.network_connected and self.network_details self.init_network() # start the mailer and send email when PP starts self.email_enabled=False if self.network_connected is True: self.init_mailer() if self.email_enabled is True and self.mailer.email_at_start is True: subject= '[Pi Presents] ' + self.unit + ': PP Started on ' + time.strftime("%Y-%m-%d %H:%M") message = time.strftime("%Y-%m-%d %H:%M") + '\nUnit: ' + self.unit + ' Profile: '+ self.options['profile']+ '\n ' + self.interface + '\n ' + self.ip self.send_email('start',subject,message) # get profile path from -p option if self.options['profile'] != '': self.pp_profile_path="/pp_profiles/"+self.options['profile'] else: self.mon.err(self,"Profile not specified in command ") self.end('error','Profile not specified with the commands -p option') # get directory containing pp_home from the command, if self.options['home'] == "": home = os.sep+ 'home' + os.sep + user + os.sep+"pp_home" else: home = self.options['home'] + os.sep+ "pp_home" self.mon.log(self,"pp_home directory is: " + home) # check if pp_home exists. # try for 10 seconds to allow usb stick to automount found=False for i in range (1, 10): self.mon.log(self,"Trying pp_home at: " + home + " (" + str(i)+')') if os.path.exists(home): found=True self.pp_home=home break time.sleep (1) if found is True: self.mon.log(self,"Found Requested Home Directory, using pp_home at: " + home) else: self.mon.err(self,"Failed to find pp_home directory at " + home) self.end('error',"Failed to find pp_home directory at " + home) # check profile exists self.pp_profile=self.pp_home+self.pp_profile_path if os.path.exists(self.pp_profile): self.mon.sched(self,"Running profile: " + self.pp_profile_path) self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile) self.end('error',"Failed to find requested profile: "+ self.pp_profile) self.mon.start_stats(self.options['profile']) if self.options['verify'] is True: val =Validator() if val.validate_profile(None,pp_dir,self.pp_home,self.pp_profile,self.pipresents_issue,False) is False: self.mon.err(self,"Validation Failed") self.end('error','Validation Failed') # initialise and read the showlist in the profile self.showlist=ShowList() self.showlist_file= self.pp_profile+ "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self,"showlist not found at "+self.showlist_file) self.end('error',"showlist not found at "+self.showlist_file) # check profile and Pi Presents issues are compatible if self.showlist.profile_version() != self.pipresents_version(): self.mon.err(self,"Version of showlist " + self.showlist.profile_version_string + " is not same as Pi Presents") self.end('error',"Version of showlist " + self.showlist.profile_version_string + " is not same as Pi Presents") # get the 'start' show from the showlist index = self.showlist.index_of_show('start') if index >=0: self.showlist.select(index) self.starter_show=self.showlist.selected_show() else: self.mon.err(self,"Show [start] not found in showlist") self.end('error',"Show [start] not found in showlist") # ******************** # SET UP THE GUI # ******************** # turn off the screenblanking and saver if self.options['noblank'] is True: call(["xset","s", "off"]) call(["xset","s", "-dpms"]) self.root=Tk() self.title='Pi Presents - '+ self.pp_profile self.icon_text= 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg=self.starter_show['background-colour']) self.mon.log(self, 'monitor screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixels') if self.options['screensize'] =='': self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() else: reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize']) if reason =='error': self.mon.err(self,message) self.end('error',message) self.mon.log(self, 'forced screen dimensions (--screensize) are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixels') # set window dimensions and decorations if self.options['fullscreen'] is False: self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width) self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height) self.window_x=self.nonfull_window_x self.window_y=self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) else: self.window_width=self.screen_width self.window_height=self.screen_height self.root.attributes('-fullscreen', True) os.system('unclutter &') self.window_x=0 self.window_y=0 self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) self.root.attributes('-zoomed','1') # canvas cover the whole screen whatever the size of the window. self.canvas_height=self.screen_height self.canvas_width=self.screen_width # make sure focus is set. self.root.focus_set() # define response to main window closing. self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort) # setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg=self.starter_show['background-colour']) if self.options['fullscreen'] is True: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) else: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=1, highlightcolor='yellow') self.canvas.place(x=0,y=0) # self.canvas.config(bg='black') self.canvas.focus_set() # **************************************** # INITIALISE THE INPUT DRIVERS # **************************************** # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs/ # use keyboard driver to bind keys to symbolic names and to set up callback kbd=KbdDriver() if kbd.read(pp_dir,self.pp_home,self.pp_profile) is False: self.end('error','cannot find, or error in keys.cfg') kbd.bind_keys(self.root,self.handle_input_event) self.sr=ScreenDriver() # read the screen click area config file reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile) if reason == 'error': self.end('error','cannot find, or error in screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes # click areas are made on the Pi Presents canvas not the show canvases. reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event) if reason == 'error': self.mon.err(self,message) self.end('error',message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required=False self.terminate_required=False self.exitpipresents_required=False # delete omxplayer dbus files # if os.path.exists("/tmp/omxplayerdbus.{}".format(user)): # os.remove("/tmp/omxplayerdbus.{}".format(user)) # if os.path.exists("/tmp/omxplayerdbus.{}.pid".format(user)): # os.remove("/tmp/omxplayerdbus.{}.pid".format(user)) # kick off GPIO if enabled by command line option self.gpio_enabled=False if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+os.sep+ 'gpio.cfg'): # initialise the GPIO self.gpiodriver=GPIODriver() reason,message=self.gpiodriver.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,50,self.handle_input_event) if reason == 'error': self.end('error',message) else: self.gpio_enabled=True # and start polling gpio self.gpiodriver.poll() # kick off animation sequencer self.animate = Animate() self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event) self.animate.poll() #create a showmanager ready for time of day scheduler and osc server show_id=-1 self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home) # first time through set callback to terminate Pi Presents if all shows have ended. self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist) # Register all the shows in the showlist reason,message=self.show_manager.register_shows() if reason == 'error': self.mon.err(self,message) self.end('error',message) # Init OSCDriver, read config and start OSC server self.osc_enabled=False if self.network_connected is True: if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'): self.oscdriver=OSCDriver() reason,message=self.oscdriver.init(self.pp_profile,self.handle_command,self.handle_input_event,self.e_osc_handle_output_event) if reason == 'error': self.mon.err(self,message) self.end('error',message) else: self.osc_enabled=True self.root.after(1000,self.oscdriver.start_server()) # enable ToD scheduler if schedule exists if os.path.exists(self.pp_profile + os.sep + 'schedule.json'): self.tod_enabled = True else: self.tod_enabled=False # warn if the network not available when ToD required if self.tod_enabled is True and self.network_connected is False: self.mon.warn(self,'Network not connected so Time of Day scheduler may be using the internal clock') # warn about start shows and scheduler if self.starter_show['start-show']=='' and self.tod_enabled is False: self.mon.sched(self,"No Start Shows in Start Show and no shows scheduled") self.mon.warn(self,"No Start Shows in Start Show and no shows scheduled") if self.starter_show['start-show'] !='' and self.tod_enabled is True: self.mon.sched(self,"Start Shows in Start Show and shows scheduled - conflict?") self.mon.warn(self,"Start Shows in Start Show and shows scheduled - conflict?") # run the start shows self.run_start_shows() # kick off the time of day scheduler which may run additional shows if self.tod_enabled is True: self.tod=TimeOfDay() self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.root,self.handle_command) self.tod.poll() # start Tkinters event loop self.root.mainloop( ) def parse_screen(self,size_text): fields=size_text.split('*') if len(fields)!=2: return 'error','do not understand --screensize comand option',0,0 elif fields[0].isdigit() is False or fields[1].isdigit() is False: return 'error','dimensions are not positive integers in --screensize',0,0 else: return 'normal','',int(fields[0]),int(fields[1]) # ********************* # RUN START SHOWS # ******************** def run_start_shows(self): self.mon.trace(self,'run start shows') # parse the start shows field and start the initial shows show_refs=self.starter_show['start-show'].split() for show_ref in show_refs: reason,message=self.show_manager.control_a_show(show_ref,'open') if reason == 'error': self.mon.err(self,message) # ********************* # User inputs # ******************** # handles one command provided as a line of text def handle_command(self,command_text,source='',show=''): # print 'PIPRESENTS ',command_text,source,'from',show self.mon.log(self,"command received: " + command_text) if command_text.strip()=="": return if command_text[0]=='/': if self.osc_enabled is True: self.oscdriver.send_command(command_text) return fields= command_text.split() show_command=fields[0] if len(fields)>1: show_ref=fields[1] else: show_ref='' if show_command in ('open','close'): self.mon.sched(self, command_text + ' received from show:'+show) if self.shutdown_required is False and self.terminate_required is False: reason,message=self.show_manager.control_a_show(show_ref,show_command) else: return elif show_command =='monitor': self.handle_monitor_command(show_ref) return elif show_command == 'event': self.handle_input_event(show_ref,'Show Control') return elif show_command == 'exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to get out of st thread self.root.after(1,self.e_all_shows_ended_callback) return else: reason,message= self.show_manager.exit_all_shows() elif show_command == 'shutdownnow': # need root.after to get out of st thread self.root.after(1,self.e_shutdown_pressed) return else: reason='error' message = 'command not recognised: '+ show_command if reason=='error': self.mon.err(self,message) return def handle_monitor_command(self,command): if command == 'on': os.system('vcgencmd display_power 1 >/dev/null') elif command == 'off': os.system('vcgencmd display_power 0 >/dev/null') def e_all_shows_ended_callback(self): self.all_shows_ended_callback('normal','no shows running') def e_shutdown_pressed(self): self.shutdown_pressed('now') def e_osc_handle_output_event(self,line): #jump out of server thread self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg)) def osc_handle_output_event(self,line): self.mon.log(self,"output event received: "+ line) #osc sends output events as a string reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line) if reason == 'error': self.mon.err(self,message) self.end(reason,message) self.handle_output_event(name,param_type,param_values,0) def handle_output_event(self,symbol,param_type,param_values,req_time): if self.gpio_enabled is True: reason,message=self.gpiodriver.handle_output_event(symbol,param_type,param_values,req_time) if reason =='error': self.mon.err(self,message) self.end(reason,message) else: self.mon.warn(self,'GPIO not enabled') # all input events call this callback with a symbolic name. # handle events that affect PP overall, otherwise pass to all active shows def handle_input_event(self,symbol,source): self.mon.log(self,"event received: "+symbol + ' from '+ source) if symbol == 'pp-terminate': self.handle_user_abort() elif symbol == 'pp-shutdown': self.shutdown_pressed('delay') elif symbol == 'pp-shutdownnow': # need root.after to grt out of st thread self.root.after(1,self.e_shutdown_pressed) return elif symbol == 'pp-exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to grt out of st thread self.root.after(1,self.e_all_shows_ended_callback) return reason,message= self.show_manager.exit_all_shows() else: # events for shows affect the show and could cause it to exit. for show in self.show_manager.shows: show_obj=show[ShowManager.SHOW_OBJ] if show_obj is not None: show_obj.handle_input_event(symbol) def shutdown_pressed(self, when): if when == 'delay': self.root.after(5000,self.on_shutdown_delay) else: self.shutdown_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def on_shutdown_delay(self): # 5 second delay is up, if shutdown button still pressed then shutdown if self.gpiodriver.shutdown_pressed() is True: self.shutdown_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def handle_sigterm(self,signum,frame): self.mon.log(self,'SIGTERM received - '+ str(signum)) self.terminate() def handle_user_abort(self): self.mon.log(self,'User abort received') self.terminate() def terminate(self): self.mon.log(self, "terminate received") self.terminate_required=True needs_termination=False for show in self.show_manager.shows: # print show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF] if show[ShowManager.SHOW_OBJ] is not None: needs_termination=True self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF]) # call shows terminate method # eventually the show will exit and after all shows have exited all_shows_callback will be executed. show[ShowManager.SHOW_OBJ].terminate() if needs_termination is False: self.end('killed','killed - no termination of shows required') # ****************************** # Ending Pi Presents after all the showers and players are closed # ************************** # callback from ShowManager when all shows have ended def all_shows_ended_callback(self,reason,message): self.canvas.config(bg=self.starter_show['background-colour']) if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True: self.end(reason,message) def end(self,reason,message): self.mon.log(self,"Pi Presents ending with reason: " + reason) if self.root is not None: self.root.destroy() self.tidy_up() # gc.collect() # print gc.garbage if reason == 'killed': if self.email_enabled is True and self.mailer.email_on_terminate is True: subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Terminated' message = time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip self.send_email(reason,subject,message) self.mon.sched(self, "Pi Presents Terminated, au revoir\n") self.mon.log(self, "Pi Presents Terminated, au revoir") # close logging files self.mon.finish() sys.exit(101) elif reason == 'error': if self.email_enabled is True and self.mailer.email_on_error is True: subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Error' message_text = 'Error message: '+ message + '\n'+ time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip self.send_email(reason,subject,message_text) self.mon.sched(self, "Pi Presents closing because of error, sorry\n") self.mon.log(self, "Pi Presents closing because of error, sorry") # close logging files self.mon.finish() sys.exit(102) else: self.mon.sched(self,"Pi Presents exiting normally, bye\n") self.mon.log(self,"Pi Presents exiting normally, bye") # close logging files self.mon.finish() if self.shutdown_required is True: # print 'SHUTDOWN' call (['sudo','shutdown','now','SHUTTING DOWN']) sys.exit(100) def init_network(self): timeout=int(self.options['nonetwork']) if timeout== 0: self.network_connected=False self.unit='' self.ip='' self.interface='' return self.network=Network() self.network_connected=False # try to connect to network self.mon.log (self, 'Waiting up to '+ str(timeout) + ' seconds for network') success=self.network.wait_for_network(timeout) if success is False: self.mon.warn(self,'Failed to connect to network after ' + str(timeout) + ' seconds') # tkMessageBox.showwarning("Pi Presents","Failed to connect to network so using fake-hwclock") return self.network_connected=True self.mon.sched (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S")) self.mon.log (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S")) # Get web configuration self.network_details=False network_options_file_path=self.pp_dir+os.sep+'pp_config'+os.sep+'pp_web.cfg' if not os.path.exists(network_options_file_path): self.mon.warn(self,"pp_web.cfg not found at "+network_options_file_path) return self.mon.log(self, 'Found pp_web.cfg in ' + network_options_file_path) self.network.read_config(network_options_file_path) self.unit=self.network.unit # get interface and IP details of preferred interface self.interface,self.ip = self.network.get_preferred_ip() if self.interface == '': self.network_connected=False return self.network_details=True self.mon.log (self, 'Network details ' + self.unit + ' ' + self.interface + ' ' +self.ip) def init_mailer(self): self.email_enabled=False email_file_path = self.pp_dir+os.sep+'pp_config'+os.sep+'pp_email.cfg' if not os.path.exists(email_file_path): self.mon.log(self,'pp_email.cfg not found at ' + email_file_path) return self.mon.log(self,'Found pp_email.cfg at ' + email_file_path) self.mailer=Mailer() self.mailer.read_config(email_file_path) # all Ok so can enable email if config file allows it. if self.mailer.email_allowed is True: self.email_enabled=True self.mon.log (self,'Email Enabled') def send_email(self,reason,subject,message): if self.try_connect() is False: return False else: success,error = self.mailer.send(subject,message) if success is False: self.mon.log(self, 'Failed to send email: ' + str(error)) success,error=self.mailer.disconnect() if success is False: self.mon.log(self,'Failed disconnect after send:' + str(error)) return False else: self.mon.log(self,'Sent email for ' + reason) success,error=self.mailer.disconnect() if success is False: self.mon.log(self,'Failed disconnect from email server ' + str(error)) return True def try_connect(self): tries=1 while True: success, error = self.mailer.connect() if success is True: return True else: self.mon.log(self,'Failed to connect to email SMTP server ' + str(tries) + '\n ' +str(error)) tries +=1 if tries >5: self.mon.log(self,'Failed to connect to email SMTP server after ' + str(tries)) return False # tidy up all the peripheral bits of Pi Presents def tidy_up(self): self.handle_monitor_command('on') self.mon.log(self, "Tidying Up") # turn screen blanking back on if self.options['noblank'] is True: call(["xset","s", "on"]) call(["xset","s", "+dpms"]) # tidy up animation and gpio if self.animate is not None: self.animate.terminate() if self.gpio_enabled==True: self.gpiodriver.terminate() if self.osc_enabled is True: self.oscdriver.terminate() # tidy up time of day scheduler if self.tod_enabled is True: self.tod.terminate()
class PPEditor(object): # *************************************** # INIT # *************************************** def __init__(self): self.editor_issue="1.3" # get command options self.command_options=ed_options() # get directory holding the code self.pp_dir=sys.path[0] if not os.path.exists(self.pp_dir+os.sep+"pp_editor.py"): tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit() # Initialise logging Monitor.log_path=self.pp_dir self.mon=Monitor() self.mon.init() Monitor.classes = ['PPEditor','EditItem','Validator'] Monitor.log_level = int(self.command_options['debug']) self.mon.log (self, "Pi Presents Editor is starting") self.mon.log (self," OS and separator " + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: code "+sys.path[0]) # set up the gui # root is the Tkinter root widget self.root = Tk() self.root.title("Editor for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False,False) # define response to main window closing self.root.protocol ("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = StringVar() self.display_selected_track_title = StringVar() self.display_show = StringVar() # define menu menubar = Menu(self.root) profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black") profilemenu.add_command(label='Open', command = self.open_existing_profile) profilemenu.add_command(label='Validate', command = self.validate_profile) menubar.add_cascade(label='Profile', menu = profilemenu) ptypemenu = Menu(profilemenu, tearoff=0, bg="grey", fg="black") ptypemenu.add_command(label='Exhibit', command = self.new_exhibit_profile) ptypemenu.add_command(label='Media Show', command = self.new_mediashow_profile) ptypemenu.add_command(label='Art Media Show', command = self.new_artmediashow_profile) ptypemenu.add_command(label='Menu', command = self.new_menu_profile) ptypemenu.add_command(label='Presentation', command = self.new_presentation_profile) ptypemenu.add_command(label='Interactive', command = self.new_interactive_profile) ptypemenu.add_command(label='Live Show', command = self.new_liveshow_profile) ptypemenu.add_command(label='Art Live Show', command = self.new_artliveshow_profile) ptypemenu.add_command(label='RadioButton Show', command = self.new_radiobuttonshow_profile) ptypemenu.add_command(label='Hyperlink Show', command = self.new_hyperlinkshow_profile) ptypemenu.add_command(label='Blank', command = self.new_blank_profile) profilemenu.add_cascade(label='New from Template', menu = ptypemenu) showmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") showmenu.add_command(label='Delete', command = self.remove_show) showmenu.add_command(label='Edit', command = self.m_edit_show) showmenu.add_command(label='Copy To', command = self.copy_show) menubar.add_cascade(label='Show', menu = showmenu) stypemenu = Menu(showmenu, tearoff=0, bg="grey", fg="black") stypemenu.add_command(label='Menu', command = self.add_menushow) stypemenu.add_command(label='MediaShow', command = self.add_mediashow) stypemenu.add_command(label='LiveShow', command = self.add_liveshow) stypemenu.add_command(label='HyperlinkShow', command = self.add_hyperlinkshow) stypemenu.add_command(label='RadioButtonShow', command = self.add_radiobuttonshow) stypemenu.add_command(label='ArtMediaShow', command = self.add_artmediashow) stypemenu.add_command(label='ArtLiveShow', command = self.add_artliveshow) showmenu.add_cascade(label='Add', menu = stypemenu) medialistmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='MediaList', menu = medialistmenu) medialistmenu.add_command(label='Add', command = self.add_medialist) medialistmenu.add_command(label='Delete', command = self.remove_medialist) medialistmenu.add_command(label='Copy To', command = self.copy_medialist) trackmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") trackmenu.add_command(label='Delete', command = self.remove_track) trackmenu.add_command(label='Edit', command = self.m_edit_track) trackmenu.add_command(label='Add from Dir', command = self.add_tracks_from_dir) trackmenu.add_command(label='Add from File', command = self.add_track_from_file) menubar.add_cascade(label='Track', menu = trackmenu) typemenu = Menu(trackmenu, tearoff=0, bg="grey", fg="black") typemenu.add_command(label='Video', command = self.new_video_track) typemenu.add_command(label='Audio', command = self.new_audio_track) typemenu.add_command(label='Image', command = self.new_image_track) typemenu.add_command(label='Web', command = self.new_web_track) typemenu.add_command(label='Message', command = self.new_message_track) typemenu.add_command(label='Show', command = self.new_show_track) typemenu.add_command(label='Menu Track', command = self.new_menu_track) trackmenu.add_cascade(label='New', menu = typemenu) oscmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='OSC', menu = oscmenu) oscmenu.add_command(label='Create OSC configuration', command = self.create_osc) oscmenu.add_command(label='Edit OSC Configuration', command = self.edit_osc) oscmenu.add_command(label='Delete OSC Configuration', command = self.delete_osc) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu = toolsmenu) toolsmenu.add_command(label='Update All', command = self.update_all) optionsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu = optionsmenu) optionsmenu.add_command(label='Edit', command = self.edit_options) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu = helpmenu) helpmenu.add_command(label='Help', command = self.show_help) helpmenu.add_command(label='About', command = self.about) self.root.config(menu=menubar) top_frame=Frame(self.root) top_frame.pack(side=TOP) bottom_frame=Frame(self.root) bottom_frame.pack(side=TOP, fill=BOTH, expand=1) left_frame=Frame(bottom_frame, padx=5) left_frame.pack(side=LEFT) middle_frame=Frame(bottom_frame,padx=5) middle_frame.pack(side=LEFT) right_frame=Frame(bottom_frame,padx=5,pady=10) right_frame.pack(side=LEFT) updown_frame=Frame(bottom_frame,padx=5) updown_frame.pack(side=LEFT) tracks_title_frame=Frame(right_frame) tracks_title_frame.pack(side=TOP) tracks_label = Label(tracks_title_frame, text="Tracks in Selected Medialist") tracks_label.pack() tracks_frame=Frame(right_frame) tracks_frame.pack(side=TOP) shows_title_frame=Frame(left_frame) shows_title_frame.pack(side=TOP) shows_label = Label(shows_title_frame, text="Shows") shows_label.pack() shows_frame=Frame(left_frame) shows_frame.pack(side=TOP) shows_title_frame=Frame(left_frame) shows_title_frame.pack(side=TOP) medialists_title_frame=Frame(left_frame) medialists_title_frame.pack(side=TOP) medialists_label = Label(medialists_title_frame, text="Medialists") medialists_label.pack() medialists_frame=Frame(left_frame) medialists_frame.pack(side=LEFT) # define buttons add_button = Button(middle_frame, width = 5, height = 2, text='Edit\nShow', fg='black', command = self.m_edit_show, bg="light grey") add_button.pack(side=RIGHT) add_button = Button(updown_frame, width = 5, height = 1, text='Add', fg='black', command = self.add_track_from_file, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Edit', fg='black', command = self.m_edit_track, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Up', fg='black', command = self.move_track_up, bg="light grey") add_button.pack(side=TOP) add_button = Button(updown_frame, width = 5, height = 1, text='Down', fg='black', command = self.move_track_down, bg="light grey") add_button.pack(side=TOP) # define display of showlist scrollbar = Scrollbar(shows_frame, orient=VERTICAL) self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=12, width = 40, bg="white",activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.shows_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.shows_display.pack(side=LEFT, fill=BOTH, expand=1) self.shows_display.bind("<ButtonRelease-1>", self.e_select_show) # define display of medialists scrollbar = Scrollbar(medialists_frame, orient=VERTICAL) self.medialists_display = Listbox(medialists_frame, selectmode=SINGLE, height=12, width = 40, bg="white",activestyle=NONE, fg="black",yscrollcommand=scrollbar.set) scrollbar.config(command=self.medialists_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.medialists_display.pack(side=LEFT, fill=BOTH, expand=1) self.medialists_display.bind("<ButtonRelease-1>", self.select_medialist) # define display of tracks scrollbar = Scrollbar(tracks_frame, orient=VERTICAL) self.tracks_display = Listbox(tracks_frame, selectmode=SINGLE, height=25, width = 40, bg="white",activestyle=NONE, fg="black",yscrollcommand=scrollbar.set) scrollbar.config(command=self.tracks_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.tracks_display.pack(side=LEFT,fill=BOTH, expand=1) self.tracks_display.bind("<ButtonRelease-1>", self.e_select_track) # initialise editor options class and OSC config class self.options=Options(self.pp_dir) # creates options file in code directory if necessary self.osc_config=OSCConfig() # initialise variables self.init() # and enter Tkinter event loop self.root.mainloop() # *************************************** # INIT AND EXIT # *************************************** def app_exit(self): self.root.destroy() exit() def init(self): self.options.read() self.pp_home_dir = self.options.pp_home_dir self.pp_profiles_offset = self.options.pp_profiles_offset self.initial_media_dir = self.options.initial_media_dir self.mon.log(self,"Data Home from options is "+self.pp_home_dir) self.mon.log(self,"Current Profiles Offset from options is "+self.pp_profiles_offset) self.mon.log(self,"Initial Media from options is "+self.initial_media_dir) self.pp_profile_dir='' self.osc_config_file = '' self.current_medialist=None self.current_showlist=None self.current_show=None self.shows_display.delete(0,END) self.medialists_display.delete(0,END) self.tracks_display.delete(0,END) # *************************************** # MISCELLANEOUS # *************************************** def edit_options(self): """edit the options then read them from file""" eo = OptionsDialog(self.root, self.options.options_file,'Edit Options') if eo.result is True: self.init() def show_help (self): tkMessageBox.showinfo("Help","Read 'manual.pdf'") def about (self): tkMessageBox.showinfo("About","Editor for Pi Presents Profiles\n" +"For profile version: " + self.editor_issue + "\nAuthor: Ken Thompson" +"\nWebsite: http://pipresents.wordpress.com/") def validate_profile(self): val =Validator() val.validate_profile(self.root,self.pp_dir,self.pp_home_dir,self.pp_profile_dir,self.editor_issue,True) # ************** # OSC CONFIGURATION # ************** def create_osc(self): if self.pp_profile_dir=='': return if self.osc_config.read(self.osc_config_file) is False: iodir=self.pp_profile_dir+os.sep+'pp_io_config' if not os.path.exists(iodir): os.makedirs(iodir) self.osc_config.create(self.osc_config_file) def edit_osc(self): if self.osc_config.read(self.osc_config_file) is False: # print 'no config file' return osc_ut=OSCUnitType(self.root,self.osc_config.this_unit_type) self.req_unit_type=osc_ut.result if self.req_unit_type != None: # print self.req_unit_type eosc = OSCEditor(self.root, self.osc_config_file,self.req_unit_type,'Edit OSC Configuration') def delete_osc(self): if self.osc_config.read(self.osc_config_file) is False: return os.rename(self.osc_config_file,self.osc_config_file+'.bak') # ************** # PROFILES # ************** def open_existing_profile(self): initial_dir=self.pp_home_dir+os.sep+"pp_profiles"+self.pp_profiles_offset if os.path.exists(initial_dir) is False: self.mon.err(self,"Profiles directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home") return dir_path=tkFileDialog.askdirectory(initialdir=initial_dir) # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt" if len(dir_path)>0: self.open_profile(dir_path) def open_profile(self,dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err(self,"Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?") return self.pp_profile_dir = dir_path self.root.title("Editor for Pi Presents - "+ self.pp_profile_dir) if self.open_showlist(self.pp_profile_dir) is False: self.init() return self.open_medialists(self.pp_profile_dir) self.refresh_tracks_display() self.osc_config_file=self.pp_profile_dir+os.sep+'pp_io_config'+os.sep+'osc.cfg' def new_profile(self,profile): d = Edit1Dialog(self.root,"New Profile","Name", "") if d .result is None: return name=str(d.result) if name == "": tkMessageBox.showwarning("New Profile","Name is blank") return to = self.pp_home_dir + os.sep + "pp_profiles"+ self.pp_profiles_offset + os.sep + name if os.path.exists(to) is True: tkMessageBox.showwarning( "New Profile","Profile exists\n(%s)" % to ) return shutil.copytree(profile, to, symlinks=False, ignore=None) self.open_profile(to) def new_exhibit_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_exhibit_1p3' self.new_profile(profile) def new_interactive_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_interactive_1p3' self.new_profile(profile) def new_menu_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_menu_1p3' self.new_profile(profile) def new_presentation_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_presentation_1p3' self.new_profile(profile) def new_blank_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep +"ppt_blank_1p3" self.new_profile(profile) def new_mediashow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_mediashow_1p3' self.new_profile(profile) def new_liveshow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_liveshow_1p3' self.new_profile(profile) def new_artmediashow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artmediashow_1p3' self.new_profile(profile) def new_artliveshow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artliveshow_1p3' self.new_profile(profile) def new_radiobuttonshow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_radiobuttonshow_1p3' self.new_profile(profile) def new_hyperlinkshow_profile(self): profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_hyperlinkshow_1p3' self.new_profile(profile) # *************************************** # Shows # *************************************** def open_showlist(self,profile_dir): showlist_file = profile_dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err(self,"showlist file not found at " + profile_dir + "\n\nHint: Have you opened the profile directory?") self.app_exit() self.current_showlist=ShowList() self.current_showlist.open_json(showlist_file) if float(self.current_showlist.sissue())<float(self.editor_issue) or (self.command_options['forceupdate'] is True and float(self.current_showlist.sissue()) == float(self.editor_issue)): self.update_profile() self.mon.err(self,"Version of profile has been updated to "+self.editor_issue+", please re-open") return False if float(self.current_showlist.sissue())>float(self.editor_issue): self.mon.err(self,"Version of profile is greater than editor, must exit") self.app_exit() self.refresh_shows_display() return True def save_showlist(self,showlist_dir): if self.current_showlist is not None: showlist_file = showlist_dir + os.sep + "pp_showlist.json" self.current_showlist.save_list(showlist_file) def add_mediashow(self): self.add_show(PPdefinitions.new_shows['mediashow']) def add_liveshow(self): self.add_show(PPdefinitions.new_shows['liveshow']) def add_radiobuttonshow(self): self.add_show(PPdefinitions.new_shows['radiobuttonshow']) def add_hyperlinkshow(self): self.add_show(PPdefinitions.new_shows['hyperlinkshow']) def add_artliveshow(self): self.add_show(PPdefinitions.new_shows['artliveshow']) def add_artmediashow(self): self.add_show(PPdefinitions.new_shows['artmediashow']) def add_menushow(self): self.add_show(PPdefinitions.new_shows['menu']) def add_start(self): self.add_show(PPdefinitions.new_shows['start']) def add_show(self,default): # append it to the showlist and then add the medialist if self.current_showlist is not None: d = Edit1Dialog(self.root,"AddShow","Show Reference", "") if d.result is None: return name=str(d.result) if name == "": tkMessageBox.showwarning("Add Show","Name is blank") return if self.current_showlist.index_of_show(name) != -1: tkMessageBox.showwarning("Add Show","A Show with this name already exists") return copied_show=self.current_showlist.copy(default,name) mediafile=self.add_medialist(name) if mediafile != '': copied_show['medialist']=mediafile self.current_showlist.append(copied_show) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def remove_show(self): if self.current_showlist is not None and self.current_showlist.length()>0 and self.current_showlist.show_is_selected(): if tkMessageBox.askokcancel("Delete Show","Delete Show"): index= self.current_showlist.selected_show_index() self.current_showlist.remove(index) self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() def show_refs(self): _show_refs=[] for index in range(self.current_showlist.length()): if self.current_showlist.show(index)['show-ref'] != "start": _show_refs.append(copy.deepcopy(self.current_showlist.show(index)['show-ref'])) return _show_refs def refresh_shows_display(self): self.shows_display.delete(0,self.shows_display.size()) for index in range(self.current_showlist.length()): self.shows_display.insert(END, self.current_showlist.show(index)['title']+" ["+self.current_showlist.show(index)['show-ref']+"]") if self.current_showlist.show_is_selected(): self.shows_display.itemconfig(self.current_showlist.selected_show_index(),fg='red') self.shows_display.see(self.current_showlist.selected_show_index()) def e_select_show(self,event): if self.current_showlist is not None and self.current_showlist.length()>0: mouse_item_index=int(event.widget.curselection()[0]) self.current_showlist.select(mouse_item_index) self.refresh_shows_display() def copy_show(self): if self.current_showlist is not None and self.current_showlist.show_is_selected(): self.add_show(self.current_showlist.selected_show()) def m_edit_show(self): self.edit_show(PPdefinitions.show_types,PPdefinitions.show_field_specs) def edit_show(self,show_types,field_specs): if self.current_showlist is not None and self.current_showlist.show_is_selected(): d=EditItem(self.root,"Edit Show",self.current_showlist.selected_show(),show_types,field_specs,self.show_refs(), self.initial_media_dir,self.pp_home_dir,'show') if d.result is True: self.save_showlist(self.pp_profile_dir) self.refresh_shows_display() # *************************************** # Medialists # *************************************** def open_medialists(self,profile_dir): self.medialists = [] for this_file in os.listdir(profile_dir): if this_file.endswith(".json") and this_file not in ('pp_showlist.json','schedule.json'): self.medialists = self.medialists + [this_file] self.medialists_display.delete(0,self.medialists_display.size()) for index in range (len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) self.current_medialists_index=-1 self.current_medialist=None def add_medialist(self,name=None): if name is None: d = Edit1Dialog(self.root,"Add Medialist","File", "") if d.result is None: return '' name=str(d.result) if name == "": tkMessageBox.showwarning("Add medialist","Name is blank") return '' if not name.endswith(".json"): name=name+(".json") path = self.pp_profile_dir + os.sep + name if os.path.exists(path) is True: tkMessageBox.showwarning("Add medialist","Medialist file exists\n(%s)" % path) return '' nfile = open(path,'wb') nfile.write("{") nfile.write("\"issue\": \""+self.editor_issue+"\",\n") nfile.write("\"tracks\": [") nfile.write("]") nfile.write("}") nfile.close() # append it to the list self.medialists.append(copy.deepcopy(name)) # add title to medialists display self.medialists_display.insert(END, name) # and set it as the selected medialist self.refresh_medialists_display() return name def copy_medialist(self,to_file=None): if self.current_medialist is not None: #from_file= self.current_medialist from_file= self.medialists[self.current_medialists_index] if to_file is None: d = Edit1Dialog(self.root,"Copy Medialist","File", "") if d.result is None: return '' to_file=str(d.result) if to_file == "": tkMessageBox.showwarning("Copy medialist","Name is blank") return '' success_file = self.copy_medialist_file(from_file,to_file) if success_file =='': return '' # append it to the list self.medialists.append(copy.deepcopy(success_file)) # add title to medialists display self.medialists_display.insert(END, success_file) # and reset selected medialist self.current_medialist=None self.refresh_medialists_display() self.refresh_tracks_display() return success_file else: return '' def copy_medialist_file(self,from_file,to_file): if not to_file.endswith(".json"): to_file+=(".json") to_path = self.pp_profile_dir + os.sep + to_file if os.path.exists(to_path) is True: tkMessageBox.showwarning("Copy medialist","Medialist file exists\n(%s)" % to_path) return '' from_path= self.pp_profile_dir + os.sep + from_file if os.path.exists(from_path) is False: tkMessageBox.showwarning("Copy medialist","Medialist file not found\n(%s)" % from_path) return '' shutil.copy(from_path,to_path) return to_file def remove_medialist(self): if self.current_medialist is not None: if tkMessageBox.askokcancel("Delete Medialist","Delete Medialist"): os.remove(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index]) self.open_medialists(self.pp_profile_dir) self.refresh_medialists_display() self.refresh_tracks_display() def select_medialist(self,event): """ user clicks on a medialst in a profile so try and select it. """ # needs forgiving int for possible tkinter upgrade if len(self.medialists)>0: self.current_medialists_index=int(event.widget.curselection()[0]) self.current_medialist=MediaList('ordered') if not self.current_medialist.open_list(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index],self.current_showlist.sissue()): self.mon.err(self,"medialist is a different version to showlist: "+ self.medialists[self.current_medialists_index]) self.app_exit() self.refresh_tracks_display() self.refresh_medialists_display() def refresh_medialists_display(self): self.medialists_display.delete(0,len(self.medialists)) for index in range (len(self.medialists)): self.medialists_display.insert(END, self.medialists[index]) if self.current_medialist is not None: self.medialists_display.itemconfig(self.current_medialists_index,fg='red') self.medialists_display.see(self.current_medialists_index) def save_medialist(self): basefile=self.medialists[self.current_medialists_index] # print type(basefile) # basefile=str(basefile) # print type(basefile) medialist_file = self.pp_profile_dir+ os.sep + basefile self.current_medialist.save_list(medialist_file) # *************************************** # Tracks # *************************************** def refresh_tracks_display(self): self.tracks_display.delete(0,self.tracks_display.size()) if self.current_medialist is not None: for index in range(self.current_medialist.length()): if self.current_medialist.track(index)['track-ref'] != '': track_ref_string=" ["+self.current_medialist.track(index)['track-ref']+"]" else: track_ref_string="" self.tracks_display.insert(END, self.current_medialist.track(index)['title']+track_ref_string) if self.current_medialist.track_is_selected(): self.tracks_display.itemconfig(self.current_medialist.selected_track_index(),fg='red') self.tracks_display.see(self.current_medialist.selected_track_index()) def e_select_track(self,event): if self.current_medialist is not None and self.current_medialist.length()>0: mouse_item_index=int(event.widget.curselection()[0]) self.current_medialist.select(mouse_item_index) self.refresh_tracks_display() def m_edit_track(self): self.edit_track(PPdefinitions.track_types,PPdefinitions.track_field_specs) def edit_track(self,track_types,field_specs): if self.current_medialist is not None and self.current_medialist.track_is_selected(): d=EditItem(self.root,"Edit Track",self.current_medialist.selected_track(),track_types,field_specs, self.show_refs(),self.initial_media_dir,self.pp_home_dir,'track') if d.result is True: self.save_medialist() self.refresh_tracks_display() def move_track_up(self): if self.current_medialist is not None and self.current_medialist.track_is_selected(): self.current_medialist.move_up() self.refresh_tracks_display() self.save_medialist() def move_track_down(self): if self.current_medialist is not None and self.current_medialist.track_is_selected(): self.current_medialist.move_down() self.refresh_tracks_display() self.save_medialist() def new_track(self,fields,values): if self.current_medialist is not None: # print '\nfields ', fields # print '\nvalues ', values new_track=copy.deepcopy(fields) # print ',\new track ',new_track self.current_medialist.append(new_track) # print '\nbefore values ',self.current_medialist.print_list() if values is not None: self.current_medialist.update(self.current_medialist.length()-1,values) self.current_medialist.select(self.current_medialist.length()-1) self.refresh_tracks_display() self.save_medialist() def new_message_track(self): self.new_track(PPdefinitions.new_tracks['message'],None) def new_video_track(self): self.new_track(PPdefinitions.new_tracks['video'],None) def new_audio_track(self): self.new_track(PPdefinitions.new_tracks['audio'],None) def new_web_track(self): self.new_track(PPdefinitions.new_tracks['web'],None) def new_image_track(self): self.new_track(PPdefinitions.new_tracks['image'],None) def new_show_track(self): self.new_track(PPdefinitions.new_tracks['show'],None) def new_menu_track(self): self.new_track(PPdefinitions.new_tracks['menu'],None) def remove_track(self): if self.current_medialist is not None and self.current_medialist.length()>0 and self.current_medialist.track_is_selected(): if tkMessageBox.askokcancel("Delete Track","Delete Track"): index= self.current_medialist.selected_track_index() self.current_medialist.remove(index) self.save_medialist() self.refresh_tracks_display() def add_track_from_file(self): if self.current_medialist is None: return # print "initial directory ", self.options.initial_media_dir files_path=tkFileDialog.askopenfilename(initialdir=self.options.initial_media_dir, multiple=True) # fix for tkinter bug files_path = self.root.tk.splitlist(files_path) for file_path in files_path: file_path=os.path.normpath(file_path) # print "file path ", file_path self.add_track(file_path) self.save_medialist() def add_tracks_from_dir(self): if self.current_medialist is None: return image_specs =[PPdefinitions.IMAGE_FILES,PPdefinitions.VIDEO_FILES,PPdefinitions.AUDIO_FILES, PPdefinitions.WEB_FILES,('All files', '*')] # last one is ignored in finding files in directory, for dialog box only directory=tkFileDialog.askdirectory(initialdir=self.options.initial_media_dir) # deal with tuple returned on Cancel if len(directory) == 0: return # make list of exts we recognise exts = [] for image_spec in image_specs[:-1]: image_list=image_spec[1:] for ext in image_list: exts.append(copy.deepcopy(ext)) for this_file in os.listdir(directory): (root_file,ext_file)= os.path.splitext(this_file) if ext_file.lower() in exts: file_path=directory+os.sep+this_file # print "file path before ", file_path file_path=os.path.normpath(file_path) # print "file path after ", file_path self.add_track(file_path) self.save_medialist() def add_track(self,afile): relpath = os.path.relpath(afile,self.pp_home_dir) # print "relative path ",relpath common = os.path.commonprefix([afile,self.pp_home_dir]) # print "common ",common if common.endswith("pp_home") is False: location = afile else: location = "+" + os.sep + relpath location = string.replace(location,'\\','/') # print "location ",location (root,title)=os.path.split(afile) (root,ext)= os.path.splitext(afile) if ext.lower() in PPdefinitions.IMAGE_FILES: self.new_track(PPdefinitions.new_tracks['image'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.VIDEO_FILES: self.new_track(PPdefinitions.new_tracks['video'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.AUDIO_FILES: self.new_track(PPdefinitions.new_tracks['audio'],{'title':title,'track-ref':'','location':location}) elif ext.lower() in PPdefinitions.WEB_FILES: self.new_track(PPdefinitions.new_tracks['web'],{'title':title,'track-ref':'','location':location}) else: self.mon.err(self,afile + " - cannot determine track type, use menu track>new") # ********************************************* # UPDATE PROFILE # ********************************************** def update_all(self): self.init() for profile_file in os.listdir(self.pp_home_dir+os.sep+'pp_profiles'+self.pp_profiles_offset): # self.mon.log (self,"Updating "+profile_file) self.pp_profile_dir = self.pp_home_dir+os.sep+'pp_profiles'+self.pp_profiles_offset + os.sep + profile_file if not os.path.exists(self.pp_profile_dir+os.sep+"pp_showlist.json"): tkMessageBox.showwarning("Pi Presents","Not a profile, skipping "+self.pp_profile_dir) else: self.current_showlist=ShowList() self.current_showlist.open_json(self.pp_profile_dir+os.sep+"pp_showlist.json") self.mon.log (self,"Version of profile "+ profile_file + ' is ' + self.current_showlist.sissue()) if float(self.current_showlist.sissue())<float(self.editor_issue): self.mon.log(self,"Version of profile "+profile_file+ " is being updated to "+self.editor_issue) self.update_profile() elif (self.command_options['forceupdate'] is True and float(self.current_showlist.sissue()) == float(self.editor_issue)): self.mon.log(self, "Forced updating of " + profile_file + ' to '+self.editor_issue) self.update_profile() elif float(self.current_showlist.sissue())>float(self.editor_issue): tkMessageBox.showwarning("Pi Presents", "Version of profile " +profile_file+ " is greater than editor, skipping") else: self.mon.log(self," Skipping Profile " + profile_file + " It is already up to date ") self.init() tkMessageBox.showwarning("Pi Presents","All profiles updated") def update_profile(self): self.update_medialists() # medialists and their tracks self.update_shows() #shows in showlist, also creates menu tracks for 1.2>1.3 def update_shows(self): # open showlist into a list of dictionaries self.mon.log (self,"Updating show ") ifile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", 'rb') shows = json.load(ifile)['shows'] ifile.close() # special 1.2>1.3 create menu medialists with menu track from show #go through shows - if type = menu and version is greater copy its medialist to a new medialist with name = <show-ref>-menu1p3.json for show in shows: #create a new medialist medialist != show-ref as menus can't now share medialists if show['type']=='menu' and float(self.current_showlist.sissue())<float(self.editor_issue): to_file=show['show-ref']+'-menu1p3.json' from_file = show['medialist'] if to_file != from_file: self.copy_medialist_file(from_file,to_file) else: self.mon.warn(self, 'medialist file' + to_file + ' already exists, must exit with incomplete update') return False #update the reference to the medialist show['medialist']=to_file #delete show fields so they are recreated with new default content del show['controls'] # open the medialist and add the menu track then populate some of its fields from the show ifile = open(self.pp_profile_dir + os.sep + to_file, 'rb') tracks = json.load(ifile)['tracks'] ifile.close() new_track=copy.deepcopy(PPdefinitions.new_tracks['menu']) tracks.append(copy.deepcopy(new_track)) # copy menu parameters from menu show to menu track and init values of some self.transfer_show_params(show,tracks,'menu-track',("entry-colour","entry-font", "entry-select-colour", "hint-colour", "hint-font", "hint-text", "hint-x","hint-y", "menu-bullet", "menu-columns", "menu-direction", "menu-guidelines", "menu-horizontal-padding", "menu-horizontal-separation", "menu-icon-height", "menu-icon-mode", "menu-icon-width", "menu-rows", "menu-strip", "menu-strip-padding", "menu-text-height", "menu-text-mode", "menu-text-width", "menu-vertical-padding", "menu-vertical-separation", "menu-window")) # and save the medialist dic={'issue':self.editor_issue,'tracks':tracks} ofile = open(self.pp_profile_dir + os.sep + to_file, "wb") json.dump(dic,ofile,sort_keys=True,indent=1) # end for show in shows #update the fields in all shows replacement_shows=self.update_shows_in_showlist(shows) dic={'issue':self.editor_issue,'shows':replacement_shows} ofile = open(self.pp_profile_dir + os.sep + "pp_showlist.json", "wb") json.dump(dic,ofile,sort_keys=True,indent=1) return True def transfer_show_params(self,show,tracks,track_ref,fields): # find the menu track in medialist for index,track in enumerate(tracks): if track['track-ref']== 'menu-track': break #update some fields with new default content tracks[index]['links']=PPdefinitions.new_tracks['menu']['links'] #transfer values from show to track for field in fields: tracks[index][field]=show[field] # print show[field], tracks[index][field] pass def update_medialists(self): # UPDATE MEDIALISTS AND THEIR TRACKS for this_file in os.listdir(self.pp_profile_dir): if this_file.endswith(".json") and this_file not in ('pp_showlist.json','schedule.json'): self.mon.log (self,"Updating medialist " + this_file) # open a medialist and update its tracks ifile = open(self.pp_profile_dir + os.sep + this_file, 'rb') tracks = json.load(ifile)['tracks'] ifile.close() replacement_tracks=self.update_tracks(tracks) dic={'issue':self.editor_issue,'tracks':replacement_tracks} ofile = open(self.pp_profile_dir + os.sep + this_file, "wb") json.dump(dic,ofile,sort_keys=True,indent=1) def update_tracks(self,old_tracks): # get correct spec from type of field replacement_tracks=[] for old_track in old_tracks: # print '\nold track ',old_track track_type=old_track['type'] #update if new tracks has the track type otherwise skip if track_type in PPdefinitions.new_tracks: spec_fields=PPdefinitions.new_tracks[track_type] left_overs=dict() # go through track and delete fields not in spec for key in old_track.keys(): if key in spec_fields: left_overs[key]=old_track[key] # print '\n leftovers',left_overs replacement_track=copy.deepcopy(PPdefinitions.new_tracks[track_type]) # print '\n before update', replacement_track replacement_track.update(left_overs) # print '\nafter update',replacement_track replacement_tracks.append(copy.deepcopy(replacement_track)) return replacement_tracks def update_shows_in_showlist(self,old_shows): # get correct spec from type of field replacement_shows=[] for old_show in old_shows: show_type=old_show['type'] ## menu to menushow spec_fields=PPdefinitions.new_shows[show_type] left_overs=dict() # go through track and delete fields not in spec for key in old_show.keys(): if key in spec_fields: left_overs[key]=old_show[key] # print '\n leftovers',left_overs replacement_show=copy.deepcopy(PPdefinitions.new_shows[show_type]) replacement_show.update(left_overs) replacement_shows.append(copy.deepcopy(replacement_show)) return replacement_shows
noveltyButton = Button(framenovelty, text = "Use Novelty", command = novelty_func) noveltyButton.grid(row=4, column = 0) evolveButton = Button(frame, text = "Evolve population", command = evolve_pop) evolveButton.grid(row = 5, column = 0) menu = Menu(root) filemenu = Menu(menu) menu.add_cascade(label="File", menu = filemenu) filemenu.add_command(label = "Export Song", command = export) viewmenu = Menu(menu) menu.add_cascade(label = "View", menu = viewmenu) viewmenu.add_command(label = "Print all", command = print_all) root.config(menu = menu) yscroll = Scrollbar(framelistbox, relief = 'raised') yscroll.grid(row=0, column=1) listbox = Listbox(framelistbox, yscrollcommand = yscroll.set, width = 40, height = 8) for song in song_list: listbox.insert(END, "Song: %d.%d" %(GEN_NUM, song.song_id) + " Fitness:" + str( song.fitness) + " Novelty:" + str(song.novelty_score)) listbox.grid(row = 0, column = 0) yscroll.config(command = listbox.yview) listbox.bind('<<ListboxSelect>>', song_clicked) fitnesslabel = Label(frame, text = "Fitness Functions") fitnesslabel.grid(row = 0, column = 0)
from Tkinter import Tk import sys print(sys.executable) print(sys.version) def doNothing(): print("ok ok I won't...") root = Tk() menu = Menu(root) root.config(menu=menu) subMenu = Menu(menu) menu.add_cascade(label="file", menu=subMenu) subMenu.add_command(label="Now Project...", command=doNothing) subMenu.add_command(label="Now...", command=doNothing) subMenu.add_seperator() subMenu.add_command(label="Exit", command=doNothing) editMenu = Menu(menu) menu.add_cascade(label="Edit", menu=subMenu) editMenu.add_command(label="Redo", command=doNothing) root.mainloop()
class TkApplicationWindow(AbstractApplicationWindow): def __init__(self, app): self.root = Tk() self.root.title("Llia") self.root.config(background=factory.bg()) super(TkApplicationWindow, self).__init__(app, self.root) self.root.withdraw() if app.config["enable-splash"]: splash = TkSplashWindow(self.root, app) self.root.deiconify() self.root.protocol("WM_DELETE_WINDOW", self.exit_app) self.llia_graph = None self._main = layout.BorderFrame(self.root) self._main.config(background=factory.bg()) self._main.pack(anchor="nw", expand=True, fill=BOTH) self._init_status_panel() self._init_menu() self._init_center_frame(self._main.center) self.root.minsize(width=665, height=375) self.group_windows = [] self.add_synth_group() # def _init_status_panel(self): # south = self._main.south # south.configure(padx=4, pady=4) # self._lab_status = factory.label(south, "", modal=False) # b_panic = factory.panic_button(south) # ttip = "Clear status line" # b_clear_status = factory.clear_button(south,command=self.clear_status,ttip=ttip) # b_panic.grid(row=0, column=0, sticky="w") # b_clear_status.grid(row=0, column=1, sticky="w") # self._lab_status.grid(row=0,column=2, sticky="w", padx=8) # south.config(background=factory.bg()) def _init_status_panel(self): south = self._main.south south.configure(padx=4, pady=4) self._lab_status = factory.label(south, "", modal=False) b_panic = factory.panic_button(south) b_down = factory.button(south, "-") b_up = factory.button(south, "+") b_panic.grid(row=0, column=0) # b_down.grid(row=0,column=1) # b_up.grid(row=0,column=2) self._lab_status.grid(row=0, column=3, sticky='w') south.config(background=factory.bg()) b_down.configure(command=lambda: self.root.lower()) b_up.configure(command=lambda: self.root.lift()) # b_clear_status = factory.clear_button(south,command=self.clear_status,ttip=ttip) # b_panic.grid(row=0, column=0, sticky="w") # b_clear_status.grid(row=0, column=1, sticky="w") # self._lab_status.grid(row=0,column=2, sticky="w", padx=8) # south.config(background=factory.bg()) def _tab_change_callback(self, event): self.llia_graph.sync() def _init_center_frame(self, master): nb = ttk.Notebook(master) nb.pack(expand=True, fill="both") frame_synths = layout.FlowGrid(nb, 6) frame_efx = layout.FlowGrid(nb, 6) frame_controllers = layout.FlowGrid(nb, 6) self.llia_graph = LliaGraph(nb, self.app) nb.add(frame_synths, text="Synths") nb.add(frame_efx, text="Effects") nb.add(frame_controllers, text="Controllers") nb.add(self.llia_graph, text="Graph") nb.bind("<Button-1>", self._tab_change_callback) def display_info_callback(event): sp = event.widget.synth_spec msg = "%s: %s" % (sp["format"], sp["description"]) self.status(msg) def clear_info_callback(*_): self.status("") for st in con.SYNTH_TYPES: sp = specs[st] ttp = "Add %s Synthesizer (%s)" % (st, sp["description"]) b = factory.logo_button(frame_synths, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_synth_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_synths.add(b) for st in con.EFFECT_TYPES: sp = specs[st] ttp = "Add %s Effect (%s)" % (st, sp["description"]) b = factory.logo_button(frame_efx, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_efx_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_efx.add(b) for st in con.CONTROLLER_SYNTH_TYPES: sp = specs[st] ttp = "Add %s Effect (%s)" % (st, sp["description"]) b = factory.logo_button(frame_controllers, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_controller_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_controllers.add(b) @staticmethod def menu(master): m = Menu(master, tearoff=0) m.config(background=factory.bg(), foreground=factory.fg()) return m def _init_menu(self): main_menu = self.menu(self.root) self.root.config(menu=main_menu) file_menu = self.menu(main_menu) osc_menu = self.menu(main_menu) midi_menu = self.menu(main_menu) bus_menu = self.menu(main_menu) #buffer_menu = self.menu(main_menu) tune_menu = self.menu(main_menu) help_menu = self.menu(main_menu) main_menu.add_cascade(label="File", menu=file_menu) main_menu.add_cascade(label="OSC", menu=osc_menu) main_menu.add_cascade(label="MIDI", menu=midi_menu) main_menu.add_cascade(label="Buses", menu=bus_menu) #main_menu.add_cascade(label="Buffers", menu=buffer_menu) main_menu.add_cascade(label="Tune", menu=tune_menu) main_menu.add_cascade(label="Help", menu=help_menu) self._init_file_menu(file_menu) self._init_osc_menu(osc_menu) self._init_midi_menu(midi_menu) self._init_bus_menu(bus_menu) #self._init_buffer_menu(buffer_menu) self._init_tune_menu(tune_menu) self._init_help_menu(help_menu) def _init_file_menu(self, fmenu): fmenu.add_command(label="Lliascript", command=self.show_history_editor) fmenu.add_separator() fmenu.add_command(label="New Synth Group", command=self._add_synth_group) fmenu.add_separator() fmenu.add_command(label="Quit", command=self.exit_app) def _init_osc_menu(self, iomenu): iomenu.add_command(label="Ping", command=self.ping_global) iomenu.add_command(label="Dump", command=self.app.proxy.dump) iomenu.add_command(label="Toggle OSC Trace", command=self.toggle_osc_trace) def _init_midi_menu(self, mmenu): map_menu = self.menu(mmenu) mmenu.add_command(label="Channel Names", command=self.show_channel_name_dialog) mmenu.add_command(label="Controller Names", command=self.show_controller_name_dialog) mmenu.add_cascade(label="MIDI Maps", menu=map_menu) mmenu.add_command(label="Toggle MIDI Input Trace", command=self.toggle_midi_input_trace) mmenu.add_command(label="Toggle MIDI Output Trace", command=self.toggle_midi_output_trace) mmenu.add_command(label="Toggle Program Pretty Printer", command=self.toggle_program_pretty_printer) def _init_bus_menu(self, bmenu): bmenu.add_command(label="Audio", command=self.show_audiobus_dialog) bmenu.add_command(label="Control", command=self.show_controlbus_dialog) # def _init_buffer_menu(self, bmenu): # bmenu.add_command(label="View Buffers", command=self.show_bufferlist_dialog) def _init_tune_menu(self, tmenu): tmenu.add_command(label="FIX ME: Nothing to see here") def _init_help_menu(self, hmenu): pass def exit_gui(self): try: self.root.destroy() except: pass def exit_app(self): # ISSUE: Check config and ask user confirmation before existing self.app.exit_() def as_widget(self): return self.root def status(self, msg): self._lab_status.config(text=str(msg)) def warning(self, msg): msg = "WARNING: %s" % msg self._lab_status.config(text=msg) def clear_status(self): self.status("") def start_gui_loop(self): self.root.mainloop() def show_about_dialog(self): from llia.gui.tk.tk_about_dialog import TkAboutDialog dialog = TkAboutDialog(self.root, self.app) self.root.wait_window(dialog) def display_help(self, topic=None): pass def show_history_editor(self): from llia.gui.tk.tk_history import TkHistoryEditor dialog = TkHistoryEditor(self.root, self.app) self.root.wait_window(dialog) def ping_global(self): try: rs = self.app.proxy.ping() if rs: self.status("Ping OK") else: self.warning("Ping Error") except LliaPingError as err: self.warning(err.message) def toggle_osc_trace(self): LliaProxy.trace = not LliaProxy.trace if LliaProxy.trace: self.status("OSC transmission trace enabled") else: self.status("OSC transmission trace disabled") def show_channel_name_dialog(self): from llia.gui.tk.tk_channel_name_editor import TkChannelNameEditor dialog = TkChannelNameEditor(self.root, self.app) self.root.wait_window(dialog) def show_controller_name_dialog(self): from llia.gui.tk.tk_controller_name_editor import TkControllerNameEditor dialog = TkControllerNameEditor(self.root, self.app) self.root.wait_window(dialog) def toggle_midi_input_trace(self): flag = not self.app.midi_in_trace self.app.midi_in_trace = flag self.app.midi_receiver.enable_trace(flag) if flag: self.status("MIDI input trace enabled") else: self.status("MIDI output trace disabled") def toggle_midi_output_trace(self): self.status("MIDI output not available") # FIX ME def toggle_program_pretty_printer(self): self.app.pp_enabled = not self.app.pp_enabled if self.app.pp_enabled: self.status("Pretty printer enabled") else: self.status("Pretty printer disabled") def show_audiobus_dialog(self): from llia.gui.tk.tk_audiobus_editor import TkAudiobusEditor dialog = TkAudiobusEditor(self.root, self.app) self.root.wait_window(dialog) def show_controlbus_dialog(self): from llia.gui.tk.tk_controlbus_editor import TkControlbusEditor dialog = TkControlbusEditor(self.root, self.app) self.root.wait_window(dialog) # def show_bufferlist_dialog(self): # from llia.gui.tk.tk_buffer_info import TkBufferListDialog # dialog = TkBufferListDialog(self.root, self.app) # self.root.wait_window(dialog) def _show_add_synth_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, False) self.root.wait_window(dialog) def _show_add_efx_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=True, is_controller=False) self.root.wait_window(dialog) def _show_add_controller_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=False, is_controller=True) self.root.wait_window(dialog) def _add_synth_group(self): sh = self.app.ls_parser.synthhelper sh.new_group() def add_synth_group(self, name=None): gw = GroupWindow(self.app, self.root, name) gw.transient(self.root) self.group_windows.append(gw) self.status("Added new Synth Group Window") return gw def display_synth_editor(self, sid): try: swin = self[sid] grpid = swin.group_index grp = self.group_windows[grpid] #grp.deiconify() grp.show_synth_editor(sid) except (KeyError, IndexError): msg = "Can not find editor for %s" % sid self.warning(msg)
height=canvas_height) self.canvas.itemconfigure("inner_frame", width=window_width, height=window_height) if __name__ == '__main__': try: from Tkinter import Tk, Label except ImportError: from tkinter import Tk, Label root = Tk() root.title('TEST1') root.config(width=600, height=300) scrolling_area = Scrolling_Area(root) scrolling_area.config(width=100, height=60) scrolling_area.place(x=20, y=40) # scrolling_area.canvas.config(scrollregion=(0, 0, 8*20, 20*20)) # scrolling_area.pack(expand=1, fill=BOTH) pixel = tk.PhotoImage(master=root, name='test_photo', width=1, height=1) colors = ['#00FF00', '#FF0000'] for i in range(0, 20): rowFrame = Frame(scrolling_area.innerframe) rowFrame.pack() # rowFrame.config(width=20*20, height=20) # rowFrame.place(x=0, y=i*20)
class PraiseTexGUI(object): """Graphical interface for selecting songs and compiling them""" def __init__(self, songdir="songs"): # data self.songs = [] self.praisetex = PraiseTex(songdir) self.root = Tk() button_width = 6 button_padx = "2m" button_pady = "1m" frame_padx = "3m" frame_pady = "2m" label_padx = "3m" label_pady = "2m" listbox_width = 30 listbox_height = 20 frame_title_font = ("TkDefaultFont", 14) text_font = ("TkDefaultFont", 12) menu_font = ("TkDefaultFont", 12) button_font = ("TkDefaultFont", 12) # window properties self.root.title("praisetex") self.root.option_add("*Font", ("TkDefaultFont", 12)) # menu menubar = Menu(self.root) menubar.tk.call('tk', 'scaling', 2.5) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Open Directory", command=self.openDirectory) filemenu.add_command(label="Exit", command=self.root.quit) menubar.add_cascade(label="File", menu=filemenu) self.root.config(menu=menubar) # left section self.availableSongsTitle = Label(self.root, text="Available Songs", font=frame_title_font, padx=label_padx, pady=label_pady) self.availableSongsTitle.grid(row=0, column=0) self.availableSongsFrame = Frame(self.root) self.availableSongsFrame.grid(row=1, column=0, padx=frame_padx, pady=frame_pady) self.availableSongsScroll = Scrollbar(self.availableSongsFrame, orient=VERTICAL) self.availableSongs = Listbox(self.availableSongsFrame, width=listbox_width, height=listbox_height, selectmode=EXTENDED, yscrollcommand=self.availableSongsScroll.set, exportselection=0) self.availableSongsScroll.config(command=self.availableSongs.yview) self.availableSongsScroll.pack(side=RIGHT, fill=Y) self.availableSongs.pack() self.button = Button(self.root, text="Refresh", command=self.refreshSongList) self.button.grid(row=2, column=0) # middle section self.addRemoveButtonFrame = Frame(self.root) self.addRemoveButtonFrame.grid(row=1, column=1) self.addSongButton = Button(self.addRemoveButtonFrame, text="Add", command=self.addSong) self.addSongButton.pack(side=TOP, padx=button_padx, pady=button_pady) self.removeSongButton = Button(self.addRemoveButtonFrame, text="Remove", command=self.removeSong) self.removeSongButton.pack(side=BOTTOM) # right section self.songsToCompileTitle = Label(self.root, text="Songs to Compile", font=frame_title_font, padx=label_padx, pady=label_pady) self.songsToCompileTitle.grid(row=0, column=2) self.songsToCompileFrame = Frame(self.root) self.songsToCompileFrame.grid(row=1, column=2, padx=frame_padx, pady=frame_pady) self.songsToCompileScroll = Scrollbar(self.songsToCompileFrame, orient=VERTICAL) self.songsToCompile = Listbox(self.songsToCompileFrame, width=listbox_width, height=listbox_height, selectmode=EXTENDED, yscrollcommand=self.songsToCompileScroll.set, exportselection=0, font=text_font) self.songsToCompileScroll.config(command=self.songsToCompile.yview) self.songsToCompileScroll.pack(side=RIGHT, fill=Y) self.songsToCompile.pack() self.compileButtonFrame = Frame(self.root) self.compileButtonFrame.grid(row=2, column=2) self.chordsButton = Button(self.compileButtonFrame, text="Chords", command=self.compileChords) self.chordsButton.pack(side=LEFT, padx=button_padx, pady=button_pady) self.slidesButton = Button(self.compileButtonFrame, text="Slides", command=self.compileSlides) self.slidesButton.pack(side=RIGHT, padx=button_padx, pady=button_pady) # status bar self.status = Label(self.root, text="Ready", padx="1m") self.status.grid(row=3, column=0, columnspan=3, sticky=W) self.refreshSongList() def run(self): """Start event loop of GUI""" self.root.mainloop() def refreshSongList(self): """Sync up the filenames in songlist with files in directory""" # clear song list self.availableSongs.delete(0, END) # add song files self.songs = self.praisetex.refreshSongList() for song in self.songs: self.availableSongs.insert(END, song) self.updateStatus("{0} songs found in directory {1}".format(len(self.songs), self.praisetex.getSongDirectory())) def openDirectory(self): """Selects directory for songs""" dirname = filedialog.askdirectory(parent=self.root, initialdir=self.praisetex.getSongDirectory(), title='Please select a directory') if len(dirname) > 0: self.praisetex.setSongDirectory(dirname) self.updateStatus("Song directory set to {0}".format(dirname)) def addSong(self): """Add song to compile list""" selectedSongs = self.availableSongs.curselection() # get index of where to insert selected songs insertIndex = self.songsToCompile.curselection() if len(insertIndex) > 0: insertIndex = int(insertIndex[0]) # convert to integer else: insertIndex = -1 # song should be appended if len(selectedSongs) == 0: # do nothing pass elif len(selectedSongs) == 1: # insert the one song song = selectedSongs[0] songtitle = self.availableSongs.get(song) if insertIndex == -1: end = len(self.praisetex.compile) self.praisetex.addSong(end, songtitle) self.songsToCompile.insert(END, songtitle) else: self.praisetex.addSong(insertIndex+1, songtitle) self.songsToCompile.insert(insertIndex+1, songtitle) else: # more than one song songList = [self.availableSongs.get(song) for song in selectedSongs] if insertIndex != -1: songList.reverse() for songtitle in songList: self.praisetex.addSong(insertIndex+1, songtitle) self.songsToCompile.insert(insertIndex+1, songtitle) else: # add songs to the end for songtitle in songList: end = len(self.praisetex.compile) self.praisetex.addSong(end, songtitle) self.songsToCompile.insert(END, songtitle) self.updateStatus("{0} songs added".format(len(selectedSongs))) def removeSong(self): """Remove song from compile list""" songindexes = list(self.songsToCompile.curselection()) songindexes.reverse() for index in songindexes: self.praisetex.removeSong(index) self.songsToCompile.delete(index) self.updateStatus("{0} songs removed".format(len(songindexes))) def compileChords(self): """Compile a chord sheet from selected songs""" self.updateStatus("Compiling Songs") error = self.praisetex.compileChords() if error: self.updateStatus("pdflatex has failed") else: self.updateStatus("Compiled chords.pdf") def compileSlides(self): """Compile slides from selected songs""" self.updateStatus("Compiling Songs") error = self.praisetex.compileSlides() if error: self.updateStatus("pdflatex has failed") else: self.updateStatus("Compiled slides.pdf") def updateStatus(self, message): """Update the status bar""" self.status.config(text=message)
def _help(): win = Toplevel(root) lab = Label(win, text="Вам необходимо ввести колличество каналов в пакетах Социальный, Базовый и Полный.\nПосле этого открыть EXCEL файл с нужным сервичным планом и нажать на кнопку Преобразовать.\nРезультат будет преобразован в формат txt\nи появится на экране. Файл txt будет автоматически сохранен.") lab.pack() def _about(): win = Toplevel(root) lab = Label(win, text="Эта программа преобразовывает xls файл \n в txt формат специальной разметкой.") lab.pack() root = Tk() root.title('IPTV playlist creator') m = Menu(root) root.config(menu=m) fm = Menu(m) m.add_cascade(label="File", menu=fm) fm.add_command(label="Open", command = _open) fm.add_command(label="Save", command = _save) fm.add_command(label="Exit", command = _close) hm = Menu(m) m.add_cascade(label="Help", menu=hm) hm.add_command(label="Help", command = _help) hm.add_command(label="About", command = _about) fra1 = Frame(root, width=500, height=30, bd = 5) fra2 = Frame(root, width=500, height=100, bd = 5) fra3 = Frame(root, width=500, height=500, bd = 5)
class ClusterFK: """ The Tkinter UI, responsible for drawing the board and accepting user input. """ def __init__(self, rounds, filename, trail): self.root = Tk() self.menubar = Menu(self.root) self.filemenu = Menu(self.menubar, tearoff=0) self.filemenu.add_command(label="Save Trail", command=self.saveTrail) self.filemenu.add_command(label="Load Trail", command=self.loadTrail) self.filemenu.add_command(label="Export to Tex", command=self.exportToLatex) self.filemenu.add_command(label="Quit", command=self.root.quit) self.menubar.add_cascade(label="File", menu=self.filemenu) self.root.config(menu=self.menubar) self.trailUI = None if filename.endswith(".cfk"): self._loadTrailFromFile(open(filename, "rb")) elif filename.endswith(".trail"): self._initTrailUI(trail(rounds, filename=filename)) elif filename.endswith(".json"): self._loadTrailFromJson(open(filename, "rb")) else: print "File extensions not supported. Use .trail, .cfk or .json" raise IOError() # self.mantis.printTrail() self.root.geometry("{:d}x{:d}".format(1920, 1080)) self.root.mainloop() def _initTrailUI(self, trail): if self.trailUI is not None: self.trailUI.cleanup() self.trail = trail #self.trail.propagate() self.trailUI = TrailUI(self.root, self.trail) self.trailUI.redraw_all() self.trailUI.redrawColorList() def saveTrail(self): f = tkFileDialog.asksaveasfile(mode="w", defaultextension=".json") if f is None: # asksaveasfile return `None` if dialog closed with "cancel". return # pickle.dump(self.trail, f) json_trail = self.trail.toJSON() validate(json_trail, Utils.json_schema) json.dump(json_trail, f, sort_keys=True, indent=2) f.close() def _loadTrailFromJson(self, f): if f is None: return # load JSON data as string, not unicode string imported_trail = _byteify(json.load(f, object_hook=_byteify), ignore_dicts=True) validate(imported_trail, Utils.json_schema) f.close() trail = CIPHER_TRAILS[imported_trail["cipher"]]( imported_trail["rounds"], jsontrail=imported_trail) self._initTrailUI(trail) def _loadTrailFromFile(self, f): # for old exports if f is None: return trail = pickle.load(f) self._initTrailUI(trail) f.close() def loadTrail(self): f = tkFileDialog.askopenfile(mode="r", defaultextension=".json") if f is None: return if f.name.endswith(".cfk"): self._loadTrailFromFile(f) elif f.name.endswith(".json"): self._loadTrailFromJson(f) else: print "File extensions not supported. Use .trail, .cfk or .json" raise IOError() def exportToLatex(self): f = tkFileDialog.asksaveasfile(mode="w", defaultextension=".tex") if f is None: return self.trail.exportToLatex(f) f.close()
class App_Runner: """ App runner that uses a Board and a Palette. """ def __init__(self, on_init, app_name, dev_stage, file_extension, deserializers, board_width, board_height, palette_height, directed_wires, label_tooltips_enabled, same_label_per_connector, init_file=None): """ |on_init|: method called every time a new board of this app's type is created. |app_name|: name of this app. |dev_stage|: development stage of this app. |file_extension|: the file extension used for boards of this app's type. |deserializers|: drawabel types to open files of this app's type. |board_width|, |board_height|: board dimensions. |palette_height|: height of palette, width will be the same as board width. |directed_wires|: True if the board is to have directed wires, False otherwise. |label_tooltips_enabled|: if True, show wire and drawable label tooltips. |same_label_per_connector|: if True, all wires from a connector will have the same label. If False, this will only be true for wire connectors. |init_file|: file to open at init time. """ self._on_init = on_init self._app_name = app_name self._dev_stage = dev_stage self._file_extension = file_extension self._deserializers = deserializers self._board_width = board_width self._board_height = board_height self._palette_height = palette_height self._directed_wires = directed_wires self._label_tooltips_enabled = label_tooltips_enabled self._same_label_per_connector = same_label_per_connector self._init_file = init_file self._init() self._setup_menu() self._setup_shortcuts() def _switch_cursor_to_draw(self, *args): """ Switches board cursor state to 'draw'. """ self._draw_display.highlight() self._drag_display.unhighlight() self.board.set_cursor_state('draw') def _switch_cursor_to_drag(self, *args): """ Switches board cursor state to 'drag'. """ self._draw_display.unhighlight() self._drag_display.highlight() self.board.set_cursor_state('drag') def _toggle_cursor(self): """ Toggles board cursor state. """ if self.board.get_cursor_state() == 'draw': self._switch_cursor_to_drag() else: self._switch_cursor_to_draw() def _init(self): """ Creates the board and palette. """ self._file_name = None self._root = Tk() self._root.resizable(0, 0) self._menu = Menu(self._root, tearoff=0) self.board = Board(self._root, self._menu, width=self._board_width, height=self._board_height, directed_wires=self._directed_wires, label_tooltips_enabled=self._label_tooltips_enabled, same_label_per_connector=self._same_label_per_connector, on_changed=self._on_changed, on_exit=self._request_save) self._init_board() self.palette = Palette(self._root, self.board, width=self._board_width, height=self._palette_height) # buttons to change board cursor state self.palette.current_left_x -= PALETTE_PADDING self._draw_display = self.palette.add_drawable_type(Image_Run_Drawable, LEFT, self._switch_cursor_to_draw, image_file=PENCIL_IMAGE) self.palette.current_left_x -= PALETTE_PADDING self._drag_display = self.palette.add_drawable_type(Image_Run_Drawable, LEFT, self._switch_cursor_to_drag, image_file=HAND_IMAGE) self.palette.draw_separator() self._switch_cursor_to_draw() def _setup_menu(self): """ Creates the menu. """ file_menu = Menu(self._menu, tearoff=0) file_menu.add_command(label='New', command=self._new_file, accelerator='Ctrl+N') file_menu.add_command(label='Open', command=self._open_file, accelerator='Ctrl+O') file_menu.add_command(label='Save', command=self._save_file, accelerator='Ctrl+S') file_menu.add_command(label='Save as', command=self._save_as) file_menu.add_separator() file_menu.add_command(label='Quit', command=self.board.quit, accelerator='Ctrl+Q') self._menu.add_cascade(label='File', menu=file_menu) edit_menu = Menu(self._menu, tearoff=0) edit_menu.add_command(label='Undo', command=self.board.undo, accelerator='Ctrl+Z') edit_menu.add_command(label='Redo', command=self.board.redo, accelerator='Ctrl+Y') edit_menu.add_command(label='Delete selected', command=self.board._delete_selected_items, accelerator='Delete') edit_menu.add_command(label='Rotate selected', command=self.board._rotate_selected_item, accelerator='r') edit_menu.add_command(label='Toggle cursor', command=self._toggle_cursor, accelerator='D') self._menu.add_cascade(label='Edit', menu=edit_menu) self._root.config(menu=self._menu) def _setup_shortcuts(self): """ Adds basic shortcuts. """ self.board.parent.bind('<Control-n>', lambda event: self._new_file()) self.board.parent.bind('<Control-N>', lambda event: self._new_file()) self.board.parent.bind('<Control-o>', lambda event: self._open_file()) self.board.parent.bind('<Control-O>', lambda event: self._open_file()) self.board.parent.bind('<Control-q>', lambda event: self.board.quit()) self.board.parent.bind('<Control-Q>', lambda event: self.board.quit()) self.board.parent.bind('<Control-s>', lambda event: self._save_file()) self.board.parent.bind('<Control-S>', lambda event: self._save_file()) self.board.parent.bind('<Control-y>', lambda event: self.board.redo()) self.board.parent.bind('<Control-Y>', lambda event: self.board.redo()) self.board.parent.bind('<Control-z>', lambda event: self.board.undo()) self.board.parent.bind('<Control-Z>', lambda event: self.board.undo()) self.board.add_key_binding('d', self._toggle_cursor) def _init_board(self): """ (Re)Initializes the board based on this app's specific needs, as per self._on_init. """ self.board.clear() self._on_init(self.board) self.board.reset() def _on_changed(self, board_changed): """ Callback for when the board is changed. Updates the title of the app window to indicate whether we need to save the file. """ self._root.title('%s (%s) %s %s' % (self._app_name, self._dev_stage, strip_file_name(self._file_name), '*' if board_changed else '')) def _save_as(self, file_name=None): """ Saves the current state of the app with the given |file_name|. """ saved_file_name = save_board(self.board, file_name, self._app_name, self._file_extension) if saved_file_name: self._file_name = saved_file_name self.board.set_changed(False) def _save_file(self): """ Saves the current state of the app with its current file name (asks for a a file path if it currently does not have one). """ self._save_as(self._file_name) def _request_save(self): """ Requests for a file save if necessary. Returns True if there isn't anything to save or, in the case that there is something to save, if the user either decides to save the file (will be presented with a dialog to do so) or decides not to save the file. Returns False if the user cancels the request for save (i.e. does neither). """ if self.board.changed(): save = request_save_board() if save == 'yes': self._save_file() return True elif save == 'no': return True else: return False else: return True def _open_file(self, new_file_name=None): """ Opens a saved file of this app's type. """ if self._request_save(): new_file_name = new_file_name or get_board_file_name(self._file_name, self._app_name, self._file_extension) if open_board_from_file(self.board, new_file_name, self._deserializers, self._file_extension): self._file_name = new_file_name self._on_changed(False) self.board.reset_cursor_state() def _new_file(self): """ Opens a new file of this app's type. """ if self._request_save(): self._file_name = None self._init_board() def run(self): """ Runs this app. """ self.board.clear_action_history() self._root.title('%s (%s)' % (self._app_name, self._dev_stage)) if self._init_file: self._open_file(self._init_file) self._root.mainloop()
def Main1(): global reproducir reproducir=0 # Creacion de la ventana ventana = Tk() ventana.title("Proyecto Final") ventana.config(bg = "black") d = BooleanVar(ventana) e = BooleanVar(ventana) e.set(False) f = BooleanVar(ventana) f.set(False) CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 audio1 = Grabador1(CHUNK, FORMAT, CHANNELS, RATE) audio2 = Grabador2(CHUNK, FORMAT, CHANNELS, RATE) audio3 = Grabador3(CHUNK, FORMAT, CHANNELS, RATE) audio4 = Grabador4(CHUNK, FORMAT, CHANNELS, RATE) global Array1,Array2,Array3,Array4 global Rec1,Rec2,Rec3,Rec4 global ArrayFinal1,ArrayFinal2,ArrayFinal3,ArrayFinal4 global ArrayComprimido1, ArrayComprimido2, ArrayComprimido3, ArrayComprimido4 global FinalArray1,FinalArray2,FinalArray3,FinalArray4 global MezclaFinalFinal,MezclaMixFinal global FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4 global MezclaAUXFINAL, MezclaMixAux # Arreglos globales Array1 = [] Array2 = [] Array3 = [] Array4 = [] #Los de la grabacion Rec1 = [] Rec2 = [] Rec3 = [] Rec4 = [] #Arreglos comprimidos del Audio ArrayComprimido1= [] ArrayComprimido2= [] ArrayComprimido3= [] ArrayComprimido4= [] # Arreglos finales antes del fader ArrayFinal1 = [] ArrayFinal2 = [] ArrayFinal3 = [] ArrayFinal4 = [] # Arreglos finales antes del fader FinalArray1= [] FinalArray2= [] FinalArray3= [] FinalArray4= [] MezclaFinalFinal= [] MezclaMixFinal = [] #Arreglos de envio de AUX FinalArrayAux1 = [] FinalArrayAux2 = [] FinalArrayAux3 = [] FinalArrayAux4 = [] MezclaAUXFINAL = [] MezclaMixAux = [] audiocom1=BooleanVar(ventana) audiocom1.set(False) # Uso de frames para organizar la ventana. frame1 = Frame(ventana,bg = "black") frame1.pack(side=TOP) frame2 = Frame(ventana,bg = "black") frame2.pack(side=LEFT) frame3 = Frame(ventana,bg = "black") frame3.pack(side=LEFT) frame4 = Frame(ventana,bg = "black") frame4.pack(side=LEFT) frame5 = Frame(ventana,bg = "black") frame5.pack(side=LEFT) frame6 = Frame(ventana,bg = "black") frame6.pack(side=LEFT) frame7 = Frame(ventana,bg = "black") frame7.pack(side=LEFT) #PARTE FUNCIONES DE GRABACION POR CANAL !!!-------------------------------------------------------------------------- #Chanel 1 ----------------------------------------------------------- def Grabar1(): d.set(True) audio1.inicio() mensaje1.pack(side=TOP) while d.get(): audio1.grabacion() ventana.update() if d.get() is False: break def Stop1(): d.set(False) e.set(True) mensaje1.pack_forget() Nombre ='AudioUno' global Array1, Rec1 Rec1 = audio1.parar() audio1.creaAudio(Nombre) RecordButton1.configure(state='disabled') StopButton1.configure(state='disabled') file = wave.open(Nombre+'.wav','rb') tamano = int(file.getnframes()) for i in range (0,tamano): dato=file.readframes(1) packed_value = struct.unpack('<h', dato) Array1.append(packed_value) #Chanel 2 ----------------------------------------------------------- def Grabar2(): d.set(True) audio2.inicio() mensaje1.pack(side=TOP) while d.get(): audio2.grabacion() ventana.update() if d.get() is False: break def Stop2(): d.set(False) e.set(True) mensaje1.pack_forget() Nombre ='AudioDos' global Array2, Rec2 Rec2 = audio2.parar() audio2.creaAudio(Nombre) RecordButton2.configure(state='disabled') StopButton2.configure(state='disabled') file = wave.open(Nombre+'.wav','rb') tamano = int(file.getnframes()) for i in range (0,tamano): dato=file.readframes(1) packed_value = struct.unpack('<h', dato) Array2.append(packed_value) #Chanel 3------------------------------------------------------------ def Grabar3(): d.set(True) audio3.inicio() mensaje1.pack(side=TOP) while d.get(): audio3.grabacion() ventana.update() if d.get() is False: break def Stop3(): d.set(False) e.set(True) mensaje1.pack_forget() Nombre ='AudioTres' global Array3, Rec3 Rec3 = audio3.parar() audio3.creaAudio(Nombre) RecordButton3.configure(state='disabled') StopButton3.configure(state='disabled') file = wave.open(Nombre+'.wav','rb') tamano = int(file.getnframes()) for i in range (0,tamano): dato=file.readframes(1) packed_value = struct.unpack('<h', dato) Array3.append(packed_value) # Chanel 4--------------------------------------------- def Grabar4(): d.set(True) audio4.inicio() mensaje1.pack(side=TOP) while d.get(): audio4.grabacion() ventana.update() if d.get() is False: break def Stop4(): d.set(False) e.set(True) mensaje1.pack_forget() Nombre ='AudioCuatro' global Array4, Rec4 Rec4 = audio4.parar() audio4.creaAudio(Nombre) RecordButton4.configure(state='disabled') StopButton4.configure(state='disabled') file = wave.open(Nombre+'.wav','rb') tamano = int(file.getnframes()) for i in range (0,tamano): dato=file.readframes(1) packed_value = struct.unpack('<h', dato) Array4.append(packed_value) # PARTE FUNCION DE COMPRESORES ------------------------------------------------------------------------------------------------------------------------ def Equal1(): if Eq1.get()==1: EQ1() def Equal2(): if Eq2.get()==1: EQ2() def Equal3(): if Eq3.get()==1: EQ3() def Equal4(): if Eq4.get()==1: EQ4() # PARTE REPRODUCIR def Compresor1(): compresor=Tk() compresor.title("Compresor 1 ") compresor.config(bg = "black") # Uso de frames para organizar la ventana. frame1 = Frame(compresor,bg = "black") frame1.pack(side=TOP) global Array1, ArrayComprimido1 def compresoraudio1(): NivelThresh=Threshold.get() Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0) Attack1=float(Attack.get()/1000.0) CuadrosAttack=int(Attack1*44100) ratio=Ratio.get() Knee=float((ratio-1)/CuadrosAttack) ArregloAttack=[] for j in range(1, CuadrosAttack): Dato1=1+float(Knee*j) ArregloAttack.append(Dato1) for i in range(0, len(Array1)): if Array1[i][0]>Thresh1: if i<CuadrosAttack: c=Array1[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array1[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 if Array1[i][0]<(Thresh1*(-1)): if i<CuadrosAttack: c=Array1[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array1[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 else: Amp=Array1[i][0] ArrayComprimido1.append(Amp) Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black") Label1.pack(side=TOP) espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio2.pack(side=TOP) #threshold Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black") Label2.pack(side=TOP) Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black") Threshold.pack(side=TOP) #ratio Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black") Label3.pack(side=TOP) Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white") Ratio.pack(side=TOP) #attack Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black") Label4.pack(side=TOP) Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white") Attack.pack(side=TOP) #realease Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black") Label5.pack(side=TOP) Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black") Release.pack(side=TOP) #gain Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black") Label6.pack(side=TOP) Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black") Gain.pack(side=TOP) espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio1.pack(side=TOP) # Comprimir ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio1) ComprimirButton1.pack(side=TOP) compresor.mainloop() def Compresor2(): compresor=Tk() compresor.title("Compresor 2 ") compresor.config(bg = "black") # Uso de frames para organizar la ventana. frame1 = Frame(compresor,bg = "black") frame1.pack(side=TOP) global Array2, ArrayComprimido2 def compresoraudio2(): NivelThresh=Threshold.get() Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0) Attack1=float(Attack.get()/1000.0) CuadrosAttack=int(Attack1*44100) ratio=Ratio.get() Knee=float((ratio-1)/CuadrosAttack) ArregloAttack=[] for j in range(1, CuadrosAttack): Dato1=1+float(Knee*j) ArregloAttack.append(Dato1) for i in range(0, len(Array2)): if Array2[i][0]>Thresh1: if i<CuadrosAttack: c=Array2[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array2[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 if Array2[i][0]<(Thresh1*(-1)): if i<CuadrosAttack: c=Array2[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array2[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 else: Amp=Array2[i][0] ArrayComprimido2.append(Amp) Label1= Label(frame1, padx=15, pady=1, text="Compresor 2",fg = "white",bg = "black") Label1.pack(side=TOP) espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio2.pack(side=TOP) #threshold Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black") Label2.pack(side=TOP) Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black") Threshold.pack(side=TOP) #ratio Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black") Label3.pack(side=TOP) Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white") Ratio.pack(side=TOP) #attack Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black") Label4.pack(side=TOP) Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white") Attack.pack(side=TOP) #realease Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black") Label5.pack(side=TOP) Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black") Release.pack(side=TOP) #gain Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black") Label6.pack(side=TOP) Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black") Gain.pack(side=TOP) espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio1.pack(side=TOP) # Comprimir ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio2) ComprimirButton1.pack(side=TOP) compresor.mainloop() def Compresor3(): compresor=Tk() compresor.title("Compresor 3 ") compresor.config(bg = "black") # Uso de frames para organizar la ventana. frame1 = Frame(compresor,bg = "black") frame1.pack(side=TOP) global Array3, ArrayComprimido3 def compresoraudio3(): NivelThresh=Threshold.get() Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0) Attack1=float(Attack.get()/1000.0) CuadrosAttack=int(Attack1*44100) ratio=Ratio.get() Knee=float((ratio-1)/CuadrosAttack) ArregloAttack=[] for j in range(1, CuadrosAttack): Dato1=1+float(Knee*j) ArregloAttack.append(Dato1) for i in range(0, len(Array3)): if Array3[i][0]>Thresh1: if i<CuadrosAttack: c=Array3[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array3[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 if Array3[i][0]<(Thresh1*(-1)): if i<CuadrosAttack: c=Array3[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array3[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 else: Amp=Array3[i][0] ArrayComprimido3.append(Amp) Label1= Label(frame1, padx=15, pady=1, text="Compresor 3",fg = "white",bg = "black") Label1.pack(side=TOP) espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio2.pack(side=TOP) #threshold Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black") Label2.pack(side=TOP) Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black") Threshold.pack(side=TOP) #ratio Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black") Label3.pack(side=TOP) Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white") Ratio.pack(side=TOP) #attack Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black") Label4.pack(side=TOP) Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white") Attack.pack(side=TOP) #realease Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black") Label5.pack(side=TOP) Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black") Release.pack(side=TOP) #gain Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black") Label6.pack(side=TOP) Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black") Gain.pack(side=TOP) espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio1.pack(side=TOP) # Comprimir ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio3) ComprimirButton1.pack(side=TOP) compresor.mainloop() def Compresor4(): compresor=Tk() compresor.title("Compresor 4 ") compresor.config(bg = "black") # Uso de frames para organizar la ventana. frame1 = Frame(compresor,bg = "black") frame1.pack(side=TOP) global Array4, ArrayComprimido4 def compresoraudio4(): NivelThresh=Threshold.get() Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0) Attack1=float(Attack.get()/1000.0) CuadrosAttack=int(Attack1*44100) ratio=Ratio.get() Knee=float((ratio-1)/CuadrosAttack) ArregloAttack=[] for j in range(1, CuadrosAttack): Dato1=1+float(Knee*j) ArregloAttack.append(Dato1) for i in range(0, len(Array4)): if Array4[i][0]>Thresh1: if i<CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 if Array4[i][0]<(Thresh1*(-1)): if i<CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 else: Amp=Array4[i][0] ArrayComprimido4.append(Amp) Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black") Label1.pack(side=TOP) espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio2.pack(side=TOP) #threshold Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black") Label2.pack(side=TOP) Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black") Threshold.pack(side=TOP) #ratio Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black") Label3.pack(side=TOP) Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white") Ratio.pack(side=TOP) #attack Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black") Label4.pack(side=TOP) Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white") Attack.pack(side=TOP) #realease Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black") Label5.pack(side=TOP) Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black") Release.pack(side=TOP) #gain Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black") Label6.pack(side=TOP) Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black") Gain.pack(side=TOP) espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio1.pack(side=TOP) # Comprimir ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio4) ComprimirButton1.pack(side=TOP) compresor.mainloop() def PLAY(): global Array1,Array2,Array3,Array4 global Rec1,Rec2,Rec3,Rec4 global ArrayFinal1,ArrayFinal2,ArrayFinal3,ArrayFinal4 global ArrayComprimido1, ArrayComprimido2, ArrayComprimido3, ArrayComprimido4 global FinalArray1,FinalArray2,FinalArray3,FinalArray4 global MezclaFinalFinal,MezclaMixFinal ArrayFinal1 = np.asarray(Array1) ArrayFinal2 = np.asarray(Array2) ArrayFinal3 = np.asarray(Array3) ArrayFinal4 = np.asarray(Array4) ArregloCom1=np.asanyarray(ArrayComprimido1) ArregloCom2=np.asanyarray(ArrayComprimido2) ArregloCom3=np.asanyarray(ArrayComprimido3) ArregloCom4=np.asanyarray(ArrayComprimido4) #COMPRESOR 1 if Compre1.get()==0: FinalArray1= NivelModificado1(ArrayFinal1,Nivel.get()) if mute1.get()==1:#MUTE ON FinalArray1= (FinalArray1*0) if mute1.get()==0:#MUTE OFF FinalArray1= (FinalArray1*1) if Compre1.get()==1: FinalArray1=NivelModificado1(ArregloCom1,Nivel.get()) if mute1.get()==1:#MUTE ON FinalArray1= (FinalArray1*0) if mute1.get()==0:#MUTE OFF FinalArray1= (FinalArray1*1) #COMPRESOR 2 if Compre2.get()==0: FinalArray2= NivelModificado2(ArrayFinal2,Nivel2.get()) if mute2.get()==1:#MUTE ON FinalArray2= (FinalArray2*0) if mute2.get()==0:#MUTE OFF FinalArray2= (FinalArray2*1) if Compre2.get()==1: FinalArray2=NivelModificado2(ArregloCom2,Nivel2.get()) if mute2.get()==1:#MUTE ON FinalArray2= (FinalArray2*0) if mute2.get()==0:#MUTE OFF FinalArray2= (FinalArray2*1) #COMPRESOR 3 if Compre3.get()==0: FinalArray3= NivelModificado3(ArrayFinal3,Nivel3.get()) if mute3.get()==1:#MUTE ON FinalArray3= (FinalArray3*0) if mute3.get()==0:#MUTE OFF FinalArray3= (FinalArray3*1) if Compre3.get()==1: FinalArray3=NivelModificado3(ArregloCom3,Nivel3.get()) if mute3.get()==1:#MUTE ON FinalArray3= (FinalArray2*0) if mute3.get()==0:#MUTE OFF FinalArray3= (FinalArray2*1) #COMPRESOR 4 if Compre4.get()==0: FinalArray4= NivelModificado4(ArrayFinal4,Nivel4.get()) if mute4.get()==1:#MUTE ON FinalArray4= (FinalArray4*0) if mute4.get()==0:#MUTE OFF FinalArray4= (FinalArray4*1) if Compre4.get()==1: FinalArray4=NivelModificado4(ArregloCom4,Nivel4.get()) if mute4.get()==1:#MUTE ON FinalArray4= (FinalArray4*0) if mute4.get()==0:#MUTE OFF FinalArray4= (FinalArray4*1) # MEZCLA !! MezclaFinalFinal= [w+x+y+z for w,x,y,z in izip_longest(FinalArray1,FinalArray2,FinalArray3,FinalArray4,fillvalue=0)] MixFinalFinal= np.asarray(MezclaFinalFinal) NivelFaderMix= Nivel6.get() MezclaMixFinal= NivelModificadoMix(MixFinalFinal,NivelFaderMix) #REPRODUCCION EN TIEMPO REAL PlayRealTime=[] p=pyaudio.PyAudio() stream=p.open(format=2,channels=1,rate=44100,output=True) for k in range(0, len(MezclaMixFinal)): packed_value = struct.pack('<h', MezclaMixFinal[k]) PlayRealTime.append(packed_value) value_str=''.join(PlayRealTime) stream.write(value_str) stream.close() def Aux(): #ENVIO DE AUXILIAR global FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4 global MezclaAUXFINAL, MezclaMixAux FinalArrayAux1= NivelModificado1(ArrayFinal4,ReverbNivel1.get()) FinalArrayAux2= NivelModificado1(ArrayFinal4,ReverbNivel2.get()) FinalArrayAux3= NivelModificado1(ArrayFinal4,ReverbNivel3.get()) FinalArrayAux4= NivelModificado1(ArrayFinal4,ReverbNivel4.get()) MezclaAUXFINAL= [w+x+y+z for w,x,y,z in izip_longest(FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4,fillvalue=0)] MixFinalFinalAux= np.asarray(MezclaAUXFINAL) NivelFaderAUX= Nivel5.get() MezclaMixAux= NivelModificadoMix(MixFinalFinalAux,NivelFaderAUX) def ExportarMix(): global MezclaMixFinal doc=file(44100,16,'MEZCLA') doc.archive(MezclaMixFinal) mensaje2.pack(side=TOP) ReproButton1.pack(side=TOP) def Reproducir1(): nombre = 'MEZCLA' reproduce(nombre) def RealPlay1(): pygame.mixer.init(44100,-16,2,4096) Grabacion1 = pygame.mixer.Sound('AudioUno') Grabacion2 = pygame.mixer.Sound('AudioDos') Grabacion3 = pygame.mixer.Sound('AudioTres') Grabacion4 = pygame.mixer.Sound('AudioCuatro') RealTimePLay1(Grabacion1,Grabacion2,Grabacion3,Grabacion4,Nivel.get(),Nivel2.get(),Nivel3.get(),Nivel4.get(),Nivel6.get(),mute1.get(),mute2.get(),mute3.get(),mute4.get()) # Label para la interfraz grafica - definicion de los botones---------------------------------------------------------------------------------------- Label1= Label(frame1, padx=15, pady=1, text="Luis Sandoval, Andres Palacio, Libardo Montealegre",fg = "white",bg = "black") Label1.pack(side=TOP) mensaje1 = Label(frame1, fg='red', padx=15, pady=10, text='Grabando...',bg = "black" ) #CHANEL 1-------------------------------------------------------------------------------------------------------------- mute1=IntVar() Eq1 = IntVar() Compre1 = IntVar() Label2= Label(frame2, padx=15, pady=1, text=" Canal 1",fg = "red",bg = "black") Label2.pack(side=TOP) RecordButton1 = Button(frame2, padx=30, pady=2, text="Record 1",bg = "red",fg="white", command= Grabar1 ) RecordButton1.pack(side=TOP) StopButton1 = Button(frame2, padx=30, pady=2, text=" Stop ",bg = "red",fg="white", command= Stop1) StopButton1.pack(side=TOP) LabelPro1= Label(frame2, padx=15, pady=1, text="Procesos",fg = "red",bg = "black") LabelPro1.pack(side=TOP) EQButton1 = Checkbutton(frame2, padx=30,variable= Eq1,onvalue=1,offvalue=0, pady=2, text="EQ1",bg = "red",fg="black", command= Equal1) EQButton1.pack(side=TOP) ACompresorButton1= Button(frame2, padx=30, pady=2, text="Compresor",bg = "red",fg="black",command=Compresor1) ACompresorButton1.pack(side=TOP) CompresorButton1= Checkbutton(frame2, padx=30,variable= Compre1,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="red") CompresorButton1.pack(side=TOP) LabelReverb1= Label(frame2, padx=15, pady=1, text="Reverb",fg = "red",bg = "black") LabelReverb1.pack(side=TOP) ReverbNivel1 = Scale(frame2, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "red", fg="white") ReverbNivel1.pack(side=TOP) MuteButton1 = Checkbutton(frame2, padx=30,variable= mute1,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "red",fg="black") MuteButton1.pack(side=TOP) Nivel = Scale(frame2, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "red", fg="white") Nivel.pack(side=TOP, padx=1, pady=1) #CHANEL 2------------------------------------------------------------------------------------------------ mute2 = IntVar() Eq2 = IntVar() Compre2 = IntVar() Label3= Label(frame3, padx=15, pady=1, text=" Canal 2",fg = "blue",bg = "black") Label3.pack(side=TOP) RecordButton2 = Button(frame3, padx=30, pady=2, text="Record 2",bg = "blue",fg="white",command= Grabar2 ) RecordButton2.pack(side=TOP) StopButton2 = Button(frame3, padx=30, pady=2, text=" Stop ",bg = "blue",fg="white",command= Stop2 ) StopButton2.pack(side=TOP) LabelPro2= Label(frame3, padx=15, pady=1, text="Procesos",fg = "blue",bg = "black") LabelPro2.pack(side=TOP) EQButton2 = Checkbutton(frame3, padx=30,variable= Eq2,onvalue=1,offvalue=0, pady=2, text="EQ2",bg = "blue",fg="black",command= Equal2) EQButton2.pack(side=TOP) ACompresorButton2= Button(frame3, padx=30, pady=2, text="Compresor",bg = "blue",fg="black",command=Compresor2) ACompresorButton2.pack(side=TOP) CompresorButton2= Checkbutton(frame3, padx=30,variable= Compre2,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="blue") CompresorButton2.pack(side=TOP) LabelReverb2= Label(frame3, padx=15, pady=1, text="Reverb",fg = "blue",bg = "black") LabelReverb2.pack(side=TOP) ReverbNivel2 = Scale(frame3, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "blue", fg="white") ReverbNivel2.pack(side=TOP) MuteButton2 = Checkbutton(frame3, padx=30,variable= mute2,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "blue",fg="black") MuteButton2.pack(side=TOP) Nivel2 = Scale(frame3, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "blue", fg="white") Nivel2.pack(side=TOP, padx=1, pady=1) #CHANEL 3----------------------------------------------------------------------------- mute3 = IntVar() Eq3 = IntVar() Compre3 = IntVar() Label4= Label(frame4, padx=15, pady=1, text=" Canal 3",fg = "green",bg = "black") Label4.pack(side=TOP) RecordButton3 = Button(frame4, padx=30, pady=2, text="Record 3",bg = "green",fg="white",command= Grabar3) RecordButton3.pack(side=TOP) StopButton3 = Button(frame4, padx=30, pady=2, text=" Stop ",bg = "green",fg="white",command= Stop3) StopButton3.pack(side=TOP) LabelPro3= Label(frame4, padx=15, pady=1, text="Procesos",fg = "green",bg = "black") LabelPro3.pack(side=TOP) EQButton3 = Checkbutton(frame4, padx=30,variable= Eq3,onvalue=1,offvalue=0, pady=2, text="EQ3",bg = "green",fg="black",command= Equal3) EQButton3.pack(side=TOP) ACompresorButton3= Button(frame4, padx=30, pady=2, text="Compresor",bg = "green",fg="black",command=Compresor3) ACompresorButton3.pack(side=TOP) CompresorButton3 = Checkbutton(frame4, padx=30,variable= Compre3,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="green") CompresorButton3.pack(side=TOP) LabelReverb3= Label(frame4, padx=15, pady=1, text="Reverb",fg = "green",bg = "black") LabelReverb3.pack(side=TOP) ReverbNivel3 = Scale(frame4, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "green", fg="white") ReverbNivel3.pack(side=TOP) MuteButton3 = Checkbutton(frame4, padx=30,variable= mute3,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "green",fg="black") MuteButton3.pack(side=TOP) Nivel3 = Scale(frame4, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "green", fg="white") Nivel3.pack(side=TOP, padx=1, pady=1) #CHANEL 4------------------------------------------------------------------------------------------- mute4 = IntVar() Eq4 = IntVar() Compre4 = IntVar() Label5= Label(frame5, padx=15, pady=1, text=" Canal 4",fg = "purple",bg = "black") Label5.pack(side=TOP) RecordButton4 = Button(frame5, padx=30, pady=2, text="Record 4",bg = "purple",fg="white", command= Grabar4) RecordButton4.pack(side=TOP) StopButton4 = Button(frame5, padx=30, pady=2, text=" Stop ",bg = "purple",fg="white", command= Stop4) StopButton4.pack(side=TOP) LabelPro4= Label(frame5, padx=15, pady=1, text="Procesos",fg = "purple",bg = "black") LabelPro4.pack(side=TOP) EQButton4 = Checkbutton(frame5, padx=30,variable= Eq4,onvalue=1,offvalue=0, pady=2, text="EQ4",bg = "purple",fg="black",command= Equal4) EQButton4.pack(side=TOP) ACompresorButton4= Button(frame5, padx=30, pady=2, text="Compresor",bg = "purple",fg="black",command=Compresor4) ACompresorButton4.pack(side=TOP) CompresorButton4 = Checkbutton(frame5, padx=30,variable= Compre4,onvalue=1,offvalue=0, pady=2, text="ON / OFF ",bg = "black",fg="purple") CompresorButton4.pack(side=TOP) LabelReverb4= Label(frame5, padx=15, pady=1, text="Reverb",fg = "purple",bg = "black") LabelReverb4.pack(side=TOP) ReverbNivel4 = Scale(frame5, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "purple", fg="white") ReverbNivel4.pack(side=TOP) MuteButton4 = Checkbutton(frame5, padx=30,variable= mute4,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "purple",fg="black") MuteButton4.pack(side=TOP) Nivel4 = Scale(frame5, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "purple", fg="white") Nivel4.pack(side=TOP, padx=1, pady=1) # AUXILIAR------------------------------------------------------------------------------------------ Label6= Label(frame6, padx=15, pady=1, text=" Auxiliar Reverb",fg = "orange",bg = "black") Label6.pack(side=TOP) Nivel5 = Scale(frame6, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "orange", fg="white") Nivel5.pack(side=TOP, padx=1, pady=1) AUXButton = Button(frame6, padx=10, pady=2, text="AUX MIX",bg = "orange",fg="black",command= Aux) AUXButton.pack(side=TOP) # MAIN MIX ------------------------------------------------------------------------------------------ Label7= Label(frame7, padx=15, pady=1, text=" Main MIX",fg = "turquoise",bg = "black") Label7.pack(side=TOP) Nivel6 = Scale(frame7, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "turquoise", fg="black") Nivel6.pack(side=TOP, padx=1, pady=1) PlayButton = Button(frame7, padx=30, pady=2, text="PLAY",bg = "turquoise",fg="black",command= PLAY) PlayButton.pack(side=TOP) StopButton = Button(frame7, padx=30, pady=2, text="STOP",bg = "turquoise",fg="black") StopButton.pack(side=TOP) ExportButton = Button(frame7, padx=30, pady=2, text="Exportar",bg = "turquoise",fg="black",command= ExportarMix) ExportButton.pack(side=TOP) mensaje2 = Label(frame7, fg='green', padx=15, pady=10, text='Archivo Exportado',bg = "black") ReproButton1 = Button(frame7, padx=30, pady=2, text="Reproducir Archivo Exportado",command=Reproducir1 ,bg = "turquoise",fg="black") ventana.mainloop()
else: try: unicode_text = f.decode('utf-8') except UnicodeDecodeError: print('unicode error, trying different encoding') else: abs_path = os.path.join(os.path.dirname(__file__), 'output_from_utf8_to_cp1251.txt') text_in_1251 = unicode_text.encode('cp1251') f = open(abs_path, 'w') f.write(text_in_1251) root = Tk() root.title('UTF-8 Converter') root.geometry('250x250+500+300') root.config(background="#FFFFFF") button = Tkinter.Button(root, text="Check encoding", width=25, bg="#FFFFFF", command=open_file) button.pack(fill=X, padx=10, pady=20) res = Label(root, bg="#FFFFFF") res.pack() button1 = Tkinter.Button(root, text="Convert from windows-1251 to utf-8", width=25, bg="#FFFFFF", command=convert_from_windows_1251) button1.pack(fill=X, padx=10, pady=15) button1 = Tkinter.Button(root, text="Convert from utf-8 to windows-1251", width=25, bg="#FFFFFF", command=convert_from_utf8_to_windows_1251) button1.pack(fill=X, padx=10, pady=15)
def Compresor4(): compresor=Tk() compresor.title("Compresor 4 ") compresor.config(bg = "black") # Uso de frames para organizar la ventana. frame1 = Frame(compresor,bg = "black") frame1.pack(side=TOP) global Array4, ArrayComprimido4 def compresoraudio4(): NivelThresh=Threshold.get() Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0) Attack1=float(Attack.get()/1000.0) CuadrosAttack=int(Attack1*44100) ratio=Ratio.get() Knee=float((ratio-1)/CuadrosAttack) ArregloAttack=[] for j in range(1, CuadrosAttack): Dato1=1+float(Knee*j) ArregloAttack.append(Dato1) for i in range(0, len(Array4)): if Array4[i][0]>Thresh1: if i<CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 if Array4[i][0]<(Thresh1*(-1)): if i<CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ArregloAttack[i]) Amp=k+Thresh1 if i >CuadrosAttack: c=Array4[i][0]-Thresh1 k=float(c/ratio) Amp=k+Thresh1 else: Amp=Array4[i][0] ArrayComprimido4.append(Amp) Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black") Label1.pack(side=TOP) espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio2.pack(side=TOP) #threshold Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black") Label2.pack(side=TOP) Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black") Threshold.pack(side=TOP) #ratio Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black") Label3.pack(side=TOP) Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white") Ratio.pack(side=TOP) #attack Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black") Label4.pack(side=TOP) Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white") Attack.pack(side=TOP) #realease Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black") Label5.pack(side=TOP) Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black") Release.pack(side=TOP) #gain Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black") Label6.pack(side=TOP) Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black") Gain.pack(side=TOP) espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black") espacio1.pack(side=TOP) # Comprimir ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio4) ComprimirButton1.pack(side=TOP) compresor.mainloop()
class TkApplicationWindow(AbstractApplicationWindow): def __init__(self, app): self.root = Tk() self.root.title("Llia") self.root.config(background=factory.bg()) super(TkApplicationWindow, self).__init__(app, self.root) self.root.withdraw() if app.config()["enable-splash"]: splash = TkSplashWindow(self.root, app) self.root.deiconify() self.root.protocol("WM_DELETE_WINDOW", self.exit_app) self.llia_graph = None self._main = layout.BorderFrame(self.root) self._main.config(background=factory.bg()) self._main.pack(anchor="nw", expand=True, fill=BOTH) self._progressbar = None self._init_status_panel() self._init_menu() self._init_center_frame(self._main.center) self.root.minsize(width=665, height=375) self.group_windows = [] self.add_synth_group() self._scene_filename = "" def _init_status_panel(self): south = self._main.south south.configure(padx=4, pady=4) self._lab_status = factory.label(south, "", modal=False) b_panic = factory.panic_button(south) b_down = factory.button(south, "-") b_up = factory.button(south, "+") b_panic.grid(row=0, column=0) self._progressbar = Progressbar(south,mode="indeterminate") self._progressbar.grid(row=0,column=PROGRESSBAR_COLUMN, sticky='w', padx=8) self._lab_status.grid(row=0,column=4, sticky='w') south.config(background=factory.bg()) b_down.configure(command=lambda: self.root.lower()) b_up.configure(command=lambda: self.root.lift()) self.update_progressbar(100, 0) def _tab_change_callback(self, event): self.llia_graph.sync() def _init_center_frame(self, master): nb = ttk.Notebook(master) nb.pack(expand=True, fill="both") frame_synths = layout.FlowGrid(nb, 6) frame_efx = layout.FlowGrid(nb, 6) frame_controllers = layout.FlowGrid(nb, 6) self.llia_graph = LliaGraph(nb, self.app) nb.add(frame_synths, text = "Synths") nb.add(frame_efx, text = "Effects") nb.add(frame_controllers, text = "Controllers") nb.add(self.llia_graph, text="Graph") nb.bind("<Button-1>", self._tab_change_callback) def display_info_callback(event): sp = event.widget.synth_spec msg = "%s: %s" % (sp["format"],sp["description"]) self.status(msg) def clear_info_callback(*_): self.status("") for st in con.SYNTH_TYPES: sp = specs[st] ttp = "Add %s Synthesizer (%s)" % (st, sp["description"]) b = factory.logo_button(frame_synths, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_synth_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_synths.add(b) for st in con.EFFECT_TYPES: sp = specs[st] ttp = "Add %s Effect (%s)" % (st, sp["description"]) b = factory.logo_button(frame_efx, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_efx_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_efx.add(b) for st in con.CONTROLLER_SYNTH_TYPES: sp = specs[st] ttp = "Add %s Effect (%s)" % (st, sp["description"]) b = factory.logo_button(frame_controllers, st, ttip=ttp) b.synth_spec = sp b.bind("<Button-1>", self._show_add_controller_dialog) b.bind("<Enter>", display_info_callback) b.bind("<Leave>", clear_info_callback) frame_controllers.add(b) @staticmethod def menu(master): m = Menu(master, tearoff=0) m.config(background=factory.bg(), foreground=factory.fg()) return m def _init_menu(self): main_menu = self.menu(self.root) self.root.config(menu=main_menu) file_menu = self.menu(main_menu) osc_menu = self.menu(main_menu) midi_menu = self.menu(main_menu) bus_menu = self.menu(main_menu) #buffer_menu = self.menu(main_menu) tune_menu = self.menu(main_menu) help_menu = self.menu(main_menu) main_menu.add_cascade(label="File", menu=file_menu) main_menu.add_cascade(label="OSC", menu=osc_menu) main_menu.add_cascade(label="MIDI", menu=midi_menu) #main_menu.add_cascade(label="Buses", menu=bus_menu) #main_menu.add_cascade(label="Buffers", menu=buffer_menu) #main_menu.add_cascade(label="Tune", menu=tune_menu) #main_menu.add_cascade(label="Help", menu=help_menu) self._init_file_menu(file_menu) self._init_osc_menu(osc_menu) self._init_midi_menu(midi_menu) self._init_bus_menu(bus_menu) #self._init_buffer_menu(buffer_menu) self._init_tune_menu(tune_menu) self._init_help_menu(help_menu) def _init_file_menu(self, fmenu): fmenu.add_command(label="Save Scene", command = self.save_scene) fmenu.add_command(label="Load Scene", command = self.load_scene) fmenu.add_separator() fmenu.add_command(label="Lliascript (Legacy)", command = self.show_history_editor) fmenu.add_separator() fmenu.add_command(label="New Synth Group", command = self._add_synth_group) fmenu.add_separator() fmenu.add_command(label="Restart", command = self._interactive_tabula_rasa) fmenu.add_command(label="Quit", command = self.exit_app) def _init_osc_menu(self, iomenu): iomenu.add_command(label="Ping", command = self.ping_global) iomenu.add_command(label="Dump", command = self.app.proxy.dump) iomenu.add_command(label="Toggle OSC Trace", command = self.toggle_osc_trace) def _init_midi_menu(self, mmenu): map_menu = self.menu(mmenu) mmenu.add_command(label = "Channel Names", command = self.show_channel_name_dialog) mmenu.add_command(label = "Controller Names", command = self.show_controller_name_dialog) mmenu.add_cascade(label = "MIDI Maps", menu = map_menu) mmenu.add_command(label = "Toggle MIDI Input Trace", command = self.toggle_midi_input_trace) mmenu.add_command(label = "Toggle MIDI Output Trace", command = self.toggle_midi_output_trace) mmenu.add_command(label = "Toggle Program Pretty Printer", command = self.toggle_program_pretty_printer) def _init_bus_menu(self, bmenu): bmenu.add_command(label="Audio", command=self.show_audiobus_dialog) bmenu.add_command(label="Control", command=self.show_controlbus_dialog) # def _init_buffer_menu(self, bmenu): # bmenu.add_command(label="View Buffers", command=self.show_bufferlist_dialog) def _init_tune_menu(self, tmenu): tmenu.add_command(label = "FIX ME: Nothing to see here") def _init_help_menu(self, hmenu): pass def exit_gui(self): try: self.root.destroy() except: pass def confirm_exit(self): return tkMessageBox.askyesno("Exit Llia", "Exit Llia?") def exit_app(self): self.app.exit_() def as_widget(self): return self.root def status(self, msg): self._lab_status.config(text=str(msg)) def warning(self, msg): msg = "WARNING: %s" % msg self._lab_status.config(text=msg) def clear_status(self): self.status("") def start_gui_loop(self): self.root.mainloop() def show_about_dialog(self): from llia.gui.tk.tk_about_dialog import TkAboutDialog dialog = TkAboutDialog(self.root, self.app) self.root.wait_window(dialog) def display_help(self, topic=None): pass def show_history_editor(self): from llia.gui.tk.tk_history import TkHistoryEditor dialog = TkHistoryEditor(self.root, self.app) self.root.wait_window(dialog) def ping_global(self): try: rs = self.app.proxy.ping() if rs: self.status("Ping OK") else: self.warning("Ping Error") except LliaPingError as err: self.warning(err.message) def toggle_osc_trace(self): LliaProxy.trace = not LliaProxy.trace if LliaProxy.trace: self.status("OSC transmission trace enabled") else: self.status("OSC transmission trace disabled") def show_channel_name_dialog(self): from llia.gui.tk.tk_channel_name_editor import TkChannelNameEditor dialog = TkChannelNameEditor(self.root, self.app) self.root.wait_window(dialog) def show_controller_name_dialog(self): from llia.gui.tk.tk_controller_name_editor import TkControllerNameEditor dialog = TkControllerNameEditor(self.root, self.app) self.root.wait_window(dialog) def toggle_midi_input_trace(self): flag = not self.app.midi_in_trace self.app.midi_in_trace = flag self.app.midi_receiver.enable_trace(flag) if flag: self.status("MIDI input trace enabled") else: self.status("MIDI output trace disabled") def toggle_midi_output_trace(self): self.status("MIDI output not available") # FIX ME def toggle_program_pretty_printer(self): self.app.pp_enabled = not self.app.pp_enabled if self.app.pp_enabled: self.status("Pretty printer enabled") else: self.status("Pretty printer disabled") def show_audiobus_dialog(self): from llia.gui.tk.tk_audiobus_editor import TkAudiobusEditor dialog = TkAudiobusEditor(self.root, self.app) self.root.wait_window(dialog) def show_controlbus_dialog(self): from llia.gui.tk.tk_controlbus_editor import TkControlbusEditor dialog = TkControlbusEditor(self.root, self.app) self.root.wait_window(dialog) # def show_bufferlist_dialog(self): # from llia.gui.tk.tk_buffer_info import TkBufferListDialog # dialog = TkBufferListDialog(self.root, self.app) # self.root.wait_window(dialog) def _show_add_synth_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, False) self.root.wait_window(dialog) def _show_add_efx_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=True, is_controller=False) self.root.wait_window(dialog) def _show_add_controller_dialog(self, event): w = event.widget st = w.config()["text"][-1] dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=False, is_controller=True) self.root.wait_window(dialog) def _add_synth_group(self): sh = self.app.ls_parser.synthhelper sh.new_group() def add_synth_group(self, name=None): gw = GroupWindow(self.app, self.root, name) # gw.transient(self.root) # If executed keeps main app window behind all other windows. self.group_windows.append(gw) self.status("Added new Synth Group Window") return gw def display_synth_editor(self, sid): try: swin = self[sid] grpid = swin.group_index grp = self.group_windows[grpid] #grp.deiconify() grp.show_synth_editor(sid) except (KeyError, IndexError): msg = "Can not find editor for %s" % sid self.warning(msg) def update_progressbar(self, count, value): self._progressbar.config(mode="determinate", maximum=count) self._progressbar.step() self.root.update_idletasks() def busy(self, flag, message=""): if message: self.status(message) self._progressbar.config(mode="indeterminate") if flag: self._progressbar.grid(row=0, column=PROGRESSBAR_COLUMN, sticky='w', padx=8) self._progressbar.start() else: self._progressbar.stop() # self._progressbar.grid_remove() self.root.update_idletasks() def save_scene(self, *_): options = {'defaultextension' : '.llia', 'filetypes' : [('Llia Scenes', '*.llia'), ('all files', '*')], 'initialfile' : self._scene_filename, 'parent' : self.root, 'title' : "Save Llia Scene"} filename = tkFileDialog.asksaveasfilename(**options) if filename: try: self.app.ls_parser.save_scene(filename) self._scene_filename = filename self.status("Scene saved as '%s'" % filename) except Exception as ex: self.warning(ex.message) else: self.status("Scene save canceld") def load_scene(self, *_): options = {'defaultextension' : '.llia', 'filetypes' : [('Llia Scenes', '*.llia'), ('all files', '*')], 'initialfile' : self._scene_filename, 'parent' : self.root, 'title' : "Load Llia Scene"} filename = tkFileDialog.askopenfilename(**options) if filename: try: self.app.ls_parser.load_scene(filename) self.status("Scene '%s' loaded" % filename) self._scene_filename = filename except Exception as ex: self.warning(ex.message) else: self.status("Load scene canceld") def tabula_rasa(self): for grp in self.group_windows: grp.tabula_rasa() self.group_windows = [] def _interactive_tabula_rasa(self, *_): # ISSUE: Check config and ask user confirmation before existing self.app.ls_parser.tabula_rasa()
class OSCMonitor(object): def __init__(self): self.editor_issue="1.3" # get command options self.command_options=remote_options() # get directory holding the code self.pp_dir=sys.path[0] if not os.path.exists(self.pp_dir+os.sep+"pipresents.py"): tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit() # Initialise logging Monitor.log_path=self.pp_dir self.mon=Monitor() self.mon.init() Monitor.classes = ['OSCMonitor','OSCConfig','OSCEditor'] Monitor.log_level = int(self.command_options['debug']) self.mon.log (self, "Pi Presents Monitor is starting") self.mon.log (self," OS and separator " + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: code "+sys.path[0]) self.setup_gui() # initialise OSC config class self.osc_config=OSCConfig() self.init() #and start the system self.root.after(1000,self.run_app) self.root.mainloop() def init(self): # read the options and allow their editing self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscmonitor.cfg' self.read_create_osc() def add_status(self,text): self.status_display.insert(END,text+'\n') self.status_display.see(END) def run_app(self): self.client=None self.server=None self.st=None # initialise OSC variables self.prefix='/pipresents' self.this_unit='/' + self.osc_config.this_unit_name self.add_status('this unit is: '+self.this_unit) self.controlled_by_unit='/'+self.osc_config.controlled_by_name self.add_status('controlled by unit : '+self.controlled_by_unit) #connect client for replies then start server to listen for commands self.client = OSC.OSCClient() self.add_status('connecting to controlled by unit: '+self.osc_config.controlled_by_ip+':'+self.osc_config.controlled_by_port +' '+self.osc_config.controlled_by_name) self.client.connect((self.osc_config.controlled_by_ip,int(self.osc_config.controlled_by_port))) self.add_status('listening for commands on:'+self.osc_config.this_unit_ip+':'+self.osc_config.this_unit_port) self.init_server(self.osc_config.this_unit_ip,self.osc_config.this_unit_port,self.client) self.add_initial_handlers() self.start_server() # *************************************** # OSC CLIENT TO SEND REPLIES # *************************************** def disconnect_client(self): if self.client != None: self.client.close() return # *************************************** # OSC SERVER TO LISTEN TO COMMANDS # *************************************** def init_server(self,ip,port_text,client): self.add_status('Init Server: '+ip+':'+port_text) self.server = myOSCServer((ip,int(port_text)),client) def start_server(self): self.add_status('Start Server') self.st = threading.Thread( target = self.server.serve_forever ) self.st.start() def close_server(self): if self.server != None: self.server.close() self.mon.log(self, 'Waiting for Server-thread to finish') if self.st != None: self.st.join() ##!!! self.mon.log(self,'server thread closed') def add_initial_handlers(self): pass self.server.addMsgHandler('default', self.no_match_handler) self.server.addMsgHandler(self.prefix+self.this_unit+"/system/server-info", self.server_info_handler) self.server.addMsgHandler(self.prefix+self.this_unit+"/system/loopback", self.loopback_handler) def no_match_handler(self,addr, tags, stuff, source): text= "Message from %s" % OSC.getUrlStr(source)+'\n' text+= " %s" % addr+ self.pretty_list(stuff) self.add_status(text+'\n') def server_info_handler(self,addr, tags, stuff, source): msg = OSC.OSCMessage(self.prefix+self.controlled_by_unit+'/system/server-info-reply') msg.append('Unit: '+ self.osc_config.this_unit_name) self.add_status('Server Info Request from %s:' % OSC.getUrlStr(source)) return msg def loopback_handler(self,addr, tags, stuff, source): # send a reply to the client. msg = OSC.OSCMessage(self.prefix+self.controlled_by_unit+'/system/loopback-reply') self.add_status('Loopback Request from %s:' % OSC.getUrlStr(source)) return msg def pretty_list(self,fields): text=' ' for field in fields: text += str(field) + ' ' return text # *************************************** # INIT EXIT MISC # *************************************** def e_edit_osc(self): self.disconnect_client() self.close_server() self.edit_osc() self.init() self.add_status('\n\n\nRESTART') self.run_app() def app_exit(self): self.disconnect_client() self.close_server() if self.root is not None: self.root.destroy() self.mon.finish() sys.exit() def show_help (self): tkMessageBox.showinfo("Help","Read 'manual.pdf'") def about (self): tkMessageBox.showinfo("About","Simple Remote Monitor for Pi Presents\n" +"Author: Ken Thompson" +"\nWebsite: http://pipresents.wordpress.com/") def setup_gui(self): # set up the gui # root is the Tkinter root widget self.root = Tk() self.root.title("Remote Monitor for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False,False) # define response to main window closing self.root.protocol ("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = StringVar() self.display_show = StringVar() self.results = StringVar() self.status = StringVar() # define menu menubar = Menu(self.root) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu = toolsmenu) osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Options', menu = osc_configmenu) osc_configmenu.add_command(label='Edit', command = self.e_edit_osc) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu = helpmenu) helpmenu.add_command(label='Help', command = self.show_help) helpmenu.add_command(label='About', command = self.about) self.root.config(menu=menubar) # status_frame status_frame=Frame(self.root,padx=5,pady=5) status_frame.pack(side=TOP, fill=BOTH, expand=1) status_label = Label(status_frame, text="Status",font="arial 12 bold") status_label.pack(side=LEFT) scrollbar = Scrollbar(status_frame, orient=VERTICAL) self.status_display=Text(status_frame,height=10, yscrollcommand=scrollbar.set) scrollbar.config(command=self.status_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.status_display.pack(side=LEFT,fill=BOTH, expand=1) # *************************************** # OSC CONFIGURATION # *************************************** def read_create_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file,'slave','Create OSC Monitor Configuration') self.osc_config.read(self.osc_config_file) def edit_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file,'slave','Edit OSC Monitor Configuration')
textvariable=stage4Pos, anchor=W, bg="white", fg="black", font=("Times New Roman", 12)) stage4Position.grid(row=1, column=0) return def updatePositions(): #import all of the labels for the positions. global ser global stage1Pos, stage2Pos, stage3Pos, stage4Pos dataManagement.setCurrentPositionLabel(ser, stage1Pos, stage2Pos, stage3Pos, stage4Pos) return menubar = Menu(root) fileMenu = Menu(menubar, tearoff=0) fileMenu.add_command(label="Quit", command=quit) menubar.add_cascade(label="File", menu=fileMenu) root.config(menu=menubar) setupFrames() setupSerialSection() setupHomeAndZeroSection() setupMoveSection() setupMovementLabels() updateOptionMenu() root.mainloop()
if (data[0:4]=='exit'): del peersData[peer_id] root.event_generate('<<new>>', when='tail') if (data[0:6]=='mclear' and peer_id==my_ip): print "clear?" clear_request_received_time = time.time() #layout initialization, start receiving thread if __name__ == "__main__": root = Tk() root.title('Shared whiteboard') root.config(bg='#ddd') root.columnconfigure(2, weight=1) root.rowconfigure(1, weight=1) root.protocol("WM_DELETE_WINDOW", callback) root.minsize(width=600, height=340) root.bind('<<openIt!>>', myDialog) root.bind('<<sorry>>', sorryDialog) root.bind('<<new>>', refreshMessage) canvas = Canvas(root, width=canvasWidth, height=canvasHeight, bg='#fff') canvas.grid(column=0, row=1, sticky=(N, W, E, S), columnspan=7) clearButton = Button(root, text="Clear everyone's canvas", width = 20, command=clearCanvas) clearButton.grid(column=0, row=0, padx=5, pady=5)
def Main1(): # Creacion de la ventana ventana = Tk() ventana.title("Ventana Principal") ventana.config(bg = "black") d = BooleanVar(ventana) e = BooleanVar(ventana) e.set(False) f = BooleanVar(ventana) f.set(False) global arreglo1 arreglo1 = [] # Uso de frames para organizar la ventana. frame1 = Frame(ventana,bg = "black") frame1.pack(side=TOP) frame2 = Frame(ventana,bg = "black") frame2.pack(side=TOP) frame3 = Frame(ventana,bg = "black") frame3.pack(side=TOP) frame4 = Frame(ventana,bg = "black") frame4.pack(side=TOP) frame5 = Frame(ventana,bg = "black") frame5.pack(side=TOP) frame6 = Frame(ventana,bg = "black") frame6.pack(side=TOP) frame7 = Frame(ventana,bg = "black") frame7.pack(side=TOP) def Delay(): if e1.get() == '': print 'error' tkMessageBox._show('Error', 'No ingreso frecuencia a generar.') if e2.get() == '': print 'error' tkMessageBox._show('Error', 'No ingreso duracion del audio.') if e3.get() == '': print 'error' tkMessageBox._show('Error', 'No ingreso el numero de cuadros.') if e4.get() == '': print 'error' tkMessageBox._show('Error', 'No ingreso nombre del audio.') else: d.set(True) Frecuencia = int( e1.get()) Time = int( e2.get()) Frames = int( e3.get()) Nombre = e4.get() Niveles = Nivel.get() Delay1 = GenerarRetraso(Time,Frecuencia,Frames) Delay1.generar() Delay1.NivelModificado(Niveles) Delay1.GenerarAudio1(Nombre) Delay1.graficar() # funcion para cerrar la ventana actual y abrir el main def Ventana2(): ventana.destroy() Main2() # funcion que reproduce el audio final def ReproducirMain(): nombre = e4.get() reproduce(nombre) # Label para la interfraz grafica - definicion de los botones cuadro= Label(frame1, padx=15, pady=1, text="DELAY 1 ",fg = "red",bg = "black") cuadro.pack(side=TOP) cuadro1= Label(frame1, padx=15, pady=1, text="Luis Sandoval , Andres Palacio, Libardo Montealegre",fg = "red",bg = "black") cuadro1.pack(side=TOP) cuadro2= Label(frame2, padx=15, pady=10, text="Digite la frecuencia a generar:",fg = "white",bg = "black") cuadro2.pack(side=LEFT) e1 = Entry(frame2, bd=5, insertwidth=1) e1.pack(side=LEFT, padx=15, pady=10) cuadro3= Label(frame3, padx=15, pady=10, text="Digite la duracion del Audio:",fg = "white",bg = "black") cuadro3.pack(side=LEFT) e2 = Entry(frame3, bd=5, insertwidth=1) e2.pack(side=LEFT, padx=15, pady=10) cuadro4= Label(frame4, padx=15, pady=10, text="Cantidad de cuadros a retrasar",fg = "white",bg = "black") cuadro4.pack(side=LEFT) e3 = Entry(frame4, bd=5, insertwidth=1) e3.pack(side=LEFT, padx=15, pady=10) cuadro5= Label(frame5, padx=15, pady=10, text="Nombre del Archivo a generar",fg = "white",bg = "black") cuadro5.pack(side=LEFT) e4 = Entry(frame5, bd=5, insertwidth=1) e4.pack(side=LEFT, padx=15, pady=10) cuadro2= Label(frame6, padx=15, pady=10, text="VOLUMEN",fg = "blue",bg = "black") cuadro2.pack(side=TOP) Nivel = Scale(frame6, from_= -20.0, to=0.0,length = 200, orient= HORIZONTAL, resolution=0.1,bg = "black", fg="white") Nivel.pack(side=TOP, padx=1, pady=1) cuadro6= Label(frame6, padx=15, pady=2, text="",fg = "white",bg = "black") cuadro6.pack(side=TOP) GenerarButton1 = Button(frame7, padx=30, pady=2, text="Generar Archivo",bg = "red",fg="white",command=Delay) GenerarButton1.pack(side=LEFT) ReproducirButton1 = Button(frame7, padx=30, pady=2, text="Reproducir",bg = "green",fg="black",command=ReproducirMain ) ReproducirButton1.pack(side=LEFT) NextButton1 = Button(frame7, padx=30, pady=2, text=" Delay 2",bg = "blue",fg="white", command= Ventana2) NextButton1.pack(side=LEFT) ventana.mainloop()
red = "cyan" white = "black" black = "white" else: grey = "light slate grey" green = "green" yellow = "yellow" red = "red" white = "white" black = "black" c_height = 476 #the border lines are approx 2px c_width = 316 #316 root = Tk() root.config(width=(c_width - 45), height=c_height, bg=black) if not testMode: root.config(cursor="none") root.attributes("-fullscreen", True) #if not in test mode switch to fullscreen textFont = tkFont.Font(family="Helvetica", size=36, weight="bold") # Declare Variables measuredItems = [ "RPM", "Water TMP", "Oil Temp", "Oil Press", "EGT", "Fuel Flow", "Fuel(left)", "Voltage" ] errorBoxItems = ["TEMP", "PRESS", "FUEL", "POWER", "ERROR"] errorBoxItemsColor = ["red", "green", "green", "yellow", "green"] measuredItemsColor = [red, green, yellow, green, green, green, green]
class TreeView(object): def __init__(self, *trees): from math import sqrt, ceil self._trees = trees self._top = Tk() self._top.title('NLTK') self._top.bind('<Control-x>', self.destroy) self._top.bind('<Control-q>', self.destroy) cf = self._cframe = CanvasFrame(self._top) self._top.bind('<Control-p>', self._cframe.print_to_file) # Size is variable. self._size = IntVar(self._top) self._size.set(12) bold = ('helvetica', -self._size.get(), 'bold') helv = ('helvetica', -self._size.get()) # Lay the trees out in a square. self._width = int(ceil(sqrt(len(trees)))) self._widgets = [] for i in range(len(trees)): widget = TreeWidget(cf.canvas(), trees[i], node_font=bold, leaf_color='#008040', node_color='#004080', roof_color='#004040', roof_fill='white', line_color='#004040', draggable=1, leaf_font=helv) widget.bind_click_trees(widget.toggle_collapsed) self._widgets.append(widget) cf.add_widget(widget, 0, 0) self._layout() self._cframe.pack(expand=1, fill='both') self._init_menubar() def _layout(self): i = x = y = ymax = 0 width = self._width for i in range(len(self._widgets)): widget = self._widgets[i] (oldx, oldy) = widget.bbox()[:2] if i % width == 0: y = ymax x = 0 widget.move(x-oldx, y-oldy) x = widget.bbox()[2] + 10 ymax = max(ymax, widget.bbox()[3] + 10) def _init_menubar(self): menubar = Menu(self._top) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='Print to Postscript', underline=0, command=self._cframe.print_to_file, accelerator='Ctrl-p') filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) zoommenu = Menu(menubar, tearoff=0) zoommenu.add_radiobutton(label='Tiny', variable=self._size, underline=0, value=10, command=self.resize) zoommenu.add_radiobutton(label='Small', variable=self._size, underline=0, value=12, command=self.resize) zoommenu.add_radiobutton(label='Medium', variable=self._size, underline=0, value=14, command=self.resize) zoommenu.add_radiobutton(label='Large', variable=self._size, underline=0, value=28, command=self.resize) zoommenu.add_radiobutton(label='Huge', variable=self._size, underline=0, value=50, command=self.resize) menubar.add_cascade(label='Zoom', underline=0, menu=zoommenu) self._top.config(menu=menubar) def resize(self, *e): bold = ('helvetica', -self._size.get(), 'bold') helv = ('helvetica', -self._size.get()) xspace = self._size.get() yspace = self._size.get() for widget in self._widgets: widget['node_font'] = bold widget['leaf_font'] = helv widget['xspace'] = xspace widget['yspace'] = yspace if self._size.get() < 20: widget['line_width'] = 1 elif self._size.get() < 30: widget['line_width'] = 2 else: widget['line_width'] = 3 self._layout() def destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def mainloop(self, *args, **kwargs): """ Enter the Tkinter mainloop. This function must be called if this demo is created from a non-interactive program (e.g. from a secript); otherwise, the demo will close as soon as the script completes. """ if in_idle(): return self._top.mainloop(*args, **kwargs)
class TkView(object): ''' TkView represents a window container for components ''' def __init__(self): ''' Constructor: Excepts no arguments ''' self.die = Die(6) self.root = Tk() self.root.wm_title(APP_NAME) self.root.resizable(False, False) self.set_up_menu() self.set_up_labels() self.set_up_entries_and_buttons() def set_up_menu(self): ''' Sets up the menu bar and its submenus ''' menubar = Menu(self.root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="About", command=self.about) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.root.quit) menubar.add_cascade(label="File", menu=filemenu) self.root.config(menu=menubar) def set_up_labels(self): ''' Sets up the text labels for components ''' Label(self.root, text="Sides ").grid() Label(self.root, text="Mod ").grid(row=1) Label(self.root, text="Result :").grid(row=2) self.result = Label(self.root, text="~") self.result.grid(row=2, column=1, sticky=W) def set_up_entries_and_buttons(self): ''' Sets up entries and buttons the user interacts with ''' self.sides = Entry(self.root) self.sides.grid(row=0, column=1, sticky=W) self.sides.insert(0, "6") self.mod = Entry(self.root) self.mod.grid(row=1, column=1, sticky=W) self.mod.insert(0, "0") Button(self.root, text="Roll ", command=self.roll).grid(row=0, column=2, rowspan=3, sticky=(N, S)) def run(self): ''' Begins the main GUI loop ''' self.root.mainloop() def about(self): ''' Displays a pop up about the author and contact information ''' new_pop_up(APP_NAME, "PyRoller: a simple die roller\n\n" + "Wrote by Corey Prophitt <*****@*****.**>") def roll(self): ''' Rolls the die and sets the result ''' # Avoid user entering blank values if self.sides.get() != '': # Only re-instantiate die if the side has changed if self.die.face != int(self.sides.get()): self.die = Die(int(self.sides.get())) text_ = str(self.die.roll()) + " + " # Only use mod entry if sides is defined and mod isn't blank if self.mod.get() != '': text_ += str(int(self.mod.get())) text_ += " = " + str(self.die.face+int(self.mod.get())) else: text_ += str(0) + " = " + str(self.die.face) else: text_ = 0 self.result.config(text=text_)
class GUI: def __init__(self, depth): self.depth = depth self._init_app() self._init_ai() self.update() def _init_app(self): self.app = Tk() self.app.title('Connect4') self.app.resizable(width=False, height=False) self.board = Board() self.buttons = {} self.frame = Frame(self.app, borderwidth=1, relief="raised") self.tiles = {} for x in range(self.board.width): handler = lambda x=x: self.move(x) button = Button(self.app, command=handler, font=Font(family="Helvetica", size=14), text=x+1) button.grid(row=0, column=x, sticky="WE") self.buttons[x] = button self.frame.grid(row=1, column=0, columnspan=self.board.width) for x,y in self.board.fields: tile = Canvas(self.frame, width=60, height=50, bg="navy", highlightthickness=0) tile.grid(row=self.board.height-1-y, column=x) self.tiles[x,y] = tile handler = lambda: self.reset() self.restart = Button(self.app, command=handler, text='reset') self.restart.grid(row=2, column=0, columnspan=self.board.width, sticky="WE") def _init_ai(self): ai_path = os.path.join(os.path.dirname(__file__), 'conn4.pl') # for widnows: self.ai = subprocess.Popen([r"C:\Program Files\swipl\bin\swipl.exe", ai_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE) print(ai_path) self.ai = subprocess.Popen(["swipl", ai_path, str(self.depth)], stdin=subprocess.PIPE, stdout=subprocess.PIPE) def reset(self): self.ai.terminate() self._init_ai() self.board = Board() self.update() def move(self,x): self.app.config(cursor="watch") self.app.update() try: # me self.ai.stdin.write(str(x + 1) + '\n') print self.ai.stdout.readline().strip() self.board = self.board.move(x) if self.update(): return # him self.ai.stdin.write('0\n') y = self.ai.stdout.readline().strip() self.board = self.board.move(int(y[3]) - 1) self.update() print y finally: self.app.config(cursor="") def update(self): for (x,y) in self.board.fields: text = self.board.fields[x,y] if (text=='.'): self.tiles[x,y].create_oval(10, 5, 50, 45, fill="black", outline="blue", width=1) if (text=='X'): self.tiles[x,y].create_oval(10, 5, 50, 45, fill="yellow", outline="blue", width=1) if (text=='O'): self.tiles[x,y].create_oval(10, 5, 50, 45, fill="red", outline="blue", width=1) for x in range(self.board.width): if self.board.fields[x,self.board.height-1]==self.board.empty: self.buttons[x]['state'] = 'normal' else: self.buttons[x]['state'] = 'disabled' winning = self.board.won() if winning: self.ai.terminate() for x,y in winning: self.tiles[x,y].create_oval(25, 20, 35, 30, fill="black") for x in range(self.board.width): self.buttons[x]['state'] = 'disabled' return winning def mainloop(self): self.app.mainloop()
def main(): Frecuenciadesampleo = 44100 MaxBits = 16 # Creacion de la ventana ventana = Tk() ventana.title("Ventana Principal") ventana.config(bg = "black") d = BooleanVar(ventana) e = BooleanVar(ventana) e.set(False) f = BooleanVar(ventana) f.set(False) global arreglo1 arreglo1 = [] # Uso de frames para organizar la ventana. frame1 = Frame(ventana,bg = "black") frame1.pack(side=TOP) frame2 = Frame(ventana,bg = "black") frame2.pack(side=TOP) frame3 = Frame(ventana,bg = "black") frame3.pack(side=TOP) frame4 = Frame(ventana,bg = "black") frame4.pack(side=TOP) frame5 = Frame(ventana,bg = "black") frame5.pack(side=TOP) def AbrirArchivo1(): d.set(True) Abrir1() mensaje1.pack(side=LEFT) ReproButton1.pack(side=LEFT) def AbrirArchivo2(): d.set(True) Abrir2() mensaje2.pack(side=LEFT) ReproButton2.pack(side=LEFT) def AbrirArchivo3(): d.set(True) Abrir3() mensaje3.pack(side=LEFT) ReproButton3.pack(side=LEFT) def AbrirArchivo4(): d.set(True) Abrir4() mensaje4.pack(side=LEFT) ReproButton4.pack(side=LEFT) def Reproducir1(): d.set(True) reproduce1() def Reproducir2(): d.set(True) reproduce2() def Reproducir3(): d.set(True) reproduce3() def Reproducir4(): d.set(True) reproduce4() def ReproducirMain(): d.set(True) reproduce() # Creacion de botones. Titulo = Label(frame1, fg='red', padx=15, pady=10, text='Mixer Reproductor',bg = "black") Titulo.pack(side=TOP) Titulo1 = Label(frame1, fg='red', padx=15, pady=10, text='Luis Sandoval, Andres Palacio, Libardo Montealegre',bg = "black") Titulo1.pack(side=TOP) OpenButton1 = Button(frame1, padx=30, pady=2, text="Abrir Archivo 1", command=AbrirArchivo1,bg = "blue",fg="white") OpenButton1.pack(side=LEFT) OpenButton2 = Button(frame2, padx=30, pady=2, text="Abrir Archivo 2", command=AbrirArchivo2,bg = "blue",fg="white") OpenButton2.pack(side=LEFT) OpenButton3 = Button(frame3, padx=30, pady=2, text="Abrir Archivo 3", command=AbrirArchivo3,bg = "blue",fg="white") OpenButton3.pack(side=LEFT) OpenButton4 = Button(frame4, padx=30, pady=2, text="Abrir Archivo 4", command=AbrirArchivo4,bg = "blue",fg="white") OpenButton4.pack(side=LEFT) # Mensajes de grabacion activada. mensaje1 = Label(frame1, fg='green', padx=15, pady=10, text='Archivo 1 Cargado',bg = "black") mensaje2 = Label(frame2, fg='green', padx=15, pady=10, text='Archivo 2 Cargado',bg = "black") mensaje3 = Label(frame3, fg='green', padx=15, pady=10, text='Archivo 3 Cargado',bg = "black") mensaje4 = Label(frame4, fg='green', padx=15, pady=10, text='Archivo 4 Cargado',bg = "black") ReproButton1 = Button(frame1, padx=30, pady=2, text="Reproducir Archivo 1", command=Reproducir1,bg = "green",fg="black") ReproButton2 = Button(frame2, padx=30, pady=2, text="Reproducir Archivo 2", command=Reproducir2,bg = "green",fg="black") ReproButton3 = Button(frame3, padx=30, pady=2, text="Reproducir Archivo 3", command=Reproducir3,bg = "green",fg="black") ReproButton4 = Button(frame4, padx=30, pady=2, text="Reproducir Archivo 3", command=Reproducir4,bg = "green",fg="black") # Creacion e insercion del cuadro de texto 1. ReproMainButton1 = Button(frame5, padx=30, pady=2, text="Reproducir Mezcla",bg = "green",fg="black", command=ReproducirMain) ReproMainButton1.pack(side=TOP) ventana.mainloop()
class OSCRemote(object): def __init__(self): self.editor_issue = "1.3" # get command options self.command_options = remote_options() # get directory holding the code self.pp_dir = sys.path[0] if not os.path.exists(self.pp_dir + os.sep + "pp_oscremote.py"): tkMessageBox.showwarning("Pi Presents", "Bad Application Directory") exit() # Initialise logging Monitor.log_path = self.pp_dir self.mon = Monitor() self.mon.init() Monitor.classes = ['OSCRemote', 'OSCConfig', 'OSCEditor'] Monitor.log_level = int(self.command_options['debug']) self.mon.log(self, "Pi Presents Remote is starting") self.mon.log(self, " OS and separator " + os.name + ' ' + os.sep) self.mon.log(self, "sys.path[0] - location of code: code " + sys.path[0]) self.setup_gui() # OSC config class self.osc_config = OSCConfig() self.init() #and start the system self.root.after(1000, self.run_app) self.root.mainloop() def init(self): self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg' self.read_create_osc() self.pp_home_dir = self.osc_config.pp_home_dir self.pp_profiles_offset = self.osc_config.pp_profiles_offset self.mon.log(self, "Data Home from options is " + self.pp_home_dir) self.mon.log( self, "Current Profiles Offset from options is " + self.pp_profiles_offset) self.pp_profile_dir = '' self.current_showlist = None self.current_show = None self.current_show_ref = '' self.shows_display.delete(0, END) self.results.set('') def add_status(self, text): self.status_display.insert(END, text + '\n') self.status_display.see(END) def run_app(self): self.client = None self.server = None self.st = None # initialise OSC variables self.prefix = '/pipresents' self.this_unit = '/' + self.osc_config.this_unit_name self.add_status('this unit is: ' + self.this_unit) self.controlled_unit = '/' + self.osc_config.controlled_unit_1_name self.add_status('controlled unit is: ' + self.controlled_unit) #connect client then start server to listen for replies self.init_client() self.add_status('connecting to controlled unit: ' + self.osc_config.controlled_unit_1_ip + ':' + self.osc_config.controlled_unit_1_port + ' ' + self.osc_config.controlled_unit_1_name) self.connect_client(self.osc_config.controlled_unit_1_ip, self.osc_config.controlled_unit_1_port) self.add_status('listening for replies on:' + self.osc_config.this_unit_ip + ':' + self.osc_config.this_unit_port) self.init_server(self.osc_config.this_unit_ip, self.osc_config.this_unit_port, self.client) self.add_initial_handlers() self.start_server() # *************************************** # RESPOND TO BUTTONS # *************************************** def open_show(self): self.msg_path = '/core/open ' self.msg_arg_text = self.current_show_ref self.display_msg_text() def close_show(self): self.msg_path = '/core/close ' self.msg_arg_text = self.current_show_ref self.display_msg_text() def exit_pipresents(self): self.msg_path = '/core/exitpipresents' self.msg_arg_text = '' self.display_msg_text() def play_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-play' self.display_msg_text() def pause_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-pause' self.display_msg_text() pass def stop_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-stop' self.display_msg_text() pass def up_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-up' self.display_msg_text() def down_event(self): self.msg_path = '/core/event' self.msg_arg_text = 'pp-down' self.display_msg_text() def output(self): self.msg_path = '/core/output' self.msg_arg_text = '' self.display_msg_text() def loopback(self): self.msg_path = '/system/loopback' self.msg_arg_text = '' self.display_msg_text() def server_info(self): self.msg_path = '/system/server-info' self.msg_arg_text = '' self.display_msg_text() # and put the created text in the results box in the gui def display_msg_text(self): self.results.set(self.prefix + self.controlled_unit + self.msg_path + ' ' + self.msg_arg_text) #calback from the Send button # parses the message string into fields and sends - NO error checking def send_message(self): msg_text = self.results.get() self.add_status('Send message:' + msg_text) self.mon.log(self, 'send message: ' + msg_text) fields = msg_text.split() address = fields[0] arg_list = fields[1:] self.send(address, arg_list) # *************************************** # OSC CLIENT TO SEND MESSAGES # *************************************** def init_client(self): self.client = OSC.OSCClient() def connect_client(self, ip, port): self.mon.log(self, 'connect to: ' + ip + ':' + str(port)) self.client.connect((ip, int(port))) def send(self, address, arg_list): msg = OSC.OSCMessage() msg.setAddress(address) for arg in arg_list: msg.append(arg) self.client.send(msg) def disconnect_client(self): self.client.close() return # *************************************** # OSC SERVER TO LISTEN TO REPLIES # *************************************** def init_server(self, ip, port_text, client): self.mon.log(self, 'Start Server: ' + ip + ':' + port_text) self.server = OSC.OSCServer((ip, int(port_text)), client) def start_server(self): self.st = threading.Thread(target=self.server.serve_forever) self.st.start() def close_server(self): if self.server != None: self.server.close() self.mon.log(self, 'Waiting for Server-thread to finish') if self.st != None: self.st.join() ##!!! self.mon.log(self, 'server thread closed') def add_initial_handlers(self): self.server.addMsgHandler('default', self.no_match_handler) self.server.addMsgHandler( self.prefix + self.this_unit + "/system/loopback-reply", self.loopback_reply_handler) self.server.addMsgHandler( self.prefix + self.this_unit + "/system/server-info-reply", self.server_info_reply_handler) def no_match_handler(self, addr, tags, stuff, source): text = '' text += "no match for new osc msg from %s" % OSC.getUrlStr( source) + '\n' text += "with addr : %s" % addr + '\n' text += "typetags %s" % tags + '\n' text += "data %s" % stuff + '\n' self.add_status(text + '\n') def loopback_reply_handler(self, addr, tags, stuff, source): self.add_status('Loopback reply received from: ' + self.pretty_list(source)) def server_info_reply_handler(self, addr, tags, stuff, source): self.add_status('Server Information from: ' + self.pretty_list(source) + '\n ' + self.pretty_list(stuff)) def pretty_list(self, fields): text = ' ' for field in fields: text += str(field) + ' ' return text # *************************************** # INIT EXIT MISC # *************************************** def e_edit_osc(self): self.disconnect_client() self.close_server() self.edit_osc() self.init() self.add_status('\n\n\nRESTART') self.run_app() def app_exit(self): self.disconnect_client() self.close_server() if self.root is not None: self.root.destroy() self.mon.finish() sys.exit() def show_help(self): tkMessageBox.showinfo("Help", "Read 'manual.pdf'") def about(self): tkMessageBox.showinfo( "About", "Simple Remote Control for Pi Presents\n" + "Author: Ken Thompson" + "\nWebsite: http://pipresents.wordpress.com/") def setup_gui(self): # set up the gui # root is the Tkinter root widget self.root = Tk() self.root.title("Remote Control for Pi Presents") # self.root.configure(background='grey') self.root.resizable(False, False) # define response to main window closing self.root.protocol("WM_DELETE_WINDOW", self.app_exit) # bind some display fields self.filename = StringVar() self.display_show = StringVar() self.results = StringVar() self.status = StringVar() # define menu menubar = Menu(self.root) profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black") profilemenu.add_command(label='Select', command=self.open_existing_profile) menubar.add_cascade(label='Profile', menu=profilemenu) toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Tools', menu=toolsmenu) osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='OSC', menu=osc_configmenu) osc_configmenu.add_command(label='Edit', command=self.e_edit_osc) helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black") menubar.add_cascade(label='Help', menu=helpmenu) helpmenu.add_command(label='Help', command=self.show_help) helpmenu.add_command(label='About', command=self.about) self.root.config(menu=menubar) #top frame top_frame = Frame(self.root, padx=5, pady=5) top_frame.pack(side=TOP) results_label = Label(top_frame, text="Message to Send", font="arial 12 bold") results_label.pack(side=LEFT) results_display = Entry(top_frame, textvariable=self.results, width=70) results_display.pack(side=LEFT, fill=BOTH, expand=1) send_button = Button(top_frame, width=5, height=1, text='Send', fg='black', command=self.send_message, bg="light grey") send_button.pack(side=RIGHT) #bottom frame bottom_frame = Frame(self.root, padx=5, pady=5) bottom_frame.pack(side=TOP, fill=BOTH, expand=1) left_frame = Frame(bottom_frame, padx=5) left_frame.pack(side=LEFT) right_frame = Frame(bottom_frame, padx=5, pady=5) right_frame.pack(side=LEFT) suplabel_frame = Frame(right_frame, pady=5) suplabel_frame.pack(side=TOP) commands_label = Label(suplabel_frame, text="Show Control", font="arial 12 bold") commands_label.pack() supervisor_frame = Frame(right_frame, pady=5) supervisor_frame.pack(side=TOP) # supervisor buttons add_button = Button(supervisor_frame, width=5, height=1, text='Open\nShow', fg='black', command=self.open_show, bg="light grey") add_button.pack(side=LEFT) add_button = Button(supervisor_frame, width=5, height=1, text='Close\nShow', fg='black', command=self.close_show, bg="light grey") add_button.pack(side=LEFT) add_button = Button(supervisor_frame, width=10, height=1, text='Exit\nPi Presents', fg='black', command=self.exit_pipresents, bg="light grey") add_button.pack(side=LEFT) # events buttons oplabel_frame = Frame(right_frame, pady=5) oplabel_frame.pack(side=TOP) operations_label = Label(oplabel_frame, text="Input Events", font="arial 12 bold") operations_label.pack() operations_frame = Frame(right_frame, pady=5) operations_frame.pack(side=TOP) add_button = Button(operations_frame, width=5, height=1, text='Play', fg='black', command=self.play_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Pause', fg='black', command=self.pause_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Stop', fg='black', command=self.stop_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Up', fg='black', command=self.up_event, bg="light grey") add_button.pack(side=LEFT) add_button = Button(operations_frame, width=5, height=1, text='Down', fg='black', command=self.down_event, bg="light grey") add_button.pack(side=LEFT) # animate buttons animate_frame = Frame(right_frame, pady=5) animate_frame.pack(side=TOP) animate_label = Label(animate_frame, text="Control Outputs", font="arial 12 bold") animate_label.pack() animate_frame = Frame(right_frame, pady=5) animate_frame.pack(side=TOP) add_button = Button(animate_frame, width=5, height=1, text='Output', fg='black', command=self.output, bg="light grey") add_button.pack(side=LEFT) # system buttons systemlabel_frame = Frame(right_frame, pady=5) systemlabel_frame.pack(side=TOP) system_label = Label(systemlabel_frame, text="System", font="arial 12 bold") system_label.pack() system_frame = Frame(right_frame, pady=5) system_frame.pack(side=TOP) add_button = Button(system_frame, width=5, height=1, text='Loopback', fg='black', command=self.loopback, bg="light grey") add_button.pack(side=LEFT) add_button = Button(system_frame, width=10, height=1, text='Server Info', fg='black', command=self.server_info, bg="light grey") add_button.pack(side=LEFT) # define display of showlist shows_title_frame = Frame(left_frame) shows_title_frame.pack(side=TOP) shows_label = Label(shows_title_frame, text="Shows") shows_label.pack() shows_frame = Frame(left_frame) shows_frame.pack(side=TOP) scrollbar = Scrollbar(shows_frame, orient=VERTICAL) self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=12, width=40, bg="white", activestyle=NONE, fg="black", yscrollcommand=scrollbar.set) scrollbar.config(command=self.shows_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.shows_display.pack(side=LEFT, fill=BOTH, expand=1) self.shows_display.bind("<ButtonRelease-1>", self.e_select_show) # status_frame status_frame = Frame(self.root, padx=5, pady=5) status_frame.pack(side=TOP, fill=BOTH, expand=1) status_label = Label(status_frame, text="Status", font="arial 12 bold") status_label.pack(side=LEFT) scrollbar = Scrollbar(status_frame, orient=VERTICAL) self.status_display = Text(status_frame, height=10, yscrollcommand=scrollbar.set) scrollbar.config(command=self.status_display.yview) scrollbar.pack(side=RIGHT, fill=Y) self.status_display.pack(side=LEFT, fill=BOTH, expand=1) # *************************************** # SHOWLIST # *************************************** def open_existing_profile(self): initial_dir = self.pp_home_dir + os.sep + "pp_profiles" + self.pp_profiles_offset if os.path.exists(initial_dir) is False: self.mon.err( self, "Profiles directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home") return dir_path = tkFileDialog.askdirectory(initialdir=initial_dir) # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt" if len(dir_path) > 0: self.open_profile(dir_path) def open_profile(self, dir_path): showlist_file = dir_path + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err( self, "Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?") return self.pp_profile_dir = dir_path self.root.title("Remote for Pi Presents - " + self.pp_profile_dir) self.open_showlist(self.pp_profile_dir) def open_showlist(self, profile_dir): showlist_file = profile_dir + os.sep + "pp_showlist.json" if os.path.exists(showlist_file) is False: self.mon.err( self, "showlist file not found at " + profile_dir + "\n\nHint: Have you opened the profile directory?") self.app_exit() self.current_showlist = ShowList() self.current_showlist.open_json(showlist_file) if float(self.current_showlist.sissue()) != float(self.editor_issue): self.mon.err( self, "Version of profile does not match Remote: " + self.editor_issue) self.app_exit() self.refresh_shows_display() def refresh_shows_display(self): self.shows_display.delete(0, self.shows_display.size()) for index in range(self.current_showlist.length()): self.shows_display.insert( END, self.current_showlist.show(index)['title'] + " [" + self.current_showlist.show(index)['show-ref'] + "]") if self.current_showlist.show_is_selected(): self.shows_display.itemconfig( self.current_showlist.selected_show_index(), fg='red') self.shows_display.see(self.current_showlist.selected_show_index()) def e_select_show(self, event): print 'select show', self.current_showlist.length() if self.current_showlist is not None and self.current_showlist.length( ) > 0: mouse_item_index = int(event.widget.curselection()[0]) self.current_showlist.select(mouse_item_index) self.current_show_ref = self.current_showlist.selected_show( )['show-ref'] self.refresh_shows_display() else: self.current_show_ref = '' # *************************************** # OSC CONFIGURATION # *************************************** def read_create_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file, 'remote', 'Create OSC Remote Configuration') self.osc_config.read(self.osc_config_file) def edit_osc(self): if self.osc_config.read(self.osc_config_file) is False: self.osc_config.create(self.osc_config_file) eosc = OSCEditor(self.root, self.osc_config_file, 'remote', 'Edit OSC Reomote Configuration')
class PiPresents(object): def pipresents_version(self): vitems=self.pipresents_issue.split('.') if len(vitems)==2: # cope with 2 digit version numbers before 1.3.2 return 1000*int(vitems[0])+100*int(vitems[1]) else: return 1000*int(vitems[0])+100*int(vitems[1])+int(vitems[2]) def __init__(self): # gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL) gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_SAVEALL) self.pipresents_issue="1.3.5" self.pipresents_minorissue = '1.3.5d' # position and size of window without -f command line option self.nonfull_window_width = 0.45 # proportion of width self.nonfull_window_height= 0.7 # proportion of height self.nonfull_window_x = 0 # position of top left corner self.nonfull_window_y=0 # position of top left corner StopWatch.global_enable=False # set up the handler for SIGTERM signal.signal(signal.SIGTERM,self.handle_sigterm) # **************************************** # Initialisation # *************************************** # get command line options self.options=command_options() # get Pi Presents code directory pp_dir=sys.path[0] self.pp_dir=pp_dir if not os.path.exists(pp_dir+"/pipresents.py"): if self.options['manager'] is False: tkMessageBox.showwarning("Pi Presents","Bad Application Directory") exit(102) # Initialise logging and tracing Monitor.log_path=pp_dir self.mon=Monitor() # Init in PiPresents only self.mon.init() # uncomment to enable control of logging from within a class # Monitor.enable_in_code = True # enables control of log level in the code for a class - self.mon.set_log_level() # make a shorter list to log/trace only some classes without using enable_in_code. Monitor.classes = ['PiPresents', 'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow', 'GapShow','Show','ArtShow', 'AudioPlayer','BrowserPlayer','ImagePlayer','MenuPlayer','MessagePlayer','VideoPlayer','Player', 'MediaList','LiveList','ShowList', 'PathManager','ControlsManager','ShowManager','PluginManager','IOPluginManager', 'MplayerDriver','OMXDriver','UZBLDriver', 'TimeOfDay','ScreenDriver','Animate','OSCDriver','CounterManager', 'Network','Mailer' ] # Monitor.classes=['PiPresents','MediaShow','GapShow','Show','VideoPlayer','Player','OMXDriver'] # Monitor.classes=['OSCDriver'] # get global log level from command line Monitor.log_level = int(self.options['debug']) Monitor.manager = self.options['manager'] # print self.options['manager'] self.mon.newline(3) self.mon.sched (self,None, "Pi Presents is starting, Version:"+self.pipresents_minorissue + ' at '+time.strftime("%Y-%m-%d %H:%M.%S")) self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue+ ' at '+time.strftime("%Y-%m-%d %H:%M.%S")) # self.mon.log (self," OS and separator:" + os.name +' ' + os.sep) self.mon.log(self,"sys.path[0] - location of code: "+sys.path[0]) # log versions of Raspbian and omxplayer, and GPU Memory with open("/boot/issue.txt") as ifile: self.mon.log(self,'\nRaspbian: '+ifile.read()) self.mon.log(self,'\n'+check_output(["omxplayer", "-v"])) self.mon.log(self,'\nGPU Memory: '+check_output(["vcgencmd", "get_mem", "gpu"])) if os.geteuid() == 0: print 'Do not run Pi Presents with sudo' self.mon.log(self,'Do not run Pi Presents with sudo') self.mon.finish() sys.exit(102) if "DESKTOP_SESSION" not in os.environ: print 'Pi Presents must be run from the Desktop' self.mon.log(self,'Pi Presents must be run from the Desktop') self.mon.finish() sys.exit(102) else: self.mon.log(self,'Desktop is '+ os.environ['DESKTOP_SESSION']) # optional other classes used self.root=None self.ppio=None self.tod=None self.animate=None self.ioplugin_manager=None self.oscdriver=None self.osc_enabled=False self.tod_enabled=False self.email_enabled=False user=os.getenv('USER') if user is None: tkMessageBox.showwarning("You must be logged in to run Pi Presents") exit(102) if user !='pi': self.mon.warn(self,"You must be logged as pi to use GPIO") self.mon.log(self,'User is: '+ user) # self.mon.log(self,"os.getenv('HOME') - user home directory (not used): " + os.getenv('HOME')) # does not work # self.mon.log(self,"os.path.expanduser('~') - user home directory: " + os.path.expanduser('~')) # does not work # check network is available self.network_connected=False self.network_details=False self.interface='' self.ip='' self.unit='' # sets self.network_connected and self.network_details self.init_network() # start the mailer and send email when PP starts self.email_enabled=False if self.network_connected is True: self.init_mailer() if self.email_enabled is True and self.mailer.email_at_start is True: subject= '[Pi Presents] ' + self.unit + ': PP Started on ' + time.strftime("%Y-%m-%d %H:%M") message = time.strftime("%Y-%m-%d %H:%M") + '\nUnit: ' + self.unit + ' Profile: '+ self.options['profile']+ '\n ' + self.interface + '\n ' + self.ip self.send_email('start',subject,message) # get profile path from -p option if self.options['profile'] != '': self.pp_profile_path="/pp_profiles/"+self.options['profile'] else: self.mon.err(self,"Profile not specified in command ") self.end('error','Profile not specified with the commands -p option') # get directory containing pp_home from the command, if self.options['home'] == "": home = os.sep+ 'home' + os.sep + user + os.sep+"pp_home" else: home = self.options['home'] + os.sep+ "pp_home" self.mon.log(self,"pp_home directory is: " + home) # check if pp_home exists. # try for 10 seconds to allow usb stick to automount found=False for i in range (1, 10): self.mon.log(self,"Trying pp_home at: " + home + " (" + str(i)+')') if os.path.exists(home): found=True self.pp_home=home break time.sleep (1) if found is True: self.mon.log(self,"Found Requested Home Directory, using pp_home at: " + home) else: self.mon.err(self,"Failed to find pp_home directory at " + home) self.end('error',"Failed to find pp_home directory at " + home) # check profile exists self.pp_profile=self.pp_home+self.pp_profile_path if os.path.exists(self.pp_profile): self.mon.sched(self,None,"Running profile: " + self.pp_profile_path) self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile) else: self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile) self.end('error',"Failed to find requested profile: "+ self.pp_profile) self.mon.start_stats(self.options['profile']) if self.options['verify'] is True: self.mon.err(self,"Validation option not supported - use the editor") self.end('error','Validation option not supported - use the editor') # initialise and read the showlist in the profile self.showlist=ShowList() self.showlist_file= self.pp_profile+ "/pp_showlist.json" if os.path.exists(self.showlist_file): self.showlist.open_json(self.showlist_file) else: self.mon.err(self,"showlist not found at "+self.showlist_file) self.end('error',"showlist not found at "+self.showlist_file) # check profile and Pi Presents issues are compatible if self.showlist.profile_version() != self.pipresents_version(): self.mon.err(self,"Version of showlist " + self.showlist.profile_version_string + " is not same as Pi Presents") self.end('error',"Version of showlist " + self.showlist.profile_version_string + " is not same as Pi Presents") # get the 'start' show from the showlist index = self.showlist.index_of_start_show() if index >=0: self.showlist.select(index) self.starter_show=self.showlist.selected_show() else: self.mon.err(self,"Show [start] not found in showlist") self.end('error',"Show [start] not found in showlist") # ******************** # SET UP THE GUI # ******************** # turn off the screenblanking and saver if self.options['noblank'] is True: call(["xset","s", "off"]) call(["xset","s", "-dpms"]) self.root=Tk() self.title='Pi Presents - '+ self.pp_profile self.icon_text= 'Pi Presents' self.root.title(self.title) self.root.iconname(self.icon_text) self.root.config(bg=self.starter_show['background-colour']) self.mon.log(self, 'monitor screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixels') if self.options['screensize'] =='': self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight() else: reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize']) if reason =='error': self.mon.err(self,message) self.end('error',message) self.mon.log(self, 'forced screen dimensions (--screensize) are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixels') # set window dimensions and decorations if self.options['fullscreen'] is False: self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width) self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height) self.window_x=self.nonfull_window_x self.window_y=self.nonfull_window_y self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) else: self.window_width=self.screen_width self.window_height=self.screen_height self.root.attributes('-fullscreen', True) os.system('unclutter &') self.window_x=0 self.window_y=0 self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y)) self.root.attributes('-zoomed','1') # canvas cover the whole screen whatever the size of the window. self.canvas_height=self.screen_height self.canvas_width=self.screen_width # make sure focus is set. self.root.focus_set() # define response to main window closing. self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort) # setup a canvas onto which will be drawn the images or text self.canvas = Canvas(self.root, bg=self.starter_show['background-colour']) if self.options['fullscreen'] is True: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=0) else: self.canvas.config(height=self.canvas_height, width=self.canvas_width, highlightthickness=1, highlightcolor='yellow') self.canvas.place(x=0,y=0) # self.canvas.config(bg='black') self.canvas.focus_set() # **************************************** # INITIALISE THE TOUCHSCREEN DRIVER # **************************************** # each driver takes a set of inputs, binds them to symboic names # and sets up a callback which returns the symbolic name when an input event occurs self.sr=ScreenDriver() # read the screen click area config file reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile) if reason == 'error': self.end('error','cannot find, or error in screen.cfg') # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes # click areas are made on the Pi Presents canvas not the show canvases. reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event) if reason == 'error': self.mon.err(self,message) self.end('error',message) # **************************************** # INITIALISE THE APPLICATION AND START # **************************************** self.shutdown_required=False self.reboot_required=False self.terminate_required=False self.exitpipresents_required=False # initialise the I/O plugins by importing their drivers self.ioplugin_manager=IOPluginManager() reason,message=self.ioplugin_manager.init(self.pp_dir,self.pp_profile,self.root,self.handle_input_event) if reason == 'error': # self.mon.err(self,message) self.end('error',message) # kick off animation sequencer self.animate = Animate() self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event) self.animate.poll() #create a showmanager ready for time of day scheduler and osc server show_id=-1 self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home) # first time through set callback to terminate Pi Presents if all shows have ended. self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist) # Register all the shows in the showlist reason,message=self.show_manager.register_shows() if reason == 'error': self.mon.err(self,message) self.end('error',message) # Init OSCDriver, read config and start OSC server self.osc_enabled=False if self.network_connected is True: if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'): self.oscdriver=OSCDriver() reason,message=self.oscdriver.init(self.pp_profile, self.unit,self.interface,self.ip, self.handle_command,self.handle_input_event,self.e_osc_handle_animate) if reason == 'error': self.mon.err(self,message) self.end('error',message) else: self.osc_enabled=True self.root.after(1000,self.oscdriver.start_server()) # initialise ToD scheduler calculating schedule for today self.tod=TimeOfDay() reason,message,self.tod_enabled = self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.showlist,self.root,self.handle_command) if reason == 'error': self.mon.err(self,message) self.end('error',message) # warn if the network not available when ToD required if self.tod_enabled is True and self.network_connected is False: self.mon.warn(self,'Network not connected so Time of Day scheduler may be using the internal clock') # init the counter manager self.counter_manager=CounterManager() self.counter_manager.init() # warn about start shows and scheduler if self.starter_show['start-show']=='' and self.tod_enabled is False: self.mon.sched(self,None,"No Start Shows in Start Show and no shows scheduled") self.mon.warn(self,"No Start Shows in Start Show and no shows scheduled") if self.starter_show['start-show'] !='' and self.tod_enabled is True: self.mon.sched(self,None,"Start Shows in Start Show and shows scheduled - conflict?") self.mon.warn(self,"Start Shows in Start Show and shows scheduled - conflict?") # run the start shows self.run_start_shows() # kick off the time of day scheduler which may run additional shows if self.tod_enabled is True: self.tod.poll() # start the I/O plugins input event generation self.ioplugin_manager.start() # start Tkinters event loop self.root.mainloop( ) def parse_screen(self,size_text): fields=size_text.split('*') if len(fields)!=2: return 'error','do not understand --screensize comand option',0,0 elif fields[0].isdigit() is False or fields[1].isdigit() is False: return 'error','dimensions are not positive integers in --screensize',0,0 else: return 'normal','',int(fields[0]),int(fields[1]) # ********************* # RUN START SHOWS # ******************** def run_start_shows(self): self.mon.trace(self,'run start shows') # parse the start shows field and start the initial shows show_refs=self.starter_show['start-show'].split() for show_ref in show_refs: reason,message=self.show_manager.control_a_show(show_ref,'open') if reason == 'error': self.mon.err(self,message) # ********************* # User inputs # ******************** def e_osc_handle_animate(self,line): #jump out of server thread self.root.after(1, lambda arg=line: self.osc_handle_animate(arg)) def osc_handle_animate(self,line): self.mon.log(self,"animate command received: "+ line) #osc sends output events as a string reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line) if reason == 'error': self.mon.err(self,message) self.end(reason,message) self.handle_output_event(name,param_type,param_values,0) # output events are animate commands def handle_output_event(self,symbol,param_type,param_values,req_time): reason,message=self.ioplugin_manager.handle_output_event(symbol,param_type,param_values,req_time) if reason =='error': self.mon.err(self,message) self.end(reason,message) # all input events call this callback providing a symbolic name. # handle events that affect PP overall, otherwise pass to all active shows def handle_input_event(self,symbol,source): self.mon.log(self,"event received: "+symbol + ' from '+ source) if symbol == 'pp-terminate': self.handle_user_abort() elif symbol == 'pp-shutdown': self.mon.err(self,'pp-shutdown removed in version 1.3.3a, see Release Notes') self.end('error','pp-shutdown removed in version 1.3.3a, see Release Notes') elif symbol == 'pp-shutdownnow': # need root.after to grt out of st thread self.root.after(1,self.shutdownnow_pressed) return elif symbol == 'pp-exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to grt out of st thread self.root.after(1,self.e_all_shows_ended_callback) return reason,message= self.show_manager.exit_all_shows() else: # pass the input event to all registered shows for show in self.show_manager.shows: show_obj=show[ShowManager.SHOW_OBJ] if show_obj is not None: show_obj.handle_input_event(symbol) # commands are generaed by tracks and shows # they can open or close shows, generate input events and do special tasks # commands also generate osc outputs to other computers # handles one command provided as a line of text def handle_command(self,command_text,source='',show=''): # print 'PIPRESENTS ',command_text,'\n Source',source,'from',show self.mon.log(self,"command received: " + command_text) if command_text.strip()=="": return fields= command_text.split() if fields[0] in ('osc','OSC'): if self.osc_enabled is True: status,message=self.oscdriver.parse_osc_command(fields[1:]) if status=='warn': self.mon.warn(self,message) if status=='error': self.mon.err(self,message) self.end('error',message) return if fields[0] =='counter': status,message=self.counter_manager.parse_counter_command(fields[1:]) if status=='error': self.mon.err(self,message) self.end('error',message) return show_command=fields[0] if len(fields)>1: show_ref=fields[1] else: show_ref='' if show_command in ('open','close','closeall','openexclusive'): self.mon.sched(self, TimeOfDay.now,command_text + ' received from show:'+show) if self.shutdown_required is False and self.terminate_required is False: reason,message=self.show_manager.control_a_show(show_ref,show_command) else: return elif show_command =='monitor': self.handle_monitor_command(show_ref) return elif show_command =='cec': self.handle_cec_command(show_ref) return elif show_command == 'event': self.handle_input_event(show_ref,'Show Control') return elif show_command == 'exitpipresents': self.exitpipresents_required=True if self.show_manager.all_shows_exited() is True: # need root.after to get out of st thread self.root.after(1,self.e_all_shows_ended_callback) return else: reason,message= self.show_manager.exit_all_shows() elif show_command == 'shutdownnow': # need root.after to get out of st thread self.root.after(1,self.shutdownnow_pressed) return elif show_command == 'reboot': # need root.after to get out of st thread self.root.after(1,self.reboot_pressed) return else: reason='error' message = 'command not recognised: '+ show_command if reason=='error': self.mon.err(self,message) return def handle_monitor_command(self,command): if command == 'on': os.system('vcgencmd display_power 1 >/dev/null') elif command == 'off': os.system('vcgencmd display_power 0 >/dev/null') def handle_cec_command(self,command): if command == 'on': os.system('echo "on 0" | cec-client -s') elif command == 'standby': os.system('echo "standby 0" | cec-client -s') elif command == 'scan': os.system('echo scan | cec-client -s -d 1') # deal with differnt commands/input events def shutdownnow_pressed(self): self.shutdown_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def reboot_pressed(self): self.reboot_required=True if self.show_manager.all_shows_exited() is True: self.all_shows_ended_callback('normal','no shows running') else: # calls exit method of all shows, results in all_shows_closed_callback self.show_manager.exit_all_shows() def handle_sigterm(self,signum,fframe): self.mon.log(self,'SIGTERM received - '+ str(signum)) self.terminate() def handle_user_abort(self): self.mon.log(self,'User abort received') self.terminate() def terminate(self): self.mon.log(self, "terminate received") self.terminate_required=True needs_termination=False for show in self.show_manager.shows: # print show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF] if show[ShowManager.SHOW_OBJ] is not None: needs_termination=True self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF]) # call shows terminate method # eventually the show will exit and after all shows have exited all_shows_callback will be executed. show[ShowManager.SHOW_OBJ].terminate() if needs_termination is False: self.end('killed','killed - no termination of shows required') # ****************************** # Ending Pi Presents after all the showers and players are closed # ************************** def e_all_shows_ended_callback(self): self.all_shows_ended_callback('normal','no shows running') # callback from ShowManager when all shows have ended def all_shows_ended_callback(self,reason,message): self.canvas.config(bg=self.starter_show['background-colour']) if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True or self.reboot_required is True: self.end(reason,message) def end(self,reason,message): self.mon.log(self,"Pi Presents ending with reason: " + reason) if self.root is not None: self.root.destroy() self.tidy_up() if reason == 'killed': if self.email_enabled is True and self.mailer.email_on_terminate is True: subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Terminated' message = time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip self.send_email(reason,subject,message) self.mon.sched(self, None,"Pi Presents Terminated, au revoir\n") self.mon.log(self, "Pi Presents Terminated, au revoir") # close logging files self.mon.finish() print 'Uncollectable Garbage',gc.collect() # objgraph.show_backrefs(objgraph.by_type('Monitor')) sys.exit(101) elif reason == 'error': if self.email_enabled is True and self.mailer.email_on_error is True: subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Error' message_text = 'Error message: '+ message + '\n'+ time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip self.send_email(reason,subject,message_text) self.mon.sched(self,None, "Pi Presents closing because of error, sorry\n") self.mon.log(self, "Pi Presents closing because of error, sorry") # close logging files self.mon.finish() print 'uncollectable garbage',gc.collect() sys.exit(102) else: self.mon.sched(self,None,"Pi Presents exiting normally, bye\n") self.mon.log(self,"Pi Presents exiting normally, bye") # close logging files self.mon.finish() if self.reboot_required is True: # print 'REBOOT' call (['sudo','reboot']) if self.shutdown_required is True: # print 'SHUTDOWN' call (['sudo','shutdown','now','SHUTTING DOWN']) print 'uncollectable garbage',gc.collect() sys.exit(100) # tidy up all the peripheral bits of Pi Presents def tidy_up(self): self.handle_monitor_command('on') self.mon.log(self, "Tidying Up") # turn screen blanking back on if self.options['noblank'] is True: call(["xset","s", "on"]) call(["xset","s", "+dpms"]) # tidy up animation if self.animate is not None: self.animate.terminate() # tidy up i/o plugins if self.ioplugin_manager != None: self.ioplugin_manager.terminate() if self.osc_enabled is True: self.oscdriver.terminate() # tidy up time of day scheduler if self.tod_enabled is True: self.tod.terminate() # ******************************* # Connecting to network and email # ******************************* def init_network(self): timeout=int(self.options['nonetwork']) if timeout== 0: self.network_connected=False self.unit='' self.ip='' self.interface='' return self.network=Network() self.network_connected=False # try to connect to network self.mon.log (self, 'Waiting up to '+ str(timeout) + ' seconds for network') success=self.network.wait_for_network(timeout) if success is False: self.mon.warn(self,'Failed to connect to network after ' + str(timeout) + ' seconds') # tkMessageBox.showwarning("Pi Presents","Failed to connect to network so using fake-hwclock") return self.network_connected=True self.mon.sched (self, None,'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S")) self.mon.log (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S")) # Get web configuration self.network_details=False network_options_file_path=self.pp_dir+os.sep+'pp_config'+os.sep+'pp_web.cfg' if not os.path.exists(network_options_file_path): self.mon.warn(self,"pp_web.cfg not found at "+network_options_file_path) return self.mon.log(self, 'Found pp_web.cfg in ' + network_options_file_path) self.network.read_config(network_options_file_path) self.unit=self.network.unit # get interface and IP details of preferred interface self.interface,self.ip = self.network.get_preferred_ip() if self.interface == '': self.network_connected=False return self.network_details=True self.mon.log (self, 'Network details ' + self.unit + ' ' + self.interface + ' ' +self.ip) def init_mailer(self): self.email_enabled=False email_file_path = self.pp_dir+os.sep+'pp_config'+os.sep+'pp_email.cfg' if not os.path.exists(email_file_path): self.mon.log(self,'pp_email.cfg not found at ' + email_file_path) return self.mon.log(self,'Found pp_email.cfg at ' + email_file_path) self.mailer=Mailer() self.mailer.read_config(email_file_path) # all Ok so can enable email if config file allows it. if self.mailer.email_allowed is True: self.email_enabled=True self.mon.log (self,'Email Enabled') def try_connect(self): tries=1 while True: success, error = self.mailer.connect() if success is True: return True else: self.mon.log(self,'Failed to connect to email SMTP server ' + str(tries) + '\n ' +str(error)) tries +=1 if tries >5: self.mon.log(self,'Failed to connect to email SMTP server after ' + str(tries)) return False def send_email(self,reason,subject,message): if self.try_connect() is False: return False else: success,error = self.mailer.send(subject,message) if success is False: self.mon.log(self, 'Failed to send email: ' + str(error)) success,error=self.mailer.disconnect() if success is False: self.mon.log(self,'Failed disconnect after send:' + str(error)) return False else: self.mon.log(self,'Sent email for ' + reason) success,error=self.mailer.disconnect() if success is False: self.mon.log(self,'Failed disconnect from email server ' + str(error)) return True
class ConcordanceSearchView(object): _BACKGROUND_COLOUR='#FFF' #white #Colour of highlighted results _HIGHLIGHT_WORD_COLOUR='#F00' #red _HIGHLIGHT_WORD_TAG='HL_WRD_TAG' _HIGHLIGHT_LABEL_COLOUR='#C0C0C0' # dark grey _HIGHLIGHT_LABEL_TAG='HL_LBL_TAG' #Percentage of text left of the scrollbar position _FRACTION_LEFT_TEXT=0.30 def __init__(self): self.model = ConcordanceSearchModel() self.model.add_listener(self) self.top = Tk() self._init_top(self.top) self._init_menubar() self._init_widgets(self.top) self._bind_event_handlers() self.load_corpus(self.model.DEFAULT_CORPUS) def _init_top(self, top): top.geometry('950x680+50+50') top.title('NLTK Concordance Search') top.bind('<Control-q>', self.destroy) top.minsize(950,680) def _init_widgets(self, parent): self.main_frame = Frame(parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1)) self._init_corpus_select(self.main_frame) self._init_query_box(self.main_frame) self._init_results_box(self.main_frame) self._init_paging(self.main_frame) self._init_status(self.main_frame) self.main_frame.pack(fill='both', expand=True) def _init_menubar(self): self._result_size = IntVar(self.top) self._cntx_bf_len = IntVar(self.top) self._cntx_af_len = IntVar(self.top) menubar = Menu(self.top) filemenu = Menu(menubar, tearoff=0, borderwidth=0) filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-q') menubar.add_cascade(label='File', underline=0, menu=filemenu) editmenu = Menu(menubar, tearoff=0) rescntmenu = Menu(editmenu, tearoff=0) rescntmenu.add_radiobutton(label='20', variable=self._result_size, underline=0, value=20, command=self.set_result_size) rescntmenu.add_radiobutton(label='50', variable=self._result_size, underline=0, value=50, command=self.set_result_size) rescntmenu.add_radiobutton(label='100', variable=self._result_size, underline=0, value=100, command=self.set_result_size) rescntmenu.invoke(1) editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu) cntxmenu = Menu(editmenu, tearoff=0) cntxbfmenu = Menu(cntxmenu, tearoff=0) cntxbfmenu.add_radiobutton(label='60 characters', variable=self._cntx_bf_len, underline=0, value=60, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='80 characters', variable=self._cntx_bf_len, underline=0, value=80, command=self.set_cntx_bf_len) cntxbfmenu.add_radiobutton(label='100 characters', variable=self._cntx_bf_len, underline=0, value=100, command=self.set_cntx_bf_len) cntxbfmenu.invoke(1) cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu) cntxafmenu = Menu(cntxmenu, tearoff=0) cntxafmenu.add_radiobutton(label='70 characters', variable=self._cntx_af_len, underline=0, value=70, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='90 characters', variable=self._cntx_af_len, underline=0, value=90, command=self.set_cntx_af_len) cntxafmenu.add_radiobutton(label='110 characters', variable=self._cntx_af_len, underline=0, value=110, command=self.set_cntx_af_len) cntxafmenu.invoke(1) cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu) editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu) menubar.add_cascade(label='Edit', underline=0, menu=editmenu) self.top.config(menu=menubar) def set_result_size(self, **kwargs): self.model.result_count = self._result_size.get() def set_cntx_af_len(self, **kwargs): self._char_after = self._cntx_af_len.get() def set_cntx_bf_len(self, **kwargs): self._char_before = self._cntx_bf_len.get() def _init_corpus_select(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.var = StringVar(innerframe) self.var.set(self.model.DEFAULT_CORPUS) Label(innerframe, justify=LEFT, text=' Corpus: ', background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left') other_corpora = self.model.CORPORA.keys().remove(self.model.DEFAULT_CORPUS) om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora()) om['borderwidth'] = 0 om['highlightthickness'] = 1 om.pack(side='left') innerframe.pack(side='top', fill='x', anchor='n') def _init_status(self, parent): self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx = 1, pady = 0) self.status.pack(side='top', anchor='sw') def _init_query_box(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) another = Frame(innerframe, background=self._BACKGROUND_COLOUR) self.query_box = Entry(another, width=60) self.query_box.pack(side='left', fill='x', pady=25, anchor='center') self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1) self.search_button.pack(side='left', fill='x', pady=25, anchor='center') self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler) another.pack() innerframe.pack(side='top', fill='x', anchor='n') def search_enter_keypress_handler(self, *event): self.search() def _init_results_box(self, parent): innerframe = Frame(parent) i1 = Frame(innerframe) i2 = Frame(innerframe) vscrollbar = Scrollbar(i1, borderwidth=1) hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz') self.results_box = Text(i1, font=tkFont.Font(family='courier', size='16'), state='disabled', borderwidth=1, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1) self.results_box.pack(side='left', fill='both', expand=True) self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG, foreground=self._HIGHLIGHT_WORD_COLOUR) self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG, foreground=self._HIGHLIGHT_LABEL_COLOUR) vscrollbar.pack(side='left', fill='y', anchor='e') vscrollbar.config(command=self.results_box.yview) hscrollbar.pack(side='left', fill='x', expand=True, anchor='w') hscrollbar.config(command=self.results_box.xview) #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!! Label(i2, text=' ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e') i1.pack(side='top', fill='both', expand=True, anchor='n') i2.pack(side='bottom', fill='x', anchor='s') innerframe.pack(side='top', fill='both', expand=True) def _init_paging(self, parent): innerframe = Frame(parent, background=self._BACKGROUND_COLOUR) self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled') prev.pack(side='left', anchor='center') self.next = next = Button(innerframe, text='Next', command=self.next, width='10', borderwidth=1, highlightthickness=1, state='disabled') next.pack(side='right', anchor='center') innerframe.pack(side='top', fill='y') self.current_page = 0 def previous(self): self.clear_results_box() self.freeze_editable() self.model.prev(self.current_page - 1) def next(self): self.clear_results_box() self.freeze_editable() self.model.next(self.current_page + 1) def about(self, *e): ABOUT = ("NLTK Concordance Search Demo\n") TITLE = 'About: NLTK Concordance Search Demo' try: from tkMessageBox import Message Message(message=ABOUT, title=TITLE, parent=self.main_frame).show() except: ShowText(self.top, TITLE, ABOUT) def _bind_event_handlers(self): self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded) self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated) self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error) self.top.bind(ERROR_LOADING_CORPUS_EVENT, self.handle_error_loading_corpus) def handle_error_loading_corpus(self, event): self.status['text'] = 'Error in loading ' + self.var.get() self.unfreeze_editable() self.clear_all() self.freeze_editable() def handle_corpus_loaded(self, event): self.status['text'] = self.var.get() + ' is loaded' self.unfreeze_editable() self.clear_all() self.query_box.focus_set() def handle_search_terminated(self, event): #todo: refactor the model such that it is less state sensitive results = self.model.get_results() self.write_results(results) self.status['text'] = '' if len(results) == 0: self.status['text'] = 'No results found for ' + self.model.query else: self.current_page = self.model.last_requested_page self.unfreeze_editable() self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT) def handle_search_error(self, event): self.status['text'] = 'Error in query ' + self.model.query self.unfreeze_editable() def corpus_selected(self, *args): new_selection = self.var.get() self.load_corpus(new_selection) def load_corpus(self, selection): if self.model.selected_corpus != selection: self.status['text'] = 'Loading ' + selection + '...' self.freeze_editable() self.model.load_corpus(selection) def search(self): self.current_page = 0 self.clear_results_box() self.model.reset_results() query = self.query_box.get() if (len(query.strip()) == 0): return self.status['text'] = 'Searching for ' + query self.freeze_editable() self.model.search(query, self.current_page + 1, ) def write_results(self, results): self.results_box['state'] = 'normal' row = 1 for each in results: sent, pos1, pos2 = each[0].strip(), each[1], each[2] if len(sent) != 0: if (pos1 < self._char_before): sent, pos1, pos2 = self.pad(sent, pos1, pos2) sentence = sent[pos1-self._char_before:pos1+self._char_after] if not row == len(results): sentence += '\n' self.results_box.insert(str(row) + '.0', sentence) word_markers, label_markers = self.words_and_labels(sent, pos1, pos2) for marker in word_markers: self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1])) for marker in label_markers: self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1])) row += 1 self.results_box['state'] = 'disabled' def words_and_labels(self, sentence, pos1, pos2): search_exp = sentence[pos1:pos2] words, labels = [], [] labeled_words = search_exp.split(' ') index = 0 for each in labeled_words: if each == '': index += 1 else: word, label = each.split('/') words.append((self._char_before + index, self._char_before + index + len(word))) index += len(word) + 1 labels.append((self._char_before + index, self._char_before + index + len(label))) index += len(label) index += 1 return words, labels def pad(self, sent, hstart, hend): if hstart >= self._char_before: return sent, hstart, hend d = self._char_before - hstart sent = ''.join([' '] * d) + sent return sent, hstart + d, hend + d def destroy(self, *e): if self.top is None: return self.top.destroy() self.top = None def clear_all(self): self.query_box.delete(0, END) self.model.reset_query() self.clear_results_box() def clear_results_box(self): self.results_box['state'] = 'normal' self.results_box.delete("1.0", END) self.results_box['state'] = 'disabled' def freeze_editable(self): self.query_box['state'] = 'disabled' self.search_button['state'] = 'disabled' self.prev['state'] = 'disabled' self.next['state'] = 'disabled' def unfreeze_editable(self): self.query_box['state'] = 'normal' self.search_button['state'] = 'normal' self.set_paging_button_states() def set_paging_button_states(self): if self.current_page == 0 or self.current_page == 1: self.prev['state'] = 'disabled' else: self.prev['state'] = 'normal' if self.model.has_more_pages(self.current_page): self.next['state'] = 'normal' else: self.next['state'] = 'disabled' def fire_event(self, event): #Firing an event so that rendering of widgets happen in the mainloop thread self.top.event_generate(event, when='tail') def mainloop(self, *args, **kwargs): if in_idle(): return self.top.mainloop(*args, **kwargs)