示例#1
0
class Example(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)

        self.dict = {'Asia': ['Japan', 'China', 'India'],
                     'Europe': ['Portugal', 'Switzerland', 'Ukraine']}

        self.var_a = StringVar(self)
        self.var_b = StringVar(self)

        self.var_a.trace('w', self.update_options)

        self.option_menu_a = OptionMenu(self, self.var_a, *self.dict.keys())
        self.option_menu_a.pack(side="top")
        self.option_menu_a["width"] = 10
        self.option_menu_b = OptionMenu(self, self.var_b, '')
        self.option_menu_b["width"] = 10
        self.option_menu_b.pack(side="top")

        self.var_a.set('Asia')

    def update_options(self, *args):
        countries = self.dict[self.var_a.get()]
        self.var_b.set(countries[0])

        menu = self.option_menu_b['menu']
        menu.delete(0, 'end')

        for c in countries:
            menu.add_command(label=c, command=lambda x=c: self.var_b.set(x))
示例#2
0
 class DateWidget(Frame):
     """Gets a date from the user."""
     def __init__(self, master):
         """Make boxes, register callbacks etc."""
         Frame.__init__(self, master)
         self.label = Label(self, text="När är du född?")
         self.label.pack()
         self.entry_text = StringVar()
         self.entry_text.trace("w", lambda *args: self.onEntryChanged())
         self.entry = Entry(self, width=date_entry_width,
              textvariable=self.entry_text)
         self.entry.insert(0, "ÅÅÅÅ-MM-DD")
         self.entry.pack(pady=small_pad)
         self.button = Button(self, text="Uppdatera",
              command=lambda: self.onDateChanged())
         self.button.pack()
         self.entry.focus_set()
         self.entry.select_range(0, END)
         self.entry.bind("<Return>", lambda x: self.onDateChanged())
     def setListener(self, pred_view):
         """Select whom to notify when a new date is entered."""
         self.pred_view = pred_view
     def onDateChanged(self):
         """Notifies the PredictionWidget that the date has been changed."""
         try:
             date = datetime.datetime.strptime(self.entry.get(),
                  "%Y-%m-%d").date()
             self.pred_view.update(date)
         except ValueError:
             self.entry.configure(foreground="red")
     def onEntryChanged(self):
         """Reset the text color."""
         self.entry.configure(foreground="")
示例#3
0
class GuiGeneratorSelect(Frame):
    def __init__(self, parent, generators):
        Frame.__init__(self, parent)
        self.parent = parent
        self.pack()
        
        self._generators = generators
        self._generatorName = StringVar()
        self._generatorName.set(generators[0].getName())
        self._generatorName.trace("w", self._switchSettings)
        
        self._generatorLbl = Label(self, text="Generator");
        self._generatorLbl.pack(side=LEFT)
        
        param = (self, self._generatorName) + tuple(i.getName() for i in generators)
        self._generatorOpt = OptionMenu(*param)
        self._generatorOpt.pack(side=LEFT)
        
        
        self._switchSettings()
        
    def _switchSettings(self, *args):
       print("DBG: switch generator settings")
       for i in self._generators:
           if i.getName() == self._generatorName.get(): 
               i.pack()
               self._generatorGui = i
               print("pack " + str(i.getName()))
           else:
               i.pack_forget() 
               print("unpack " + str(i.getName()))
    
    def getCurrGeneratorGui(self):
        return self._generatorGui         
示例#4
0
 def init_before_run(self, nb_models, coefficients):
     ''' See base class.
     '''
     current_dmu = StringVar()
     current_dmu.trace('w', self.frame.on_dmu_change)
     self.current_dmu = current_dmu
     self.increment = 100 / (len(coefficients) * nb_models)
     self.frame.progress_bar['value'] = 0
示例#5
0
class EntryTextHolder(Entry):
    def __init__(self, master=None):
        Entry.__init__(self, master)
        self._value = StringVar()
        self['textvariable'] = self._value
        self._value.trace('w', self._valuechanged)
        self.model = TextHolderModel(view=self)
    
    def _valuechanged(self, *args):
        self.model.text = self._value.get()
    
    #--- model --> view
    def update_text(self):
        text = self.model.text
        if text != self.get():
            self.delete(0, 'end')
            self.insert(0, text)
示例#6
0
class FileEditBar(Frame, object):


    def __init__(self, master, directory='.', filesettings=None, defaultname='*unknown{}', importhook=None,
                 deletehook=None, projecthook=None, filecontenthook=None, selectfilehook=None,
                 fileslisthook=None, updatehook=None, onchangehook=None):

        self.master = master

        Frame.__init__(self, master)

        self.selected_file = StringVar()
        self.selected_file.trace("w", self.select_file)
        self._dirty = False
        self._dirty_file_name = ''
        self._editor_dirty = False

        self.dir = directory
        self.fsettings = filesettings
        self.defaultname = defaultname

        # hooks
        self.import_hook = importhook
        self.delete_hook = deletehook
        self.save_project_hook = projecthook
        self.filecontent_hook = filecontenthook
        self.update_hook = updatehook
        self.select_file_hook = selectfilehook
        self.files_list_hook = fileslisthook
        self.onchange_hook = onchangehook

        row = 0
        self.columnconfigure(1, weight=2)

        files = []
        self.file_buffer = {}
        self.file_reload = True
        if len(files) == 0: files.append("")
        self.list_files = OptionMenu(*(self, self.selected_file) + tuple(files))
        self.list_files.grid(row=row, column=1, sticky="NWE")

        # new file
        self.btn_newfile = Button(self, text='New', command=self.new_file)
        self.btn_newfile.grid(row=row, column=2, sticky="E")

        # import file
        self.btn_importfile = Button(self, text='Import', command=self.import_file)
        self.btn_importfile.grid(row=row, column=3, sticky="E")

        # delete file
        self.btn_delfile = Button(self, text='Delete', command=self.delete_file)
        self.btn_delfile.grid(row=row, column=4, sticky="E")

        # save button
        self.btn_update_file = Button(self, text='Save', command=self.save_file)
        self.btn_update_file.grid(row=row, column=6, sticky="E")

        # save as.. button
        self.btn_saveas_file = Button(self, text='Save as...', command=self.saveas_file)
        self.btn_saveas_file.grid(row=row, column=7, sticky="E")

        # editor
        row += 1
        self.editor = SyntaxHighlightingText(self, change_hook=self.onchange_filecontent)
        self.editor.grid(row=row, column=1, columnspan=7, sticky="NWES")
        self.rowconfigure(row, weight=1)


    @property
    def dirty(self):
        return self._dirty or self.file_buffer != {}


    @dirty.setter
    def dirty(self, d):
        self._dirty = (d or self.file_buffer != {})
        if self.onchange_hook:
            self.onchange_hook(dirty=self._dirty)

    def new_file(self):
        self.list_files['menu'].add_command(label=self.defaultname.format(self.fsettings.get('extension', '.mln')), command=_setit(self.selected_file, self.defaultname.format(self.fsettings.get('extension', '.mln'))))
        self.selected_file.set(self.defaultname.format(self.fsettings.get('extension', '.mln')))
        self.file_buffer[self.defaultname.format(self.fsettings.get('extension', '.mln'))] = ''
        self.editor.delete("1.0", END)
        self.dirty = True


    def import_file(self):
        filename = askopenfilename(initialdir=self.dir, filetypes=self.fsettings.get('ftypes'), defaultextension=self.fsettings.get('extension', '.mln'))
        if filename:
            fpath, fname = ntpath.split(filename)
            self.dir = os.path.abspath(fpath)
            content = mlnpath(filename).content
            if self.import_hook is not None:
                self.import_hook(fname, content)
            self.update_file_choices()
            self.selected_file.set(fname)
            self.dirty = True


    def delete_file(self):
        fname = self.selected_file.get().strip()

        # remove element from project mlns and buffer
        if fname in self.file_buffer:
            del self.file_buffer[fname]

        if self.delete_hook is not None:
            self.delete_hook(fname)

        f = self.update_file_choices()
        # select first element from remaining list
        if f: self.list_files['menu'].invoke(0)
        else:
            self.selected_file.set('')
            self.editor.delete("1.0", END)
        self.dirty = True



    def save_all_files(self):
        current = self.selected_file.get().strip()
        for f in self.file_buffer:
            content = self.file_buffer[f]
            if f == current:
                content = self.editor.get("1.0", END).strip()

            if self.update_hook is not None:
                self.update_hook(f, f.strip('*'), content)

        # reset buffer, dirty flag for editor and update mln selections
        self.file_buffer.clear()
        self._editor_dirty = False
        self.update_file_choices()
        self.dirty = False

        if self.save_project_hook is not None:
            self.save_project_hook()


    def save_file(self):
        oldfname = self.selected_file.get().strip()
        if oldfname == self.defaultname.format(self.fsettings.get('extension', '.mln')):
            self.saveas_file()
        else:
            self.update_file(oldfname, new=oldfname.strip('*'), askoverwrite=False)


    def saveas_file(self):
        oldfname = self.selected_file.get().strip()
        res = tkinter.simpledialog.askstring('Save as', "Enter a filename", initialvalue=oldfname.strip('*'))
        if res is None: return
        elif res:
            if not res.endswith(self.fsettings.get('extension')):
                res = res + self.fsettings.get('extension')
            self.update_file(oldfname, new=res)


    def update_file(self, old, new=None, askoverwrite=True):
        success = 1
        content = self.editor.get("1.0", END).strip()

        if self.update_hook is not None:
            success = self.update_hook(old.strip('*'), new, content, askoverwrite=askoverwrite)

        if success != -1:
            if old in self.file_buffer:
                del self.file_buffer[old]

            # reset dirty flag for editor and update mln selections
            self._editor_dirty = False
            self.update_file_choices()

            fn = new if new is not None and new != '' else old
            if new != '': self.selected_file.set(fn)
            self.dirty = False

            if self.save_project_hook is not None:
                self.save_project_hook()


    def select_file(self, *_):
        filename = self.selected_file.get().strip()
        self.dirty = True

        if filename is not None and filename != '':
            # filename is neither None nor empty
            if self._editor_dirty:
                # save current state to buffer before updating editor
                self.file_buffer[self._dirty_file_name] = self.editor.get("1.0", END).strip()
                self._editor_dirty = True if '*' in filename else False
                if not self.file_reload:
                    self.file_reload = True
                    return
            if '*' in filename:# is edited
                # load previously edited content from buffer instead of mln file in project
                content = self.file_buffer.get(filename, '').strip()
                self.editor.delete("1.0", END)
                content = content.replace("\r", "")
                self.editor.insert(INSERT, content)
                self._editor_dirty = True
                self._dirty_file_name = '*' + filename if '*' not in filename else filename
                return

            if self.files_list_hook is not None and self.filecontent_hook is not None:
                files = self.files_list_hook()
                if filename in files:
                    # load content from mln file in project
                    content = self.filecontent_hook(filename)
                    self.editor.delete("1.0", END)
                    content = content.replace("\r", "")
                    self.editor.insert(INSERT, content)
                    self._editor_dirty = False

        else:
            # should not happen
            self.editor.delete("1.0", END)
            self.list_files['menu'].delete(0, 'end')
        if self.select_file_hook is not None:
            self.select_file_hook()

    def update_file_choices(self):
        self.list_files['menu'].delete(0, 'end')
        files = []
        if self.files_list_hook is not None:
            files = self.files_list_hook()

        new_files = sorted([i for i in files if '*'+i not in self.file_buffer] + list(self.file_buffer.keys()))
        for f in new_files:
            self.list_files['menu'].add_command(label=f, command=_setit(self.selected_file, f))

        return new_files


    def onchange_filecontent(self, *_):
        if not self._editor_dirty:
            self._editor_dirty = True
            self.dirty = True
            self.file_reload = False # do not reload file, only change filename to *filename
            fname = self.selected_file.get().strip()
            fname = '*' + fname if '*' not in fname else fname
            self._dirty_file_name = fname
            self.file_buffer[self._dirty_file_name] = self.editor.get("1.0", END).strip()
            self.update_file_choices()
            self.selected_file.set(self._dirty_file_name)


    def clear(self, keep=False):
        self.file_buffer.clear()

        if not keep:
            self.editor.delete("1.0", END)

        self.dirty = False
示例#7
0
    def create_selection_menu(self,
                              cb_on_select,
                              *opts,
                              always_trigger_onselect=False,
                              no_destructure=False,
                              pass_selection_to_callback=False):
        """
        Quick way of creating a drop-down menu with a set of options and selection callbacks.

        :param cb_on_select: Menu item selection event callback
        :param opts: Menu options. These should be a list of two-element tuples where the first item is the label and the second is the corresponding value
        :param always_trigger_onselect: Whether the selection callback should be triggered even if an already-selected item was selected
        :param no_destructure: Whether option values should be destructured into the arguments of the callback
        :param pass_selection_to_callback: Whether or not to pass the selected value to the selection callback function
        :return: Getter function for the currently selected `value` (not label)
        """

        options_dict = dict()

        selection_active = StringVar(self.root)
        selection_previous = StringVar(self.root)

        for (key, value) in opts:
            options_dict[key] = value

        menu = OptionMenu(self.options_frame, selection_active,
                          *options_dict.keys())

        def on_select(*args):
            """
            Callback function for when a menu item is selected

            :param args: Ignored arguments. Just contains the modified variable
            :return: None
            """
            # Check if a previously un-selected item was selected (or if the event should be processed anyway)
            if selection_active.get() != selection_previous.get(
            ) or always_trigger_onselect:
                selection_previous.set(selection_active.get())

                # Call callback if one was specified
                if cb_on_select:
                    if pass_selection_to_callback:
                        # Attempt to destructure parameter as much as possible
                        # This is just a lazy way of passing sets of arguments in less LOC
                        if (not no_destructure) and dir(
                                options_dict[selection_active.get(
                                )]).__contains__("__iter__"):
                            if type(options_dict[
                                    selection_active.get()]) is dict:
                                cb_on_select(
                                    **options_dict[selection_active.get()])
                            else:
                                cb_on_select(
                                    *(options_dict[selection_active.get()]))
                        else:
                            cb_on_select(options_dict[selection_active.get()])
                    else:
                        cb_on_select()

        # Set a callback for when variable changes value
        selection_active.trace("w", on_select)

        # Pack menu if a side as packed, else assume packing will be done elsewhere
        menu.pack(side="left")

        # Select a menu option. This also triggers an initial callback
        selection_active.set(opts[0][0])

        # Return a getter function to the active *value* (not key)
        return lambda: options_dict[selection_active.get()]
示例#8
0
class GuiApplication:
    def __init__(self):
        self.window = Tk()
        self.window.title(MAIN_TITLE)

        # this is so dumb
        if system() == 'Windows':
            with open('temp_icon.ico', 'wb') as temp_icon:
                temp_icon.write(base64.b64decode(ICON_WIN))
                self.window.iconbitmap('temp_icon.ico')
            os.remove('temp_icon.ico')

        self.window.wm_title(MAIN_TITLE)
        #self.window.resizable(False, False)

        # stupid shit only happens on mac???
        if system() == "Darwin":
            self.window.tk_setPalette(background="#e8e8e8")

        self.initialize_gui()

    def initialize_gui(self, initial_values=None):
        self.selections = {}
        self.combobox_selections = {}
        self.checkbox_text = {}

        self.main_frame = Frame(self.window)

        self.gridcontainer = Frame(self.main_frame)
        self.frames = {
            'rom-settings':
            ttk.LabelFrame(self.gridcontainer, text="ROM Settings"),
            'gameplay':
            ttk.LabelFrame(self.gridcontainer, text="Gameplay Settings"),
            'aesthetics':
            ttk.LabelFrame(self.gridcontainer, text="Aesthetic Settings"),
        }

        self.frames['rom-settings'].pack(side=TOP, fill=X, padx=2, pady=2)
        self.frames['gameplay'].pack(side=LEFT,
                                     fill=BOTH,
                                     expand=True,
                                     anchor="w",
                                     padx=2,
                                     pady=2)
        self.frames['aesthetics'].pack(side=RIGHT,
                                       fill=BOTH,
                                       expand=True,
                                       anchor="w",
                                       padx=2,
                                       pady=2)

        #self.gridcontainer.add(self.frames['rom-settings'], text='ROM Options')
        #self.gridcontainer.add(self.frames['gameplay'], text='Gameplay Rules')
        #self.gridcontainer.add(self.frames['aesthetic'], text='Aesthetic Rules')

        self.add_rom_settings()
        self.add_settings_from_file()

        self.add_main_settings()

        self.gridcontainer.pack(expand=True,
                                fill=BOTH,
                                anchor="center",
                                padx=5,
                                pady=5)
        self.main_frame.pack(expand=True, fill=BOTH)

        self.window.update_idletasks()
        self.window.mainloop()

    def select_rom_input(self):
        input_rom = filedialog.askopenfilename(title="Select Input ROM",
                                               filetypes=[("ROM Files",
                                                           (".z64", ".n64")),
                                                          ("All Files", "*")])
        self.selections['input_rom'].set(input_rom)

        #if input_rom != "":
        #if self.selections['output_rom'].get() == "":
        #path_parts = input_rom.split(".")
        #guessed_output_file = f'{".".join(path_parts[:-1])}.out.{path_parts[-1]}'
        #self.selections['output_rom'].set(guessed_output_file)

    def select_rom_output(self):
        output_suggestion = 'SM64_Randomizer.z64'
        current_input = self.selections['input_rom'].get()
        if current_input:
            path = Path(current_input)
            file = path.stem
            ext = path.suffix
            output_suggestion = f'{file}.out{ext}'

        output_int = 1
        while os.path.exists(output_suggestion):
            file = ".".join(output_suggestion.split(".")[:-1])
            ext = output_suggestion.split(".")[-1]

            output_suggestion = f'{file}.{output_int}.{ext}'

        output_rom = filedialog.asksaveasfilename(
            title="Select Output Path",
            filetypes=[("ROM Files", (".z64"))],
            #initialdir=self.selections["output_rom"],
            initialfile=output_suggestion)

        if output_rom != "":
            self.selections['output_rom'].set(output_rom)

    def toggle_checkbox_label(self, key):
        def trigger():
            if bool(self.selections[key].get()):
                self.checkbox_text[key].set("Enabled")
            else:
                self.checkbox_text[key].set("Disabled")

        return trigger

    def set_random_seed(self):
        self.seed_entry.set(randint(0, 1e19))

    def set_seed_as_num(self, *args):
        byte_entry = bytes(self.seed_entry.get(), 'utf8')
        self.selections['seed'].set(
            int.from_bytes(byte_entry, 'little', signed=False))

    def check_validity(self):
        rom_file = self.selections['input_rom'].get()
        self.check_error = None

        if not len(rom_file):
            self.check_error = 'Please select a ROM-File first'
            return False

        if not os.path.isfile(rom_file):
            self.check_error = 'The selected ROM is invalid'
            return False

        out_file = self.selections['output_rom'].get()
        if not len(out_file):
            self.check_error = 'Please select an output path'
            return False

        return True

    def read_from_clipboard(self):
        data = pyperclip.paste()

        try:
            json_data = json.loads(data)
        except Exception:
            messagebox.showerror(
                title=MAIN_TITLE,
                message=
                f"Sorry, the settings in your clipboard are not valid. Please try again."
            )
            return

        if json_data['version'] != __version__:
            messagebox.showerror(
                title=MAIN_TITLE,
                message=
                f"Sorry, the settings version do not match. Please ensure you're using the same version when copying the settings."
            )
            return

        json_data["input_rom"] = self.selections['input_rom'].get()
        json_data["output_rom"] = self.selections['output_rom'].get()

        for (key, tkinter_var) in self.selections.items():
            if key in json_data:
                tkinter_var.set(json_data[key])
        self.seed_entry.set(json_data["seed"])
        self.set_seed_as_num()

        self.pasteSettings.configure(text="Settings applied!")
        self.window.update()
        s = Timer(
            2, lambda: self.pasteSettings.configure(
                text="Paste Settings from Clipboard"))
        s.start()

    def copy_to_clipboard(self):
        output = {"version": __version__}

        data = {key: var.get() for (key, var) in self.selections.items()}
        output.update(data)

        # this makes no sense for other people
        del output['input_rom']
        del output['output_rom']
        output['seed'] = self.seed_entry.get()

        pyperclip.copy(json.dumps(output))

        self.copySettings.configure(text="Settings copied!")
        s = Timer(
            2, lambda: self.copySettings.configure(
                text="Copy Settings to Clipboard"))
        s.start()

    def generate_rom(self):
        try:
            if not self.check_validity():
                messagebox.showerror(title="ROM Generation Failed",
                                     message=self.check_error)
                return

            params = []
            input_rom = None

            for (key, tkinter_var) in self.selections.items():
                key_in_arg_format = f"--{key.replace('_', '-')}"

                if key == 'input_rom':
                    input_rom = tkinter_var.get()
                elif key == 'output_rom':
                    params.append('--out')
                    params.append(tkinter_var.get())
                elif isinstance(tkinter_var, BooleanVar):
                    # boolean args work by adding the param or not
                    if tkinter_var.get():
                        params.append(key_in_arg_format)
                elif isinstance(tkinter_var, StringVar):
                    params.append(key_in_arg_format)
                    params.append(quote(tkinter_var.get()))
                else:
                    raise NotImplementedError(
                        f'arg format for {type(tkinter_var)} is not implemented yet'
                    )

            args = [input_rom, *params]
            from Rom import ROM

            test_output = os.path.join(tempfile.gettempdir(),
                                       'test_output.z64')
            try:
                with ROM(input_rom, test_output) as test_rom:
                    test_rom.verify_header()
            except Exception as excp:
                messagebox.showerror(
                    title="ROM Generation failed",
                    message=
                    f'Sorry, the specified ROM is not valid. Verification failed with error: {excp}'
                )

            try:
                run_with_args(args)
            except Exception as err:
                messagebox.showerror(
                    title="ROM Generation failed",
                    message=
                    f"Unfortunately, generation failed with error:\n {err}\nPlease submit this error to the projects github: https://github.com/andre-meyer/sm64-randomizer/issues"
                )
                print(err)
                return

            rom_output = self.selections['output_rom'].get()
            (folder_containing_rom,
             filename_output) = os.path.split(rom_output)
            messagebox.showinfo(
                title="ROM Generation completed!",
                message=
                f"Your randomized ROM was created as \"{filename_output}\"! Have fun!"
            )
            #if system() == "Windows":
            #subprocess.Popen('explorer /select,"' + rom_output.replace("/", "\\") + '"', shell=True)
            #else:
            #webbrowser.open("file:///" + folder_containing_rom)
            return True
        except Exception as excp:
            messagebox.showerror(
                title="ROM Generation failed",
                message=
                f'Sorry, ROM generation failed with error:\n {excp}\nPlease submit this error to the projects github: https://github.com/andre-meyer/sm64-randomizer/issues'
            )

    def add_setting_field(self, field):
        master = self.frames[field['category']]
        optionFrame = Frame(master)
        key = field['name']

        if field['type'] == 'checkbox':
            self.selections[key] = BooleanVar(optionFrame)
            checkboxField = ttk.Checkbutton(optionFrame,
                                            text=field['label'],
                                            variable=self.selections[key])
            if 'help' in field:
                CreateToolTip(checkboxField, field['help'])

            checkboxField.pack(side=LEFT)
        elif field['type'] == 'select':
            optionLabel = ttk.Label(optionFrame, text=field['label'])
            optionLabel.pack(side=LEFT)
            if 'help' in field:
                CreateToolTip(optionLabel, field['help'])

            self.selections[key] = StringVar(optionFrame)
            self.combobox_selections[key] = StringVar(optionFrame)

            choice_dict = {
                option['label']: option['value']
                for option in field['options']
            }
            choice_dict_invert = {
                option['value']: option['label']
                for option in field['options']
            }
            self.selections[key].set(field['options'][0]['value'])

            optionsField = ttk.OptionMenu(
                optionFrame,
                self.combobox_selections[key],
                field['options'][0]['label'],
                *[option['label'] for option in field['options']],
                command=lambda *args, sel_key=key, choices=choice_dict: self.
                selections[sel_key].set(choices[self.combobox_selections[
                    sel_key].get()]))
            self.selections[key].trace(
                'w',
                lambda *args, sel_key=key, choices=choice_dict_invert: self.
                combobox_selections[sel_key].set(choice_dict_invert[
                    self.selections[sel_key].get()]))

            optionsField.pack(side=LEFT, fill=X, expand=True)

        optionFrame.pack(side=TOP, padx=5, pady=(5, 1), fill=X)

    def add_settings_from_file(self):
        with open(
                os.path.join(application_path, 'Data',
                             'configurableParams.json'), 'r') as json_file:
            fields = json.loads(json_file.read())

            for field in fields:
                self.add_setting_field(field)

    """
  def add_gameplay_settings(self):
    self.add_setting_fields(gameplay_settings, self.frames['gameplay'])

  def add_aesthetic_settings(self):
    self.add_setting_fields(aesthetic_settings, self.frames['aesthetic'])
  """

    def add_main_settings(self):
        buttonsFrame = Frame(self.main_frame, padx=5, pady=5, height=60)
        buttonsFrame.pack_propagate(0)

        generateButton = ttk.Button(buttonsFrame,
                                    text="Generate ROM",
                                    command=self.generate_rom,
                                    width=10)
        generateButton.pack(side=LEFT, fill=BOTH, expand=True)
        self.copySettings = ttk.Button(buttonsFrame,
                                       text="Copy Settings to Clipboard",
                                       command=self.copy_to_clipboard,
                                       width=20)
        self.copySettings.pack(side=LEFT, fill=BOTH, expand=True)
        self.pasteSettings = ttk.Button(buttonsFrame,
                                        text="Paste Settings from Clipboard",
                                        command=self.read_from_clipboard,
                                        width=30)
        self.pasteSettings.pack(side=LEFT, fill=BOTH, expand=True)

        buttonsFrame.pack(fill=X, anchor="center", side=BOTTOM)

    def add_rom_settings(self):
        inputFrame = Frame(self.frames['rom-settings'])
        self.seed_entry = StringVar()
        self.seed_entry.trace('w', self.set_seed_as_num)

        self.selections['seed'] = StringVar()
        self.set_random_seed()
        seedFrame = Frame(inputFrame)

        seedLabel = Label(seedFrame, text="Seed", width=10)
        seedLabel.pack(side=LEFT)
        seedEntry = Entry(seedFrame, textvariable=self.seed_entry)
        seedEntry.pack(side=LEFT, fill=BOTH, expand=True)
        seedRandom = ttk.Button(seedFrame,
                                text='New',
                                command=self.set_random_seed,
                                width=15)
        seedRandom.pack(side=RIGHT)

        seedFrame.pack(side=TOP, fill=X, expand=True)

        self.selections['input_rom'] = StringVar()

        baseRomLabel = Label(inputFrame, text="Input ROM", width=10)
        baseRomLabel.pack(side=LEFT, padx=(0, 0))
        baseRomEntry = Entry(inputFrame,
                             textvariable=self.selections['input_rom'])
        baseRomEntry.pack(side=LEFT, fill=BOTH, expand=True)
        romSelectButton = ttk.Button(inputFrame,
                                     text='Select ROM',
                                     command=self.select_rom_input,
                                     width=15)
        romSelectButton.pack(side=RIGHT)

        inputFrame.pack(side=TOP, fill=X, expand=True)

        outputFrame = Frame(self.frames['rom-settings'])
        self.selections['output_rom'] = StringVar()

        outputPathLabel = Label(outputFrame, text="Output ROM", width=10)
        outputPathLabel.pack(side=LEFT, padx=(0, 0))
        outputRomEntry = Entry(outputFrame,
                               textvariable=self.selections['output_rom'])
        outputRomEntry.pack(side=LEFT, fill=BOTH, expand=True)
        outputSelectButton = ttk.Button(outputFrame,
                                        text='Select Output',
                                        command=self.select_rom_output,
                                        width=15)
        outputSelectButton.pack(side=RIGHT)

        outputFrame.pack(side=TOP, fill=X, expand=True)
示例#9
0
class Card :
    def __init__(self,name="Nom monstre",att=1,pv=1,bonus=None,photo='',monster_type="unknown") :
        self.name=name
        self.att = att
        self.pv = pv
        if not bonus :
            bonus=[] # a cause du fonctionnement etrange de python pour les valeurs d arguments [] par defaut
        self.bonus=bonus
        self.is_spell=(pv<1)
        self.photofile=photo
        self.dumping_file = os.path.join("CardFiles",monster_type+"_monsters.sav")
        self.monster_type = monster_type
        #global all_monsters
        name=self.name.replace(" ","_")
        self.content=self
#        try :
#            self.image = image.load(os.path.join("Card",name+".png"))
#        except :
#            self.image=None
    def equivalentto(self,other) :
        return self==other
    def show(self) :
        pass
    def constructor(self) :
        return ('Card("'+self.name+'",'+str(self.att)+","+str(self.pv)+
            ",["+",".join([p.constructor() for p in self.bonus])+"],"+
             repr(self.photofile)+",'"+self.monster_type+"')")
    def takePlace(self,*ar1,**ars) :
        pass
    def addBonus(self,bonus) :
        self.bonus.append(bonus)
    def getCost(self) :
        if self.pv > 0 :
            cost=self.att/2.+self.pv/2.+sum([p.getCost(self) for p in self.bonus])
        else :
            #print self.bonus
            #if self.bonus :
            #print self.bonus[0].getCost
            #print self.bonus[0].getCost()           
            #if len(self.bonus)>1 : print "** anomalie **"
            S = 0
            for p in self.bonus:
                if p.is_cost_alterator:
                    S += p.getCost(self)
                else:
                    S += p.getCost()
            cost=S# +0.5*(len(self.bonus)-1): why?
        if cost < 0:            cost = 0
        if hasattr(self,"cost") and self.cost!=None :
            # pour les monstres du save, l attribut cost est None        
            print ("cout=",cost," so ",int(floor(cost)))
            self.cost.set(int(floor(cost)))
            self.getStars()
        return cost
    def getStars(self):
        stars = sum([p.getStars() for p in self.bonus])
        if stars>2 : stars=(stars-1)*2
        if stars<0 : stars=0
        if hasattr(self,"stars")  and self.stars != None :
            # pour les monstres du save, l attribut stars existe = None
            self.stars.set('* '*stars)
        #print "stars=",stars
        return stars
    def getDescription(self):
        for b in reversed(self.bonus) :
            try :
                b.getDescription()
            except Exception :
                self.bonus.remove(b)
        return self.name +" ("+str(self.att)+"  "+str(self.pv)+'\n'*bool(self.bonus)+'\n'.join(
            [b.getDescription() for b in self.bonus]) +" )"
    def getInlineDescription(self):
        for b in reversed(self.bonus) :
            try :
                b.getInlineDescription()
            except Exception :
                self.bonus.remove(b)
        return self.name +" ("+str(self.att)+"  "+str(self.pv)+' '.join(
            [b.getInlineDescription() for b in self.bonus]) +" )"
    def postAndSave(self,*args):
        if self.name=="nom monstre" or self.name=="change name" or self.name in Card.blocked_creature :
            self.name="change name"
            self.refreshWidget()
            return
        if not self.verifyBonus() :
            return            
        self.deleteCreature(self.name)
        temp=self.category.get()
        pygame.init()
        fenetre=self.card_win.master
        self.card_win.pack_forget()
        self.save(None)
        

        done=False
        while not done :
            for event in pygame.event.get() :
                if event.type == pygame.QUIT :
                    done=True
        pygame.display.quit()
        self = Card("nom monstre",1,1)
        #card.pack_forget()
        self.initWidget(fenetre)
        self.category.set(temp)
        self.setFile("dummy_arg")

    def verifyBonus(self) :
        nb=[b.__class__.__name__ for b in self.bonus]
        if len(set(nb))!=len(nb) :
            showinfo("Not Allowed","You can't have twice the same bonus")
            return False
        for b1,b2 in [("Insaisissable","Provocation"),("Insaisissable","Inciblable"),("Errant","Incarnation"),
                      ("Camouflage","Provocation"),("Camouflage","ChaqueTour"),("NePeutPasAttaquer","ALaPlaceDeLAttaque"),
                      ("NePeutPasAttaquer","NePeutPasAttaquerLesHeros"),("NePeutPasAttaquerLesHeros","ALaPlaceDeLAttaque"),
                    ("GardienDeVie","QuandIlEstBlesse"),("Charge","NePeutPasRisposter"),("Furie","ALaPlaceDeLAttaque"),
                    ("NePeutPasRiposter","NePeutPasAttaquer"),("NePeutPasRiposter","CoutReduit"),("CriDeGuerre","Incarnation"),
                    ("Charge","CriDeGuerrre"),("Insaisissable","InsensibleALaMagie"),("Charge","Errant"),("CriDeGuerre","Errant"),
                    ("Errant","RaleDAgonie"),("AttaqueADistance","AvecAttaque"),("Errant","AuDebutDuProchainTour"),
                    ("BonusParEnnemi","Determine"),("QuandIlEstBlesse","Incassable"),("Souffrant","QuandIlEstBlesse") ] :
            if b1 in nb and b2 in nb :
                showinfo("Not Allowed","You can't have this combination of powers: {0} and {1}".format(b1,b2))
                return False
        total=self.constructor()
        if "QuandUnAllieEstTue" in nb and (("Spell.Invocation" in total) or ("CopieMain"  in total) or ("PlaceCarteDansMain" in total)):
            showinfo("Not Allowed","You can't have anything to do with Invocation or card creation if you have QuandUnAllieEstTue")
            return False
        return True
 
    def save(self,*args):
        if (self.name in Card.blocked_creature) :
            return
        for b in self.bonus : # on veut que la plainte maudite soit en dernier
            if b.__class__.__name__=="PlainteMaudite" :
                self.bonus.remove(b)
                self.bonus.append(b)
                break
        image = self.createImage()
        
        print ("apres createImage")
        name=self.name.replace(" ","_")
        pygame.image.save(image,"Cards/"+name+".png")
        print ("save image done")
        # now new monster
        loaded_monsters=readMonsters(self.dumping_file)
        #print "Monsters from file = ",file_monsters
        #remove_widget(self)
        loaded_monsters[self.name] = self
        #print "Monsters from file (after) = ",file_monsters
        global all_monsters
        all_monsters.update(loaded_monsters)
        #print "window reinit done"
        with open(self.dumping_file,"wb") as savefile :      
            savefile.write(bytes("\n".join([m.constructor() for k,m in sorted(loaded_monsters.items())]),'UTF-8'))
#        with open(self.dumping_file+".old","rb") as filepickle :
#            print "now in file", self.dumping_file,":",pickle.load(filepickle).keys()
#            filepickle.close()
        with open(os.path.join("CardFiles","all_monsters.sav"), "wb" ) as f :
            f.write(bytes("\n".join([m.constructor() for m in all_monsters.values()]),'UTF-8'))
        recupfile=os.path.join("CardFiles","recup_monsters.sav")
        if (not os.path.isfile(recupfile)) or len(all_monsters)>=len(open(recupfile,'r').readlines()):
            with open(recupfile, "wb" ) as f :
                f.write(bytes("\n".join([m.constructor() for k,m in sorted(all_monsters.items())]),'UTF-8'))
            print ("SAVED in all_monsters.sav and recup_monsters.sav")
        else:
            print ("WARNING : Recup monster file bigger than all monsters file")

    def initWidget(self,fenetre) :
        #print "init"
        self.card_win = PanedWindow(fenetre, orient=VERTICAL)
        fenetre.child=self
        self.refreshWidget()
    def Open(self,*args) :
        print ("open monster ",  self.opening.get())
        #deck_with_card =  self.deck_check(self.opening.get())
        creature = Card.monster_list[self.opening.get()]
        if not ( creature.name in Card.blocked_creature) :
            self.card_win.pack_forget()
            fenetre=self.card_win.master
            #for i in Card.monster_list.keys() :
            #    print i, Card.monster_list[i].getInlineDescription()
            self = Card.monster_list[self.opening.get()]
            print (self.name +" loaded")
            if self.pv<1 :
                self.is_spell=True
            else :
                self.is_spell=False
            #self.card_win.pack_forget()
            for b in self.bonus:
                b.parent = self.bonus
                b.card = self
            self.initWidget(fenetre)
        else:
            showinfo("Sorry","You can't open this monsters because he comes from the campaign.")
         
    def clicDelete(self,*args) :
        #self.card_win.pack_forget()
        #fenetre=self.card_win.master
        """
        for i in all_monsters.keys() :
            print i, all_monsters[i].getInlineDescription()
            
        """
        
        creature= self.delete.get()
        if creature in Card.blocked_creature :
            print ("not possible : creature in campaign")
            self.delete.set('delete')
            return
        if askyesno('Beware!', 'Confirm the deletion of '+creature+"?"):                
            self.deleteCreature(creature)
        self.card_win.pack_forget()
        #self.initWidget(fenetre)
        self.setFile(*args)
    

    def deleteCreature(self,creature) :
        dm=None
        global all_monsters
        if not creature in all_monsters :
            print (creature," is not in all_monsters")
            try :
                fm=os.path.join("CardFiles",self.category.get()+"_monsters.sav")
                dm = readMonsters(fm)
            except:
                print ("error reading file ",fm)
        else :
            print ("delete monster ",  creature)
            try :
                fm = os.path.join("CardFiles",(all_monsters[creature].monster_type)+"_monsters.sav")
                dm = readMonsters(fm)
            except:
                print ("ERROR : no type for ",creature, " or read error")
            del all_monsters[creature]
            fall=os.path.join("CardFiles","all_monsters.sav") 
            with open(fall,"wb") as savefile :
                savefile.write(bytes("\n".join([m.constructor() for m in all_monsters.values()]), 'UTF-8'))            
            print ("deletion of monster ",  creature, "done")
            shutil.copyfile(fall,"CardFiles/recup_monsters.sav")
        if dm and creature in dm :
            del dm[creature]
            with open(fm,"wb") as savefile :
                print('dmv',dm.values())
                savefile.write(bytes("\n".join([m.constructor() for m in dm.values()]), 'UTF-8'))
            print ("deletion of monster ",  creature, " in ",fm," done" )
        else :
            print (creature," not found in dedicated file")
            
            
        
    def choosePhoto(self,*args) :
        from tkinter.filedialog import askopenfilename
        #Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
        filename = askopenfilename(defaultextension=".gif",filetypes=[ ("image",("*.jpg", "*.gif","*.png")),('PNG file','*.png'),('Jpg file','*.jpg'),('GIF file','*.gif')]) # show an "Open" dialog box and return the path to the selected file
        if filename:
            import os.path
            chem=os.path.dirname(os.path.realpath(__file__)).replace('\\','/')+'/'
            #print chem
            if chem in filename :
                filename=filename.replace(chem,'')
                print ("filename modif",filename)
            try :
                pilImage = Image.open(filename)
                PhotoImage(pilImage,master=None)
                #ImageTk.PhotoImage(monimage)
                self.photofile=filename
                print ("photo choosen !")
            except Exception :
                print ("echec ouverture image")
                raise
        self.refreshWidget()

    def setFile(self,*args):
        self.dumping_file = os.path.join("CardFiles",self.category.get()+"_monsters.sav")
        print ("Change dumping file to ",self.dumping_file)
        self.monster_type = self.category.get()
        Card.monster_list=readMonsters(self.dumping_file)
        #from cardPowers import *
        self.refreshWidget()

    def refreshWidget(self) :
        #print "refresh"
        self.card_win.pack_forget()
        import unicodedata
        #Card window      
        self.card_win = PanedWindow(self.card_win.master, orient=VERTICAL)
        self.card_win.pack(side=TOP, expand=True, fill=BOTH, pady=2, padx=2)
        
        
        #Create the name zone
        name_zone=PanedWindow(self.card_win, orient=HORIZONTAL)
        name = StringVar() 
        name.set(self.name)
        def modifName(*args) :
            try :
                assert('"' not in name.get())
                name.get().encode('ascii')
            except Exception as e:
                print ("error on name")
                name.set(self.name)
                return
            old = self.name in Card.blocked_creature
            self.name=name.get()
            if old or self.name in Card.blocked_creature :
                self.refreshWidget()
        name.trace("w", modifName)
        name_wid=Entry(name_zone, width=30,textvariable=name)
        name_wid.pack()
        name_zone.add(name_wid)
        #Create the cost ad star stringvar
        #print int(floor(self.getCost()))
        self.cost=StringVar()
        self.stars=StringVar()
        cost_wid=Label(None, textvariable=self.cost, background='red',width=5, anchor=W)
        star_wid=Label(None, textvariable=self.stars, background='blue', anchor=E)
        self.cost.set(str(int(floor(self.getCost()))))
        self.stars.set("*"*self.getStars())
        #Add them in name zone
        name_zone.add(cost_wid)
        name_zone.add(star_wid)
        
        
        #Create an Image Zone
        image_zone=Button(self.card_win,  command=self.choosePhoto)
        if hasattr(self,"photofile") and self.photofile :            
            print ("Image: ",self.photofile)
            try :
                pilImage=Image.open(self.photofile)
                img=PhotoImage(pilImage,master=image_zone)
            except :
               decomp=self.photofile.split('/')
               for i in range(1,6) :
                   try :
                       fname="/".join(decomp[-i:])
                       print ("try to open",fname)
                       pilImage = Image.open(fname)
                       img=PhotoImage(pilImage,master=image_zone)
                       self.photofile=fname
                       break
                   except :
                       self.photofile=None
        if self.photofile :
            w, h = img.width(), img.height()
            print('wh',w,h)
            if h>400 :
                print("reduction")
                img=PhotoImage(pilImage.resize((w//2,h//2), Image.ANTIALIAS),master=image_zone)
            image_zone=Button(self.card_win,image=img,  command=self.choosePhoto)
            image_zone.image=img
            #image_zone.configure(image=image_zone.image,width=50,height=50,compound=RIGHT)
            #image_zone.pack()
            #print "IMAGE CHANGED"
        else :
            from os import path
            fname=self.name.replace(" ","_")
            if path.isfile("Cards/"+fname+".png") :
                image_zone.config(text='image can be taken from\n'+"Cards/"+fname+".png",background='white',anchor=CENTER)
            else :
                image_zone.config(text='clic to choose image',background='white',anchor=CENTER)

        #image_zone.pack()
        
        
        # POWER ZONE
        power_zone=PanedWindow(self.card_win, orient=VERTICAL)
        #fenetre=self.card_win.master
        def removePowerCreator(px) :
            def removePower(*args) :
                #print 'avant',list_pow
                self.bonus.remove(px)
                #print 'apres',list_pow
                #self.card_win.pack_forget()
                self.refreshWidget()
            return removePower
        for p in self.bonus :
            powline =  PanedWindow(self.card_win, orient=HORIZONTAL)
            pow_wid=p.initWidget(powline)
            powline.add(pow_wid)
            removepow=Button(powline, text="X", command=removePowerCreator(p), anchor=E)
            removepow.pack()
            powline.add(removepow)
            power_zone.add(powline) 
        def addPower(*args) :
            if addBonus.get()!= "add bonus":
                name=addBonus.get()
            else:
                name=add_cost_alteration.get()
            print ("added :",name)
            import CardPowers
            self.bonus+=[eval('CardPowers.'+name+'()')]
            self.bonus[-1].parent=self.bonus
            self.bonus[-1].card=self
            #self.card_win.pack_forget()
            self.refreshWidget()
        #Add bonus Option menu
        addBonus = StringVar(power_zone)
        addBonus.set("add bonus") # default value
        if not self.pv:  
            addBonus_wid = Spell.getSpellMenu(power_zone, addBonus)
        else: addBonus_wid = getBonusMenu(power_zone, addBonus) 
        addBonus.trace('w', addPower)
        if self.pv>0 or len(self.bonus)==0 or all([b.is_cost_alterator for b in self.bonus]):
            addBonus_wid.pack()
            #Add this to power zone
            power_zone.add(addBonus_wid)
        
        #Create save zone
        save_zone = PanedWindow(self.card_win, orient=HORIZONTAL)
        if self.monster_type != "all" and not(self.name in Card.blocked_creature) :
            save_wid = Button(save_zone, text="Save", command=self.postAndSave)
        elif self.monster_type != "all" : 
            save_wid = Button(save_zone, text="creature in campaign", command=None)
        else:
            save_wid = Button(save_zone, text="nead type", command=None)
        save_wid.pack()
        #Create the open button
        save_zone.pack()        
        if Card.monster_list.keys():
            self.opening = StringVar(save_zone)
            self.opening.set("Open")
            choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature]
            choice.sort()
            #print all_monsters.keys()
            open_wid = OptionMenu(save_zone, self.opening,*choice)
            self.opening.trace('w', self.Open)
            open_wid.pack()
            save_zone.add(open_wid)
        
        if Card.monster_list.keys():
            self.delete = StringVar(save_zone)
            self.delete.set("Delete")
            choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature]
            choice.sort()
            delete_wid = OptionMenu(save_zone, self.delete,*choice)
            self.delete.trace('w', self.clicDelete)
            delete_wid.pack()
            save_zone.add(delete_wid)
        
        #Create the type button
        self.category = StringVar(save_zone)
        self.category.set(self.monster_type)
        choice = [file2name(t,"_monsters.sav") for t in glob.glob("CardFiles/*_monsters.sav")]
        if "recup" in choice:
            choice.remove("recup")
        #print all_monsters.keys()
        category_wid = OptionMenu(save_zone, self.category,*choice)
        self.category.trace('w', self.setFile)
        
        
        
        category_wid.pack()
        
        #Add it to save zone
        save_zone.add(save_wid)
        save_zone.add(category_wid)
        
        #Create a new Strength zone for att and pv
        strength_zone=PanedWindow(self.card_win, orient=HORIZONTAL)
        att=StringVar()
        att.set(str(self.att))
        pv=StringVar() ; pv.set(str(self.pv))
        def modifiedAttPv(*args) :
            print ("modifiedAttPv")
            self.pv=int(pv.get())
            if self.pv<1 and self.is_spell==False :
                if len(self.bonus)==0 :
                    self.is_spell=True
                    self.refreshWidget()
                else :
                    self.pv=1
                    self.refreshWidget()
            if self.pv>0 and self.is_spell==True :
                if len(self.bonus)==0 :
                    self.is_spell=False
                    self.refreshWidget()
                else :
                    self.pv=0
                    self.refreshWidget()            
            self.att=int(att.get())
            self.getCost()
        att_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=att,command=modifiedAttPv)
        att_wid.pack()
        strength_zone.add(att_wid)
        strength_zone.add(Label(strength_zone, text='       ', background='white', 
             anchor=CENTER))
        pv_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=pv,command=modifiedAttPv)
        pv_wid.pack()
        strength_zone.add(pv_wid)
        
        #Put it all in window
        self.card_win.add(name_zone)
        self.card_win.add(image_zone)
        self.card_win.add(power_zone)  
        self.card_win.add(strength_zone)
        self.card_win.add(save_zone)
        
        
        self.card_win.pack()                      

    def createImage(self,black=False):
        width=189*2; height=277*2
        screen = pygame.display.set_mode((width,height))

        print ("Type = ",self.monster_type)
        if self.monster_type in all_backgrounds.keys():
            try:
                bg = pygame.image.load(all_backgrounds[self.monster_type])
            except:
                print ("error (? when load of bg")
        else:
            bg = pygame.image.load('gameAnimationImages/Card_face_avant.gif')
        #fond = PhotoImage(file =bg,master=fenetre) pilImage = Image.open(
        #ligne1 = canvas.create_line(75, 0, 75, 120)
        #ligne2 = canvas.create_line(0, 60, 150, 60)      
        if self.photofile and not black:
            try :
               img=pygame.image.load(self.photofile)
            except :
               decomp=self.photofile.split('/')
               for i in range(1,6) :
                   try :
                       fname="/".join(decomp[-i:])
                       print ("try to open",fname)
                       img=pygame.image.load(fname)
                       self.photofile=fname
                       break
                   except:
                       pass
            img = pygame.image.load(self.photofile)
            w, h = img.get_size()
            factor=max(150.*2./w,90.*2./h)
            img=pygame.transform.scale(img,(int(w*factor),int(h*factor)))
            #fenetre.photo=PhotoImage(file=self.photofile,master=canvas)
            #img=ImageTk.PhotoImage(img,master=fenetre)
            screen.blit(img,(width/2.-w*factor/2.,140.-h*factor/4.))
        else :
            try :
                name=self.name.replace(" ","_")
                img=pygame.image.load("Cards/"+name+".png")
                print ("* Found for image ","Cards/"+name+".png")
                screen.blit(img,(0,0))
            except :
                pass
        screen.blit(bg,(0,0))    
        
        pygame.font.init()
        #print  pygame.font.get_fonts()
        if self.monster_type in white_font_types:
            color = (255,255,255)
        else:
            color = (0,0,0)
        centerText(screen,(width/2.+10.,33.*2.),self.name,36-(len(self.name)>11)*(len(self.name)-11)//3,color)
        #txt = canvas.create_text(101, 32, text=self.name, font=("Calibri",12-(len(self.name)>11)*(len(self.name)-11)/5,"bold"), anchor=CENTER)
        if not(self.is_spell):
            centerText(screen,(24*2.,258*2.),str(self.att),40,color)
            centerText(screen,(169*2.,255*2.),str(self.pv),40,color)
        else :
            centerText(screen,(width/2.,265*2.),"SPELL",30,color)
        #elif self.is_spell:
        #    txt = canvas.create_text(100,265, text="SPELL", anchor=CENTER, font=("Calibri",14,'bold'))
        #txt = canvas.create_text(22,35, text=int(floor(self.getCost())), anchor=CENTER, font=("Calibri",18,'bold'))
        centerText(screen,(22*2.,35*2.),str(int(floor(self.getCost()))),50,color)
        #txt1 = canvas.create_text(92,257, text='*'*self.getStars(), anchor=CENTER, font=("Calibri",26,'bold'))
        centerText(screen,(92*2.,257*2.),'*'*self.getStars(),60,color)
        if not(self.monster_type == "unknown"):
            if self.monster_type in all_type_colors:
                Color = all_type_colors[self.monster_type]
            else:
                Color = "human"
        else:
            Color = "human"
        centerText(screen,(95*2.,142*2.),self.monster_type.capitalize(),26,Color)
        
        if len(self.bonus)>0 :
            powers = "e%96".join([b.getDescription() for b in self.bonus if b.getDescription()])
            powers = [p.split("\n") for p in powers.split("e%96")]
            print ("powers are ",powers)
        else :
            powers =""
        #print "POWERS = ", powers
        if powers: 
            space=min([80., 160./sum([len(p)*3+2 for p in powers])])
            print ("Space: ",space)
        line = 0
        for i,b in enumerate(powers):
            if b!=[''] :
                print ("power",b)
                size = min([36.,500./max([len(p) for p in b]) * 2.])
                for x,part in enumerate(b):
                    centerText(screen,(90*2.,167*2.+line*space),part,int(size),color)
                    line += 3
                line += 2
        #canvas.pack()
        #print "toto!"
        pygame.display.flip()
        return screen
      
    def init_as_invocation(self,master,spells=False):
        # monster widget in invocation widget        
        #print "monster init_as_invocation"
        self.content=StringVar()
        self.content.set(self.name)
        self.content.trace("w", self.is_changed_as_invocation)
        l = [ m for m in Card.monster_list.keys() if (spells or all_monsters[m].pv>0) and not(m in Card.blocked_creature) 
                  and (spells or not "PlainteMaudite" in all_monsters[m].constructor())
                   and not any([b.__class__.__name__=="Charge" for b in all_monsters[m].bonus])
                   and not any([b.__class__.__name__=="Errant" for b in all_monsters[m].bonus])
                   and not any([b.__class__.__name__=="Essentiel" for b in all_monsters[m].bonus])
                   and not any([b.__class__.__name__=="Incarnation" for b in all_monsters[m].bonus])
                   #and not any([b.__class__.__name__=="AuDebutDuProchainTour" for b in all_monsters[m].bonus])
                   ]
        self.widget=OptionMenu(master,self.content,*l)
        return self.widget
 
    def init_as_card(self,master):
        # monster widget in invocation widget        
        #print "monster init_as_invocation"
        self.content=StringVar()
        self.content.set(self.name)
        self.content.trace("w", self.is_changed_as_invocation)
        l = [ m for m in Card.monster_list.keys() if  not(m in Card.blocked_creature)  ]
        self.widget=OptionMenu(master,self.content,*l)
        return self.widget
 
       
    def is_changed_as_invocation(self,*args):
        print ("monster is_changed_as_invocation")
        if self.content.get()!= "Troll gris":
            new= Card.monster_list[self.content.get()]
        else:
            new = Card("Troll gris",4,4)

        #print self.content.get()
        if self.parent :
            #parent.spell=new
            #print "self.parent = True"
            self.parent.monster=new
            new.parent = self.parent
            new.card=self.card
        else :
            raise "ce cas existe ?! me dire comment"
            self.bonus[self.bonus.index(self)]=new
        #self.card_win.pack_forget()
        self.card.refreshWidget()
示例#10
0
class NoteBag:
    config = None
    notes = None

    # Config Options
    notes_filename = None
    notes_dir = None
    note_template_filename = None
    document_editor = None

    # GUI Elements
    note_name_action_strvar = None
    note_name_entry_strvar = None
    note_name_entry = None
    note_names_label_strvar = None
    note_names_listbox = None

    ## Config/Init Methods
    def load_config(self):
        """
        Load NoteBag's config file, and use it to set config options.
        """

        config = self.config = read_config(CONFIG_FILENAME)
        self.notes_list_filename = config.get("NoteBag", "Notes List File")
        self.notes_dir = config.get("NoteBag", "Notes Directory")
        self.note_template_filename = config.get("NoteBag", "Note Template Filename")
        self.document_editor = config.get("NoteBag", "Document Editor")

    def save_config(self):
        """
        Save NoteBag's current configuration to its config file.
        """

        save_config(self.config, CONFIG_FILENAME)

    def load_notes_list(self):
        """
        Load the list of notes.
        """

        # TODO handle exceptions
        notes_list_path = self.notes_list_path()
        if not os.path.isfile(notes_list_path):
            self.notes = {}
        else:
            self.notes = read_notes_list(notes_list_path)

    def save_notes_list(self):
        """
        Save the list of notes.
        """

        save_notes_list(self.notes, self.notes_list_path())

    ## Back-End Methods
    def notes_list_path(self):
        """
        Return the path to the notes list file.
        """

        return os.path.join(self.notes_dir, self.notes_list_filename)

    def template_note_path(self):
        """
        Return the path to the template note file.
        """

        return os.path.join(get_called_script_dir(), self.note_template_filename)

    def note_filename_exists(self, filename):
        """
        If a note filename already exists case-insensitively, return
        the proper filename from self.notes.
        """

        for existing in self.notes.values():
            if filename.lower() == existing.lower():
                return existing
        return False

    def note_name_exists(self, note_name):
        """
        If the given note name matches an existing note name
        case-insensitively, return the "proper" note name from
        self.notes; if the given note name does not exist, return
        None.
        """

        note_names = self.notes.keys()
        for existing_note_name in note_names:
            if note_name.lower() == existing_note_name.lower():
                return existing_note_name
        return None

    def get_note_path(self, note_name):
        """
        Return the path to an existing note document.
        """

        note_filename = self.notes[note_name]
        note_path = os.path.join(self.notes_dir, note_filename)
        return note_path

    def new_note_filename(self, note_name):
        """
        Return an unused filename appropriate for the given note name.

        Note filenames are .rtf files. All "un-kosher" characters are
        stripped out of the note name, so the filesystem doesn't choke
        on them.
        """

        filename_base = sanitize_note_name(note_name)
        filename = filename_base + ".rtf"
        if not self.note_filename_exists(filename):
            return filename

        suffix_num = 2
        while self.note_filename_exists(filename):
            filename = "{0}-{1}.rtf".format(filename_base, str(suffix_num))
            suffix_num += 1
        return filename

    def get_listbox_selected_note_name(self):
        """
        Return the note name that is selected in the listbox; if there
        is no selection, return None.
        """

        selections = self.note_names_listbox.curselection()
        if not selections:
            return None
        selection = selections[0]
        note_name = self.note_names_listbox.get(selection)
        return note_name

    def get_entered_note_name(self):
        """
        Get the text that has been entered into the "Note Name" text
        entry box, with all leading and trailing spaces stripped off.
        """

        return self.note_name_entry.get().strip("\t ")

    def add_note(self, note_name, note_filename=None):
        """
        Add a note document, and save the list of notes.
        """

        if not note_filename:
            note_filename = self.new_note_filename(note_name)

        note_path = os.path.join(self.notes_dir, note_filename)
        create_skeleton_note(note_name, note_path, self.template_note_path())

        self.notes[note_name] = note_filename
        self.save_notes_list()

    def update_note_names_list(self):
        """
        Update the listbox of the existing notes, and the list's
        label. If there is any text entered into the "Note Name" text
        entry box, only list note names that contain the entered
        text. (This is where incremental search happens.)
        """

        search_str = self.get_entered_note_name()
        note_names = self.notes.keys()

        # Remove strings that don't match
        if search_str:
            def string_matches_search(s):
                return search_str.lower() in s.lower()
            note_names = filter(string_matches_search, note_names)

        # Sort Alphabetically
        note_names = sorted(note_names, key=lambda s: s.lower())

        # Update the note name listbox
        note_names_listbox = self.note_names_listbox
        note_names_listbox.delete(0, END)
        for note_name in note_names:
            note_names_listbox.insert(END, note_name)

        # Update the note name list label
        if search_str:
            s = "All Note Names Containing '{0}':".format(search_str)
        else:
            s = "All Existing Notes:"
        self.note_names_label_strvar.set(s)

    def open_note(self, note_name):
        """
        Open a note for editing.
        """

        note_filename = self.notes[note_name]
        note_path = os.path.join(self.notes_dir, note_filename)
        open_note(note_path, self.document_editor)

    ## GUI Callbacks
    def note_name_action_callback(self, *_args, **_kwargs):
        """
        A callback to perform an action based on the text in the "Note
        Name" text entry box.

        If the name of an existing note has been entered into the text
        box, open the note; if some other text has been entered,
        create a note with the entered text as a name; if no text has
        been entered, show a warning dialog box and do nothing.
        """

        note_name = self.get_entered_note_name()
        if not note_name:
            messagebox.showwarning("Error", "Can't add note: no note name entered")
            return

        key = self.note_name_exists(note_name)
        if key:
            # The note exists; open it.
            self.open_note(key)
        else:
            # The note doesn't exist; create it.
            # TODO popup a small confirmation/note setup dialog.
            self.add_note(note_name)
            self.clear_note_name_entry()
            self.open_note(note_name)
        self.clear_note_name_entry()

    def note_name_entry_changed(self, *_args, **_kwargs):
        """
        A callback to update the text entry action ("Open"/"Add")
        button's label, and update the incremental note list search,
        based on the text in the "Note Name" text entry box.
        """

        self.update_note_names_list()

        entered_note_name = self.get_entered_note_name()
        if self.note_name_exists(entered_note_name):
            self.note_name_action_strvar.set("Open")
        else:
            self.note_name_action_strvar.set("Add")

    def clear_note_name_entry(self):
        """
        Clear the "Note Name" text entry box.
        """

        self.note_name_entry.delete(0, END)

    def open_note_from_listbox(self, *_args, **_kwargs):
        """
        If a note name has been selected in the note name list, open
        it; otherwise, show a warning dialog box and do nothing.
        """

        note_name = self.get_listbox_selected_note_name()
        if not note_name:
            # TODO show a warning dialog box or something
            messagebox.showwarning("Error", "Can't Open: No note selected")
            return
        self.open_note(note_name)

    def delete_note_from_listbox(self, *_args, **_kwargs):
        """
        If a note name has been selected in the note name list, delete
        it after prompting the user to confirm; otherwise, show a
        warning dialog box and do nothing.
        """

        note_name = self.get_listbox_selected_note_name()
        if not note_name:
            messagebox.showwarning("Error", "Can't Delete: No note selected")
            return
        if not messagebox.askyesno("Really Delete Note?",
                                   "WARNING: This will remove the note document file from your hard drive! You cannot undo this!\n\nReally remove '{0}'?".format(note_name),
                                   icon=messagebox.ERROR):
            return

        note_path = self.get_note_path(note_name)
        del(self.notes[note_name])
        self.save_notes_list()
        os.remove(note_path)
        self.update_note_names_list()

    ## Main Code
    def __init__(self, master):
        ## High-level Layout
        input_frame = Frame(master)
        notes_frame = Frame(master)

        input_frame.pack(fill=X, padx=15)
        notes_frame.pack(fill=BOTH, expand=True, padx=10, pady=10)

        ## Input Frame Setup
        note_name_label = Label(input_frame, text="Note Name: ")
        note_name_label.pack(side=LEFT)

        self.note_name_entry_strvar = StringVar()
        self.note_name_entry_strvar.set("")
        self.note_name_entry_strvar.trace("w", self.note_name_entry_changed)
        self.note_name_entry = Entry(input_frame,
                                     textvariable=self.note_name_entry_strvar)
        note_name_entry = self.note_name_entry
        note_name_entry.pack(side=LEFT, fill=X, expand=True)
        note_name_entry.focus_set()
        note_name_entry.bind("<Return>", self.note_name_action_callback)
        note_name_entry.bind("<KP_Enter>", self.note_name_action_callback)

        self.note_name_action_strvar = StringVar()
        note_name_action_strvar = self.note_name_action_strvar
        note_name_action_strvar.set("Add")
        note_name_action_button = Button(input_frame,
                                         textvar=note_name_action_strvar,
                                         command=self.note_name_action_callback)
        note_name_action_button.pack(side=LEFT)
        clear_note_name_button = Button(input_frame, text="Clear",
                                        command=self.clear_note_name_entry)
        clear_note_name_button.pack(side=LEFT)

        ## Notes Frame Setup
        # List of existing notes
        self.note_names_label_strvar = StringVar()
        note_names_label_strvar = self.note_names_label_strvar
        note_names_label = Label(notes_frame,
                                 textvar=note_names_label_strvar)
        note_names_label.pack(anchor=W)

        note_names_listbox = self.note_names_listbox = Listbox(notes_frame)
        note_names_listbox.pack(side=LEFT, fill=BOTH, expand=True)
        note_names_listbox.bind("<Return>", self.open_note_from_listbox)
        note_names_listbox.bind("<KP_Enter>", self.open_note_from_listbox)
        note_names_listbox.bind("<Double-Button-1>", self.open_note_from_listbox)

        # Add scrollbar to list of notes
        notes_scrollbar = Scrollbar(notes_frame)
        notes_scrollbar.pack(side=LEFT, fill=Y)
        note_names_listbox.config(yscrollcommand=notes_scrollbar.set)
        notes_scrollbar.config(command=note_names_listbox.yview)

        ## Controls
        note_controls = Frame(notes_frame)
        note_controls.pack(side=LEFT, fill=Y)

        open_note_button = Button(note_controls, text="Open",
                                  command=self.open_note_from_listbox)
        open_note_button.pack(fill=X)

        delete_note_button = Button(note_controls, text="Delete",
                                    command=self.delete_note_from_listbox)
        delete_note_button.pack(fill=X)

        ## Final Initialization
        self.load_config()
        self.load_notes_list()
        self.update_note_names_list()
示例#11
0
#number texts
font = {'font': (None, 20)}
entries = []
numbers = []
for x in range(9):
    # make numbers and entries 2d lists
    row1 = []
    row2 = [] # strange things were happening when trying to use only 1 'row[]'
    numbers.append(row1)
    entries.append(row2)
    for y in range(9):
        # get string var
        sv = StringVar()
        sv.set('')
        sv.trace("w", lambda *_, var = sv, x=x, y=y: callback(var,x,y))
        numbers[x].append(sv)
        
        # get entry and attach string var
        num = Entry( canvas, textvariable = sv, width = 2, **font)
        num.grid(column = x, row = y, padx = (8), pady = (7))
        entries[x].append(num)
        
        #offset grid
        if x == 0:
            num.grid(padx = (34,8))
        if x == 8:
            num.grid(padx = (8, 34))
        if y == 0:
            num.grid(pady = (33,7))
        if y == 8:
示例#12
0
文件: gui.py 项目: nhrap-dev/TwoPAGER
class App():
    def __init__(self):
        # Create app
        self.root = tk.Tk()
        self.root.grid_propagate(0)

        # global styles
        config = json.loads(open('src/config.json').read())
        themeId = config['activeThemeId']
        theme = list(filter(
            lambda x: config['themes'][x]['themeId'] == themeId, config['themes']))[0]
        self.globalStyles = config['themes'][theme]['style']
        self.backgroundColor = self.globalStyles['backgroundColor']
        self.foregroundColor = self.globalStyles['foregroundColor']
        self.hoverColor = self.globalStyles['hoverColor']
        self.fontColor = self.globalStyles['fontColor']
        self.textEntryColor = self.globalStyles['textEntryColor']
        self.starColor = self.globalStyles['starColor']
        self.padl = 15
        # tk styles
        self.textBorderColor = self.globalStyles['textBorderColor']
        self.textHighlightColor = self.globalStyles['textHighlightColor']

        # ttk styles classes
        self.style = ttk.Style()
        self.style.configure("BW.TCheckbutton", foreground=self.fontColor,
                             background=self.backgroundColor, bordercolor=self.backgroundColor, side='LEFT')
        self.style.configure('TCombobox', background=self.backgroundColor, bordercolor=self.backgroundColor, relief='flat',
                             lightcolor=self.backgroundColor, darkcolor=self.backgroundColor, borderwidth=4, foreground=self.foregroundColor)

        # App parameters
        self.root.title('TwoPAGER Tool')
        self.root_h = 220
        self.root_w = 330
        self.root.geometry(str(self.root_w) + 'x' + str(self.root_h))
        windowWidth = self.root.winfo_reqwidth()
        windowHeight = self.root.winfo_reqheight()
        # Gets both half the screen width/height and window width/height
        positionRight = int(self.root.winfo_screenwidth()/2 - windowWidth)
        positionDown = int(self.root.winfo_screenheight()/3 - windowHeight)
        # Positions the window in the center of the page.
        self.root.geometry("+{}+{}".format(positionRight, positionDown))
        self.root.resizable(0, 0)
        self.root.configure(background=self.backgroundColor,
                            highlightcolor='#fff')

        # App images
        self.root.wm_iconbitmap('src/assets/images/HazusHIcon.ico')
        self.img_data = ImageTk.PhotoImage(Image.open(
            "src/assets/images/data_blue.png").resize((20, 20), Image.BICUBIC))
        self.img_edit = ImageTk.PhotoImage(Image.open(
            "src/assets/images/edit_blue.png").resize((20, 20), Image.BICUBIC))
        self.img_folder = ImageTk.PhotoImage(Image.open(
            "src/assets/images/folder_icon.png").resize((20, 20), Image.BICUBIC))

        # Init dynamic row
        self.row = 0

    def getStudyRegions(self):
        """Gets all study region names imported into your local Hazus install

        Returns:
            studyRegions: list -- study region names
        """
        # list all Windows SQL Server drivers
        drivers = [
            '{ODBC Driver 17 for SQL Server}',
            '{ODBC Driver 13.1 for SQL Server}',
            '{ODBC Driver 13 for SQL Server}',
            '{ODBC Driver 11 for SQL Server} ',
            '{SQL Server Native Client 11.0}',
            '{SQL Server Native Client 10.0}',
            '{SQL Native Client}',
            '{SQL Server}'
        ]
        comp_name = os.environ['COMPUTERNAME']
        # create connection with the latest driver
        for driver in drivers:
            try:
                conn = py.connect('Driver={d};SERVER={cn}\HAZUSPLUSSRVR;UID=SA;PWD=Gohazusplus_02'.format(
                    d=driver, cn=comp_name))
                break
            except:
                continue
        exclusionRows = ['master', 'tempdb', 'model',
                         'msdb', 'syHazus', 'CDMS', 'flTmpDB']
        cursor = conn.cursor()
        cursor.execute('SELECT [StateID] FROM [syHazus].[dbo].[syState]')
        for state in cursor:
            exclusionRows.append(state[0])
        cursor = conn.cursor()
        cursor.execute('SELECT * FROM sys.databases')
        studyRegions = []
        for row in cursor:
            if row[0] not in exclusionRows:
                studyRegions.append(row[0])
        studyRegions.sort(key=lambda x: x.lower())
        return studyRegions

    def setup(self, scenario_name, folder_path):
        # Make a folder in folder_path for scenario_name
        if not os.path.exists(folder_path + '\\' + scenario_name):
            os.makedirs(folder_path + '\\' + scenario_name)
        # Connect to Hazus SQL Server database where scenario results are stored
        # list all Windows SQL Server drivers
        drivers = [
            '{ODBC Driver 17 for SQL Server}',
            '{ODBC Driver 13.1 for SQL Server}',
            '{ODBC Driver 13 for SQL Server}',
            '{ODBC Driver 11 for SQL Server} ',
            '{SQL Server Native Client 11.0}',
            '{SQL Server Native Client 10.0}',
            '{SQL Native Client}',
            '{SQL Server}'
        ]
        comp_name = os.environ['COMPUTERNAME']
        # create connection with the latest driver
        for driver in drivers:
            try:
                cnxn = py.connect('Driver={d};SERVER={cn}\HAZUSPLUSSRVR;DATABASE={sn};UID=hazuspuser;PWD=Gohazusplus_02'.format(
                    d=driver, cn=comp_name, sn=scenario_name))
                break
            except:
                continue
        return comp_name, cnxn

    def read_sql(self, comp_name, cnxn, scenario_name):
        # Select Hazus results from SQL Server scenario database
        sql_econ_loss = """SELECT Tract, SUM(ISNULL(BldgLoss, 0) + ISNULL(ContentLoss, 0) + ISNULL(InvLoss, 0) + ISNULL(RelocLoss, 0) +
        ISNULL(IncLoss, 0) + ISNULL(RentLoss, 0) + ISNULL(WageLoss, 0)) AS EconLoss
        FROM %s.dbo.[eqTractEconLoss] GROUP BY [eqTractEconLoss].Tract""" % scenario_name
        sql_county_fips = """SELECT Tract, CountyFips FROM %s.dbo.[hzTract]""" % scenario_name
        sql_demographics = """SELECT Tract, Population, Households FROM
        %s.dbo.[hzDemographicsT]""" % scenario_name
        sql_impact = """SELECT Tract, DebrisW, DebrisS, DisplacedHouseholds AS DisplHouse, ShortTermShelter AS Shelter
        FROM %s.dbo.[eqTract]""" % scenario_name
        sql_injury = """SELECT Tract, SUM(ISNULL(Level1Injury, 0)) AS Level1Injury, SUM(ISNULL(Level2Injury, 0)) AS Level2Injury,
        SUM(ISNULL(Level3Injury, 0)) AS Level3Injury, SUM(ISNULL(Level1Injury, 0) + ISNULL(Level2Injury, 0) + ISNULL(Level3Injury, 0)) AS NonFatal5p
        FROM %s.dbo.[eqTractCasOccup] WHERE CasTime = 'C' AND InOutTot = 'Tot' GROUP BY Tract""" % scenario_name
        sql_building_damage = """SELECT Tract, SUM(ISNULL(PDsNoneBC, 0)) As NoDamage, SUM(ISNULL(PDsSlightBC, 0) + ISNULL(PDsModerateBC, 0)) AS GreenTag,
        SUM(ISNULL(PDsExtensiveBC, 0)) AS YellowTag, SUM(ISNULL(PDsCompleteBC, 0)) AS RedTag FROM %s.dbo.[eqTractDmg] WHERE DmgMechType = 'STR' GROUP BY Tract""" % scenario_name
        sql_building_damage_occup = """SELECT Occupancy, SUM(ISNULL(PDsNoneBC, 0)) As NoDamage, SUM(ISNULL(PDsSlightBC, 0) + ISNULL(PDsModerateBC, 0)) AS GreenTag,
        SUM(ISNULL(PDsExtensiveBC, 0)) AS YellowTag, SUM(ISNULL(PDsCompleteBC, 0)) AS RedTag FROM %s.dbo.[eqTractDmg] WHERE DmgMechType = 'STR' GROUP BY Occupancy""" % scenario_name
        sql_building_damage_bldg_type = """SELECT eqBldgType, SUM(ISNULL(PDsNoneBC, 0)) As NoDamage, SUM(ISNULL(PDsSlightBC, 0) + ISNULL(PDsModerateBC, 0)) AS GreenTag,
        SUM(ISNULL(PDsExtensiveBC, 0)) AS YellowTag, SUM(ISNULL(PDsCompleteBC, 0)) AS RedTag FROM %s.dbo.[eqTractDmg] WHERE DmgMechType = 'STR' GROUP BY eqBldgType""" % scenario_name
        sql_tract_spatial = """SELECT Tract, Shape.STAsText() AS Shape FROM %s.dbo.[hzTract]""" % scenario_name
        # Group tables and queries into iterable
        hazus_results = {'econ_loss': sql_econ_loss, 'county_fips': sql_county_fips, 'demographics': sql_demographics, 'impact': sql_impact, 'injury': sql_injury,
                         'building_damage': sql_building_damage, 'building_damage_occup': sql_building_damage_occup, 'building_damage_bldg_type': sql_building_damage_bldg_type,
                         'tract_spatial': sql_tract_spatial}
        # Read Hazus result tables from SQL Server into dataframes with Tract ID as index
        hazus_results_df = {table: pd.read_sql(
            query, cnxn) for table, query in hazus_results.items()}
        for name, dataframe in hazus_results_df.items():
            if (name != 'building_damage_occup') and (name != 'building_damage_bldg_type'):
                dataframe.set_index('Tract', append=False, inplace=True)
        return hazus_results_df

    def results(self, hazus_results_df):
        # Join and group Hazus result dataframes into final TwoPAGER dataframes
        tract_results = hazus_results_df['county_fips'].join([hazus_results_df['econ_loss'], hazus_results_df['demographics'], hazus_results_df['impact'],
                                                              hazus_results_df['injury'], hazus_results_df['building_damage']])
        county_results = tract_results.groupby('CountyFips').sum()
        return tract_results, county_results

    def to_csv(self, hazus_results_df, tract_results, county_results, folder_path, scenario_name):
        # Export TwoPAGER dataframes to text files
        two_pager_df = {'building_damage_occup': hazus_results_df['building_damage_occup'], 'building_damage_bldg_type': hazus_results_df['building_damage_bldg_type'],
                        'tract_results': tract_results, 'county_results': county_results}
        for name, dataframe in two_pager_df.items():
            path = folder_path + '\\' + scenario_name + '\\' + name + '.csv'
            dataframe.to_csv(path)

    def two_pager(self, scenario_name, folder_path, ftp=False):
        comp_name, cnxn = self.setup(scenario_name, folder_path)
        hazus_results_df = self.read_sql(comp_name, cnxn, scenario_name)
        tract_results, county_results = self.results(hazus_results_df)
        self.to_csv(hazus_results_df, tract_results,
                    county_results, folder_path, scenario_name)
        # to_shp(folder_path, scenario_name, hazus_results_df, tract_results)
        # if ftp == True:
        #     credentials = to_ftp(folder_path, scenario_name)
        #     print('Hazus earthquake results available for download at: https://' +
        #           credentials['host'] + credentials['dir'] + '/' + scenario_name)
        print('Hazus earthquake results available locally at: ' +
              folder_path + '\\' + scenario_name)

    def browsefunc(self):
        self.output_directory = filedialog.askdirectory()
        self.input_studyRegion = self.dropdownMenu.get()
        self.text_outputDir.delete("1.0", 'end-1c')
        if len(self.input_studyRegion) > 0:
            self.text_outputDir.insert(
                "1.0", self.output_directory + '/' + self.input_studyRegion)
            self.root.update_idletasks()
        else:
            self.text_outputDir.insert("1.0", self.output_directory)
            self.root.update_idletasks()

    def on_field_change(self, index, value, op):
        try:
            self.input_studyRegion = self.dropdownMenu.get()
            self.output_directory = str(
                self.text_outputDir.get("1.0", 'end-1c'))
            check = self.input_studyRegion in self.output_directory
            if (len(self.output_directory) > 0) and (not check):
                self.output_directory = '/'.join(
                    self.output_directory.split('/')[0:-1])
                self.text_outputDir.delete('1.0', tk.END)
                self.text_outputDir.insert(
                    "1.0", self.output_directory + '/' + self.input_studyRegion)
            self.root.update_idletasks()
        except:
            pass

    def getTextFields(self):
        dict = {
            'output_directory': '/'.join(self.text_outputDir.get("1.0", 'end-1c').split('/')[0:-1])
        }
        return dict

    def focus_next_widget(self, event):
        event.widget.tk_focusNext().focus()
        return("break")

    def on_enter_dir(self, e):
        self.button_outputDir['background'] = self.hoverColor

    def on_leave_dir(self, e):
        self.button_outputDir['background'] = self.backgroundColor

    def on_enter_run(self, e):
        self.button_run['background'] = '#006b96'

    def on_leave_run(self, e):
        self.button_run['background'] = '#0078a9'

    def run(self):
        try:
            if (len(self.dropdownMenu.get()) > 0) and (len(self.text_outputDir.get("1.0", 'end-1c')) > 0):
                self.root.update()
                sleep(1)
                func_row = self.row
                t0 = time()
                ### RUN FUNC HERE ###
                self.two_pager(self.input_studyRegion, self.output_directory)
                print('Total elasped time: ' + str(time() - t0))
                tk.messagebox.showinfo("Hazus", "Success! Output files can be found at: " +
                                       self.output_directory + '/' + self.input_studyRegion)
            else:
                tk.messagebox.showwarning(
                    'Hazus', 'Make sure a study region and output directory have been selected')
        except:
            ctypes.windll.user32.MessageBoxW(
                None, u"Unable to open correctly: " + str(sys.exc_info()[1]), u'Hazus - Message', 0)

    def build_gui(self):
        # App body
        # Required label
        self.label_required1 = tk.Label(
            self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor)
        self.label_required1.grid(row=self.row, column=0, padx=(
            self.padl, 0), pady=(20, 5), sticky=W)
        # Scenario name label
        self.label_scenarioName = tk.Label(
            self.root, text='Study Region', font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor)
        self.label_scenarioName.grid(
            row=self.row, column=1, padx=0, pady=(20, 5), sticky=W)
        self.row += 1

        # Get options for dropdown
        options = self.getStudyRegions()
        self.variable = StringVar(self.root)
        self.variable.set(options[0])  # default value

        # Scenario name dropdown menu
        self.v = StringVar()
        self.v.trace(W, self.on_field_change)
        self.dropdownMenu = ttk.Combobox(
            self.root, textvar=self.v, values=options, width=40, style='H.TCombobox')
        self.dropdownMenu.grid(row=self.row, column=1,
                               padx=(0, 0), pady=(0, 0), sticky=W)
        self.dropdownMenu.bind("<Tab>", self.focus_next_widget)

        # Scenario icon
        self.img_scenarioName = tk.Label(
            self.root, image=self.img_data, background=self.backgroundColor)
        self.img_scenarioName.grid(
            row=self.row, column=2, padx=0, pady=(0, 0), sticky=W)
        self.row += 1

        # Required label
        self.label_required3 = tk.Label(
            self.root, text='*', font='Helvetica 14 bold', background=self.backgroundColor, fg=self.starColor)
        self.label_required3.grid(row=self.row, column=0, padx=(
            self.padl, 0), pady=(10, 0), sticky=W)
        # Output directory label
        self.label_outputDir = tk.Label(self.root, text='Output Directory',
                                        font='Helvetica 10 bold', background=self.backgroundColor, fg=self.fontColor)
        self.label_outputDir.grid(
            row=self.row, column=1, padx=0, pady=(10, 0), sticky=W)
        self.row += 1

        # Output directory text form
        self.text_outputDir = tk.Text(self.root, height=1, width=37, font='Helvetica 10', background=self.textEntryColor,
                                      relief='flat', highlightbackground=self.textBorderColor, highlightthickness=1, highlightcolor=self.textHighlightColor)
        self.text_outputDir.grid(
            row=self.row, column=1, padx=(0, 0), pady=(0, 0), sticky=W)
        self.text_outputDir.bind("<Tab>", self.focus_next_widget)

        # Output directory browse button
        self.button_outputDir = tk.Button(self.root, text="", image=self.img_folder, command=self.browsefunc,
                                          relief='flat', background=self.backgroundColor, fg='#dfe8e8', cursor="hand2", font='Helvetica 8 bold')
        self.button_outputDir.grid(
            row=self.row, column=2, padx=0, pady=(0, 0), sticky=W)
        self.button_outputDir.bind("<Tab>", self.focus_next_widget)
        self.button_outputDir.bind("<Enter>", self.on_enter_dir)
        self.button_outputDir.bind("<Leave>", self.on_leave_dir)
        self.row += 1

        # Run button
        self.button_run = tk.Button(self.root, text='Run', width=5, command=self.run,
                                    background='#0078a9', fg='#fff', cursor="hand2", font='Helvetica 8 bold', relief='flat')
        self.button_run.grid(row=self.row, column=1, columnspan=1,
                             sticky='nsew', padx=50, pady=(30, 20))
        self.button_run.bind("<Enter>", self.on_enter_run)
        self.button_run.bind("<Leave>", self.on_leave_run)
        self.row += 1

    # Run app
    def start(self):
        self.build_gui()
        self.root.mainloop()
示例#13
0
    canvas.create_image(sw, sh, image=img, anchor="nw")

    if img is not None:
        iy = sh + img.width() / (int(yo.get()) + 1)
        while iy < sh + img.height():
            canvas.create_line(sw,
                               iy,
                               root.winfo_screenwidth(),
                               iy,
                               fill='red')
            iy += img.width() / (int(yo.get()) + 1)

        ix = sw + img.width() / (int(xo.get()) + 1)
        while ix < sw + img.width():
            canvas.create_line(ix,
                               sh,
                               ix,
                               root.winfo_screenheight(),
                               fill='red')
            ix += img.width() / (int(xo.get()) + 1)


yo.trace("w", mriezkuj)
xo.trace("w", mriezkuj)

loading()

canvas.pack()

root.mainloop()
class StudentGUI(tk.Frame):
    """Student GUI frame to be used in the main GUI
 
    This class contains multiple input widgets for the GUI,
    as well as the Server class used to connect with the
    socket client.
    """

    # Settings
    header_1_style = "TkDefaultFont 42 bold"
    header_2_style = "TkDefaultFont 18 bold"
    default_style = "TkDefaultFont 14"

    def __init__(self, parent, *args, **kwargs):
        """Constructor
 
        Args:
            parent (tk.widget): parent widget to make the frame a child of
            *args: Variable length argument list
            **kwargs: Arbitrary keyword argument list
        """
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # Mutex for the networking thread
        self.socket_queue = Queue()

        # Socket server
        self.server = Server(port=25565)
        self.server.start(self.socket_queue)

        # Instantiated signals class to generate signals
        self.ecg_signals = Signals()

        # ============ GUI Variables ============
        # Instructor realtime setting variables
        self.hr = IntVar(self, value=80)
        self.threshold = IntVar(self, value=20)
        self.hr_paced = IntVar(self, value=80)

        # Manual Override variables
        self.position = IntVar(self, value=0)
        self.override_position = BooleanVar(self, value=False)

        self.hr1 = StringVar(self, value='0')

        self.pathway_1 = IntVar(self, value=0)
        self.pathway_2 = IntVar(self, value=0)
        self.is_paced = BooleanVar(self, value=False)

        # Serial in position
        self.serial_position = IntVar(self, value='0')

        # Command variables
        self.wait_for_update = BooleanVar(self, value=False)
        self.wait_for_position = BooleanVar(self, value=False)
        self.wait_for_pathway_1 = BooleanVar(self, value=False)
        self.wait_for_pathway_2 = BooleanVar(self, value=False)

        # ============ Main Frame Sides ===========
        # Signals frame
        frame_signals = Frame(self, bg='black')
        frame_signals.pack(side=tk.LEFT)

        # Monitor value frame
        frame_values = Frame(self, bg='black')
        frame_values.pack(side=tk.RIGHT, padx=10)

        # Take care of plotting
        self.plot_point = 0

        self.new_x = [0.0]
        self.new_y = [0.0]

        self.last_x = 0
        self.last_x_lim = 0

        self.position_to_show = 0

        self.variation = 0

        self.flat_span = False
        self.end_flat = 0
        self.flat_span_y = 0

        # HR Monitor setup
        tk.Label(frame_values,
                 text="HR",
                 font=self.header_2_style,
                 bg="black",
                 fg="lime green").pack()
        tk.Label(frame_values,
                 textvariable=self.hr1,
                 font=self.header_1_style,
                 bg="black",
                 fg="lime green").pack()

        # Serial selection setup
        Options = ['']
        Options.extend(serial.tools.list_ports.comports())

        self.s = 'RIP'
        self.ser = None

        self.variable = StringVar(self)
        self.variable.set(Options[0])  #Default option

        w = OptionMenu(frame_signals, self.variable, *Options)
        w.grid(row=2, column=1)

        self.variable.trace('w', self.change_dropdown)

        # Create plotting canvas
        fig = plt.Figure(figsize=(14, 4.5),
                         dpi=100,
                         facecolor='k',
                         edgecolor='k')

        canvas = FigureCanvasTkAgg(fig, master=frame_signals)
        canvas.get_tk_widget().grid(row=1, column=1)

        # Sets plot customisations
        self.ax = fig.add_subplot(111)
        self.ax.set_xlim(self.last_x_lim, 4)
        self.ax.set_ylim(-3.0, 3.0)
        self.ax.set_yticklabels([])
        self.ax.set_xticklabels([])
        self.ax.xaxis.set_tick_params(width=1, top=True)
        self.ax.set_facecolor('black')

        self.line, = self.ax.plot(0, 0)
        self.ax.get_lines()[0].set_color("xkcd:lime")

        # Starts an animated plot for the ECG signal
        self.ani = animation.FuncAnimation(fig,
                                           self.animate,
                                           interval=24,
                                           blit=True)

        # Polling Initialisation for socket connection
        self.after(10, self.read_socket)

    def animate(self, i):
        """Animation function that is called periodically
 
        Args:
            i (int): the current frame value (not used)

        Returns:
            line (matplotlib.line): The line to plot with the next value
        """

        # Set the position index value based on which source is responsible for the signal
        if self.override_position.get():
            position_index = self.position.get()
        else:
            position_index = self.serial_position.get()

        # Set initial heart rate to use
        hr_to_use = self.hr.get()

        # Adjust position and heart rate based on alternative pathways and pacer setting
        if position_index == 4:
            position_index = position_index + self.pathway_1.get()
        elif position_index == 6:
            position_index = position_index + self.pathway_2.get()

            # Show the paced signal if pacer override is active
            if not position_index == 16 and self.is_paced.get():
                position_index = 26
                hr_to_use = self.hr_paced.get()
        else:
            # If no overrides or special settings, just keep the position the same
            position_index = position_index

        # Print what position is being printed
        print(self.ecg_signals.signal_index[position_index])

        # Display heart rate value on GUI
        if position_index == 0:
            self.hr1.set(0)
        else:
            self.hr1.set(hr_to_use)

        # Get the ECG signal values for the corresponding settings
        [x, y] = self.ecg_signals.get_signal(
            self.ecg_signals.signal_index[position_index], hr_to_use,
            self.variation)

        # If not currently traveling between beats
        if not self.flat_span:
            # Set a variable to the potential next value
            x_val = self.last_x + x[self.plot_point]

            # If the potential new value is not going backwards
            if x_val > self.new_x[-1]:
                # Add the new x and y values to the axis lists
                self.new_x.append(x_val)
                self.new_y.append(y[self.plot_point])

                # Update the line
                self.line.set_data(self.new_x, self.new_y)  # update the data

            # If at the end of the beat
            if self.plot_point == 29:
                # Update where the last x value to build from is
                self.last_x = self.new_x[-1]

                # Start plotting for a flat area
                self.end_flat = (x[-1] - x[-2]) + self.new_x[-1]
                self.flat_span_y = y[-1]
                self.flat_span = True

            # Go back to the start of the heart beat if at the end of the beat
            if self.plot_point == 29:
                self.plot_point = 0
            # Go to the next beat value otherwise
            else:
                self.plot_point = self.plot_point + 1
        # If current traveling between beats
        else:
            # Add the new x and y values to the axis lists
            self.new_x.append(self.new_x[-1] + 0.05)
            self.new_y.append(self.flat_span_y)

            # Update the line
            self.line.set_data(self.new_x, self.new_y)  # update the data

            # If reached the end of the flat line area between beats
            if self.new_x[-1] >= self.end_flat:
                # Stop plotting flat
                self.flat_span = False
                self.last_x = self.new_x[-1]

        # If at the end of the plotting window
        if self.new_x[-1] >= self.last_x_lim + 5:
            # Shift the plotting window (this is used instead of a reset to allow for future ECG output options)
            self.last_x_lim += 5
            self.ax.set_xlim(self.last_x_lim, self.last_x_lim + 5)

        # Returns the new line to the plot
        return self.line,

    def change_dropdown(self, *args):
        """Callback function for when a COM port is selected.

        This will automatically send an updated pathway.
 
        Args:
            *args: Variable length argument list
        """

        # If the current selected port is not empty
        if not self.variable.get() == '':
            # Try to connect
            try:
                choice = self.variable.get().split(' -')
                # Open the COM port
                self.ser = serial.Serial(choice[0], 9600)
                print('Connection established.')

                # Start the polling for the serial
                self.after(10, self.read_serial)
            # Print exception if it fails
            except SerialException as e:
                print('Error: {}'.format(e))

    def read_socket(self):
        """Reads the socket connection and interprets the contents for a command to run.

        The valid commands are as follows:
            - update: listen for an incoming ECG settings update
            - start-pos: start manual position override
            - stop-pos: stop manual position override
            - manual-pos: listen for a new override position
            - chpa1: listen for an updated alternative pathway 1
            - chpa2: listen for an updated alternative pathway 2
            - close: close the socket
            - start-pace: start pacing override
            - stop-pace: stop pacing override
            - cal: signal for the microcontroller to recalibrate
            - ressig: reset the student GUI signal
        """

        # If there is something in the socket queue
        if not self.socket_queue.empty():
            # Read from the queue
            message = self.socket_queue.get()

            # Print the value
            print(message)

            # If a previous command set the GUI to wait for a new ECG customisation
            if self.wait_for_update.get():
                # Strip the new value of any commas (for multivalue messages)
                result = [
                    x.strip() for x in message.decode('utf-8').split(',')
                ]

                # Set the ECG customisation values
                self.hr.set(result[0])
                self.threshold.set(result[1])
                self.hr_paced.set(result[2])

                # Stop waiting for an update
                self.wait_for_update.set(False)
            # If the previous command set the GUI to wait for a new manual override position
            elif self.wait_for_position.get():
                # Set the position to the new incoming value
                self.position.set(int(message.decode('utf-8')))
                # Stop listening for new value
                self.wait_for_position.set(False)
                # Override the position
                self.override_position.set(True)
            # If the previous command set the GUI to wait for a new pathway
            elif self.wait_for_pathway_1.get():
                # Set the new pathway
                self.pathway_1.set(int(message.decode('utf-8')))
                print(self.pathway_1.get())
                # Stop listening for a new pathway
                self.wait_for_pathway_1.set(False)
            # If the previous command set the GUI to wait for a new pathway
            elif self.wait_for_pathway_2.get():
                # Set the new pathway
                self.pathway_2.set(int(message.decode('utf-8')))
                print(self.pathway_2.get())
                # Stop listening for a new pathway
                self.wait_for_pathway_2.set(False)
            # Determine what command to run otherwise
            else:
                if message == b'update':
                    self.wait_for_update.set(True)
                elif message == b'start-pos':
                    self.wait_for_position.set(True)
                elif message == b'stop-pos':
                    self.override_position.set(False)
                elif message == b'manual-pos':
                    self.wait_for_position.set(True)
                elif message == b'chpa1':
                    self.wait_for_pathway_1.set(True)
                elif message == b'chpa2':
                    self.wait_for_pathway_2.set(True)
                elif message == b'close':
                    self.destroy()
                elif message == b'start-pace':
                    self.is_paced.set(True)
                elif message == b'stop-pace':
                    self.is_paced.set(False)
                elif message == b'cal':
                    self.write_serial(b'C')
                elif message == b'ressig':
                    self.position_to_show = 0

        # Put this function to call on another timer
        self.after(10, self.read_socket)

    def pause_plot(self):
        """Pause the plotting animation"""
        self.ani.event_source.stop()

    def start_plot(self):
        """Start the plotting animation"""
        self.ani.event_source.start()

    def write_serial(self, message):
        """Write a message to the microcontroller over serial
 
        Args:
            message (str): Message to write the microcontroller
        """

        # If a serial connection exists
        if not self.ser == None:
            # Try to write the message
            try:
                self.ser.write(message)
                print(message)
            # Print an exception if one occurs
            except Exception as e:
                print('Error: {}'.format(e))

    def read_serial(self):
        """Read from the serial"""

        # If a serial connection exists
        if not self.ser == None:
            # Try to read
            try:
                # If there is an incoming message
                if self.ser.in_waiting:
                    # Read in one byte
                    self.s = self.ser.read()
                    # Update the GUI position with that value
                    self.serial_position.set(int(self.s))
                    print(int(self.s))
            # Catch an exception and print it
            except Exception as e:
                print('Error: {}'.format(e))

        # Put read serial back on a timer
        self.after(10, self.read_serial)

    def stop_gui(self):
        """Cleanup any option connections"""
        # Try to close out of the serial and the server
        try:
            self.server.stop()
            self.ser.close()
        # Print any exceptions that occur
        except Exception as e:
            print(e)
示例#15
0
class DUnits(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller = controller
        self.left_value = StringVar()  # the input on the left
        self.right_value = StringVar()  # the input on the right

        self.columnconfigure(0, weight=1, pad=5)
        self.columnconfigure(1, weight=1, pad=5)

        self.rowconfigure(0, pad=5)
        self.rowconfigure(1, pad=5)
        self.rowconfigure(2, pad=5)
        self.rowconfigure(3, weight=1, pad=5)

        # Title
        bbutton = Button(self,
                         text="<",
                         command=lambda: controller.show_frame("MainPage"))
        bbutton.grid(row=0, column=0, padx=10, sticky=W)
        title = Label(self, text="Digital Storage")
        title.grid(row=0, columnspan=4, padx=10)

        # Labels
        flabel = Label(self, text="From:")
        flabel.grid(row=1, column=0, padx=10, sticky=W)

        tlabel = Label(self, text="To:")
        tlabel.grid(row=1, column=1, padx=10, sticky=W)

        # In/Outputs
        self.left = Entry(self, textvariable=self.left_value)
        self.left.grid(row=2, column=0, padx=10, sticky=E + W)

        self.right = Entry(self, textvariable=self.right_value)
        self.right.grid(row=2, column=1, padx=10, sticky=E + W)

        # Options
        self.loptions = Listbox(self, exportselection=0)
        self.loptions.grid(row=3,
                           column=0,
                           padx=12,
                           pady=8,
                           sticky=N + E + S + W)
        self.roptions = Listbox(self, exportselection=0)
        self.roptions.grid(row=3,
                           column=1,
                           padx=12,
                           pady=8,
                           sticky=N + E + S + W)

        self.loptions.bind('<<ListboxSelect>>',
                           lambda a: self.update_outputs(1))
        self.roptions.bind('<<ListboxSelect>>',
                           lambda a: self.update_outputs(0))

        # Insert all keys in the dictionary in the listboxes
        units = [
            'bit', 'kilobit', 'kibibit', 'megabit', 'mebibit', 'gigabit',
            'gibibit', 'terabit', 'tebibit', 'petabit', 'pebibit', 'byte',
            'kilobyte', 'kibibyte', 'megabyte', 'mebibyte', 'gigabyte',
            'gibibyte', 'terabyte', 'tebibyte', 'petabyte', 'pebibyte'
        ]
        for x in units:
            self.loptions.insert('end', x)
            self.roptions.insert('end', x)

        self.loptions.select_set(0)  # select first item on the left
        self.roptions.select_set(0)  # select first item on the right

        # If the contents of an entry box change, update each box
        self.update_in_progress = False
        self.left_value.trace("w", lambda a, b, c: self.update_outputs(0))
        self.right_value.trace("w", lambda a, b, c: self.update_outputs(1))

    def update_outputs(self, *args):
        if self.update_in_progress:
            return
        try:
            self.update_in_progress = True
            temp_left = self.left_value.get()
            temp_right = self.right_value.get()

            lselection = self.loptions.curselection()
            left_units = self.loptions.get(lselection[0])
            rselection = self.roptions.curselection()
            right_units = self.roptions.get(rselection[0])

            if args[0] == 0:
                self.right_value.set(
                    convert_dunits(float(temp_left), left_units, right_units))
            else:
                self.left_value.set(
                    convert_dunits(float(temp_right), right_units, left_units))

        except ValueError:
            if args[0] == 0:
                self.right_value.set("Invalid input!")
            else:
                self.left_value.set("Invalid input!")
        except:
            print("Unexpected error:", sys.exc_info()[0])
            raise
        self.update_in_progress = False
示例#16
0
class Application(ttk.Frame):
    """The application, which is the main content frame in the root window."""
    def __init__(self, root=None, title='Cabinet Calc'):
        """Construct an Application object."""
        if root is None:
            # Create a new root window to be our master
            self.root = Tk()
        else:
            # Our master will be what was passed in as `root'
            self.root = root
        super().__init__(self.root, padding=5)
        # Instance variables
        self.root.title(title)
        self.jobname = StringVar()
        self.description = StringVar()
        self.fullwidth = StringVar()
        self.height = StringVar()
        self.depth = StringVar()
        self.fillers = StringVar()
        self.prim_material = StringVar()
        self.prim_thickness = StringVar()
        self.door_material = StringVar()
        self.door_thickness = StringVar()
        self.legs = StringVar()
        self.bottom_thickness = StringVar()
        self.btmpanel1_thickness = StringVar()
        self.btmpanel2_thickness = StringVar()
        self.stacked_btm = StringVar()
        self.btm_material = StringVar()
        self.doors_per_cab = IntVar()
        self.output = ''
        self.job = None
        self.initialize_vars()
        self.make_widgets()

    def initialize_vars(self):
        """Initialize all attributes to default vaules."""
        self.jobname.set('')
        self.description.set('')
        self.fullwidth.set('')
        self.height.set('')
        self.depth.set('')
        self.fillers.set('NEITHER')
        self.prim_material.set(MATERIALS[PRIM_MAT_DEFAULT])
        self.prim_thickness.set(MATL_THICKNESSES[self.prim_material.get()][0])
        self.door_material.set(MATERIALS[DOOR_MAT_DEFAULT])
        self.door_thickness.set(MATL_THICKNESSES[self.door_material.get()][0])
        self.legs.set('no')
        self.bottom_thickness.set('')
        self.btmpanel1_thickness.set('')
        self.btmpanel1_thickness.trace('w', self.btmpnl_thickness_changed)
        self.btmpanel2_thickness.set('')
        self.btmpanel2_thickness.trace('w', self.btmpnl_thickness_changed)
        self.stacked_btm.set('no')
        self.btm_material.set('')
        self.doors_per_cab.set(2)
        self.output = 'No job yet.'
        self.job = None

    def make_widgets(self):
        """Create and layout all the UI elements.

        Only the widgets that need to be refered to in other parts of the code
        are made as instance variables (with `self.').
        """
        ttk.Label(self,
                  text='The Custom Euro-Style Cabinet Configurator').grid(
                      column=0, row=0, sticky=W)
        inputframe = ttk.Labelframe(self,
                                    text='Parameters: ',
                                    borderwidth=2,
                                    relief='groove',
                                    padding=5)
        ttk.Label(self, text='Job Specification:').grid(column=0,
                                                        row=2,
                                                        sticky=W,
                                                        pady=2)
        outputframe = ttk.Frame(self, borderwidth=1, relief='sunken')
        outp_btnsframe = ttk.Frame(self, padding=(0, 10))
        self.grid(column=0, row=0, sticky=(N, S, W, E))
        inputframe.grid(column=0, row=1, sticky=(N, S, W, E), pady=10)
        outputframe.grid(column=0, row=3, sticky=(N, S, W, E))
        outp_btnsframe.grid(column=0, row=4, sticky=(N, S, W, E))
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(3, weight=1)
        self.fill_inputframe(inputframe)
        self.fill_outputframe(outputframe)
        self.fill_outp_btnsframe(outp_btnsframe)

    def fill_inputframe(self, inpframe):
        """Layout the widgets for gathering input in the input frame."""
        def make_jobframe():
            jobframe = ttk.Frame(inpframe, padding=(0, 5, 0, 10))
            jobframe.grid(column=0, row=0, sticky=(N, S, W, E))
            jobframe.columnconfigure(0, weight=0)
            jobframe.columnconfigure(1, weight=1)
            ttk.Label(jobframe, text='Job Name:').grid(column=0,
                                                       row=0,
                                                       pady=2,
                                                       sticky=W)
            self.jobname_ent = ttk.Entry(jobframe,
                                         textvariable=self.jobname,
                                         validate='key',
                                         validatecommand=(vcmd, '%P'))
            ttk.Label(jobframe, text='Description:').grid(column=0,
                                                          row=1,
                                                          pady=2,
                                                          sticky=W)
            self.descrip_ent = ttk.Entry(jobframe,
                                         textvariable=self.description,
                                         validate='key',
                                         validatecommand=(vcmd, '%P'))
            self.jobname_ent.grid(column=1,
                                  row=0,
                                  pady=2,
                                  sticky=(W, E),
                                  padx=(5, 0))
            self.descrip_ent.grid(column=1,
                                  row=1,
                                  pady=2,
                                  sticky=(W, E),
                                  padx=(5, 0))
            self.jobname_ent.focus_set()

        def make_dimframe():
            dimframe = ttk.Frame(inpframe, padding=(0, 10))
            dimframe.grid(column=0, row=1, sticky=(N, S, W, E))
            dimframe.columnconfigure(0, weight=0)
            dimframe.columnconfigure(1, weight=1)
            dimframe.columnconfigure(2, weight=0)
            dimframe.columnconfigure(3, weight=1)
            dimframe.columnconfigure(4, weight=0)
            dimframe.columnconfigure(5, weight=1)
            ttk.Label(dimframe, text='Width:').grid(column=0,
                                                    row=0,
                                                    sticky=W,
                                                    padx=(0, 3))
            self.fullwidth_ent = ttk.Entry(dimframe,
                                           width=10,
                                           textvariable=self.fullwidth,
                                           validate='key',
                                           validatecommand=(vcmd, '%P'))
            ttk.Label(dimframe, text='Height:').grid(column=2,
                                                     row=0,
                                                     sticky=E,
                                                     padx=(6, 3))
            self.height_ent = ttk.Entry(dimframe,
                                        width=10,
                                        textvariable=self.height,
                                        validate='key',
                                        validatecommand=(vcmd, '%P'))
            ttk.Label(dimframe, text='Depth:').grid(column=4,
                                                    row=0,
                                                    sticky=E,
                                                    padx=(6, 3))
            self.depth_ent = ttk.Entry(dimframe,
                                       width=10,
                                       textvariable=self.depth,
                                       validate='key',
                                       validatecommand=(vcmd, '%P'))
            self.fullwidth_ent.grid(column=1, row=0, sticky=(W, E), padx=3)
            self.height_ent.grid(column=3, row=0, sticky=(W, E), padx=3)
            self.depth_ent.grid(column=5, row=0, sticky=(W, E), padx=3)

        def make_miscframe():
            miscframe = ttk.Frame(inpframe, padding=(0, 5))
            miscframe.grid(column=0, row=2, sticky=(N, S, W, E))
            miscframe.columnconfigure(0, weight=0)
            miscframe.columnconfigure(1, weight=0)
            miscframe.columnconfigure(2, weight=0)
            miscframe.columnconfigure(3, weight=0)
            miscframe.columnconfigure(4, weight=1)
            miscframe.columnconfigure(5, weight=1)
            miscframe.columnconfigure(6, weight=1)
            ttk.Label(miscframe,
                      text='Fillers for which ends?').grid(column=0,
                                                           columnspan=2,
                                                           row=0,
                                                           sticky=W,
                                                           padx=(0, 2),
                                                           pady=2)
            ttk.Radiobutton(miscframe,
                            value='NEITHER',
                            text='Neither',
                            variable=self.fillers).grid(column=2,
                                                        row=0,
                                                        sticky=W,
                                                        padx=3,
                                                        pady=2)
            ttk.Radiobutton(miscframe,
                            value='LEFT',
                            text='Left',
                            variable=self.fillers).grid(column=3,
                                                        row=0,
                                                        sticky=W,
                                                        padx=3,
                                                        pady=2)
            ttk.Radiobutton(miscframe,
                            value='RIGHT',
                            text='Right',
                            variable=self.fillers).grid(column=4,
                                                        row=0,
                                                        sticky=W,
                                                        padx=3,
                                                        pady=2)
            ttk.Radiobutton(miscframe,
                            value='BOTH',
                            text='Both',
                            variable=self.fillers).grid(column=5,
                                                        row=0,
                                                        sticky=W,
                                                        padx=3,
                                                        pady=2)

            ttk.Label(miscframe, text='Material:').grid(column=1,
                                                        row=1,
                                                        sticky=(N, W),
                                                        padx=4,
                                                        pady=(15, 2))
            ttk.Label(miscframe, text='Thickness:').grid(column=2,
                                                         row=1,
                                                         sticky=W,
                                                         padx=4,
                                                         pady=(15, 2))

            ttk.Label(miscframe,
                      text='Measure actual material thickness to the\n'
                      'nearest 0.01" and adjust values accordingly.').grid(
                          column=3,
                          columnspan=3,
                          row=2,
                          rowspan=2,
                          sticky=(N, W),
                          padx=(8, 4),
                          pady=2)

            ttk.Label(miscframe, text='Primary:').grid(column=0,
                                                       row=2,
                                                       sticky=W,
                                                       padx=(0, 2),
                                                       pady=2)
            self.prim_material_cbx = ttk.Combobox(
                miscframe,
                textvariable=self.prim_material,
                width=max(map(len, MATERIALS)) - 2)
            self.prim_material_cbx['values'] = MATERIALS
            # Prevent direct editing of the value in the combobox:
            self.prim_material_cbx.state(['readonly'])
            # Call the `selection clear' method when the value changes. It looks
            # a bit odd visually without doing that.
            self.prim_material_cbx.bind('<<ComboboxSelected>>',
                                        self.prim_material_changed)
            self.prim_material_cbx.grid(column=1,
                                        row=2,
                                        sticky=W,
                                        padx=(6, 3),
                                        pady=2)
            ttk.Entry(miscframe, textvariable=self.prim_thickness,
                      width=6).grid(column=2, row=2, padx=6, pady=2)

            ttk.Label(miscframe, text='Doors:').grid(column=0,
                                                     row=3,
                                                     sticky=W,
                                                     padx=(0, 2),
                                                     pady=2)
            self.door_material_cbx = ttk.Combobox(
                miscframe,
                textvariable=self.door_material,
                width=max(map(len, MATERIALS)) - 2)
            self.door_material_cbx['values'] = MATERIALS
            # Prevent direct editing of the value in the combobox:
            self.door_material_cbx.state(['readonly'])
            # Call the `selection clear' method when the value changes. It looks
            # a bit odd visually without doing that.
            self.door_material_cbx.bind('<<ComboboxSelected>>',
                                        self.door_material_changed)
            self.door_material_cbx.grid(column=1,
                                        row=3,
                                        sticky=W,
                                        padx=(6, 3),
                                        pady=2)

            # ttk.Label(miscframe, text='Thickness:').grid(
            #     column=4, row=3, sticky=E, padx=4, pady=2)
            ttk.Entry(miscframe, textvariable=self.door_thickness,
                      width=6).grid(column=2, row=3, padx=6, pady=2)

            self.legs_thicker_btm_lbl = ttk.Label(
                miscframe,
                text='Mounting legs requires bottoms thicker than\n'
                '3/4" so that leg mounting screws will grab.')
            self.legs_thicker_btm_lbl.state(['disabled'])
            self.legs_thicker_btm_lbl.grid(column=3,
                                           columnspan=3,
                                           row=7,
                                           rowspan=2,
                                           sticky=(N, W),
                                           padx=(8, 4),
                                           pady=2)

            ttk.Checkbutton(miscframe,
                            text='Mount legs on cabinets.',
                            variable=self.legs,
                            command=self.legs_changed,
                            onvalue='yes',
                            offvalue='no').grid(column=0,
                                                columnspan=3,
                                                row=6,
                                                sticky=W,
                                                padx=2,
                                                pady=(15, 2))

            self.bottoms_lbl = ttk.Label(miscframe, text='Bottoms:')
            self.bottoms_lbl.state(['disabled'])
            self.bottoms_lbl.grid(column=0,
                                  row=9,
                                  sticky=W,
                                  padx=2,
                                  pady=(6, 2))
            self.btm_material_lbl = ttk.Label(miscframe,
                                              textvariable=self.btm_material,
                                              width=max(map(len, MATERIALS)) -
                                              2)
            self.btm_material_lbl.grid(column=1,
                                       row=9,
                                       sticky=W,
                                       padx=2,
                                       pady=(6, 2))
            self.bottom_thickness_ent = ttk.Entry(
                miscframe, textvariable=self.bottom_thickness, width=6)
            self.bottom_thickness_ent.state(['disabled'])
            self.bottom_thickness_ent.grid(column=2,
                                           row=9,
                                           padx=6,
                                           pady=(6, 2))

            self.stacked_btm_chk = ttk.Checkbutton(
                miscframe,
                text='Stack bottom panels:',
                variable=self.stacked_btm,
                command=self.stacked_btm_changed,
                onvalue='yes',
                offvalue='no')
            self.stacked_btm_chk.state(['disabled'])
            self.stacked_btm_chk.grid(column=0,
                                      columnspan=2,
                                      row=7,
                                      sticky=W,
                                      padx=(25, 2),
                                      pady=2)

            #            ttk.Label(miscframe, text='Upper panel:').grid(
            #                column=1, row=7, sticky=W, padx=(10, 2), pady=2)
            self.btmpanel1_thickness_ent = ttk.Entry(
                miscframe, textvariable=self.btmpanel1_thickness, width=6)
            self.btmpanel1_thickness_ent.state(['disabled'])
            self.btmpanel1_thickness_ent.grid(column=2, row=7, padx=6, pady=2)

            #            ttk.Label(miscframe, text='Lower panel:').grid(
            #                column=1, row=8, sticky=W, padx=(10, 2), pady=2)
            self.btmpanel2_thickness_ent = ttk.Entry(
                miscframe, textvariable=self.btmpanel2_thickness, width=6)
            self.btmpanel2_thickness_ent.state(['disabled'])
            self.btmpanel2_thickness_ent.grid(column=2, row=8, padx=6, pady=2)

            ttk.Label(miscframe, text='Doors per Cabinet:').grid(column=0,
                                                                 columnspan=2,
                                                                 row=10,
                                                                 sticky=W,
                                                                 padx=(0, 6),
                                                                 pady=(15, 2))
            drs_per_cab_rb1 = ttk.Radiobutton(miscframe,
                                              value=1,
                                              text='1',
                                              variable=self.doors_per_cab)
            # Do not allow selection of one door per cabinet. This can only be
            # enabled after major code changes throughout, to allow for upper
            # cabinet banks, variable height/width cabinets, etc.
            drs_per_cab_rb1.state(['disabled'])
            drs_per_cab_rb1.grid(column=2,
                                 row=10,
                                 sticky=W,
                                 padx=3,
                                 pady=(15, 2))
            ttk.Radiobutton(miscframe,
                            value=2,
                            text='2',
                            variable=self.doors_per_cab).grid(column=3,
                                                              row=10,
                                                              sticky=W,
                                                              padx=3,
                                                              pady=(15, 2))

        def make_buttonframe():
            buttonframe = ttk.Frame(inpframe, padding=(0, 12, 0, 0))
            buttonframe.grid(column=0, row=3, sticky=(N, S, W, E))
            buttonframe.columnconfigure(0, weight=1)
            buttonframe.columnconfigure(1, weight=1)
            buttonframe.columnconfigure(2, weight=1)
            buttonframe.rowconfigure(0, weight=1)
            self.calc_button = ttk.Button(buttonframe,
                                          text='Calculate',
                                          command=self.calculate_job)
            self.calc_button.state(['disabled'])
            clear_button = ttk.Button(buttonframe,
                                      text='Clear',
                                      command=self.clear_input)
            quit_button = ttk.Button(buttonframe,
                                     text='Quit',
                                     command=self.quit)
            self.calc_button.grid(column=0, row=0, sticky=E, padx=2)
            clear_button.grid(column=1, row=0, sticky=W, padx=2)
            quit_button.grid(column=2, row=0, padx=2)

        # Register our validate function to get its function ID. This is used
        # to disable the `Calculate' button if the fields necessary for
        # calculation are not filled in.
        vcmd = self.root.register(self.validate_entry)
        make_jobframe()
        make_dimframe()
        make_miscframe()
        make_buttonframe()
        inpframe.columnconfigure(0, weight=1)

    def fill_outputframe(self, outpframe):
        """Layout the widgets for showing output in the output frame."""
        # self.output_lbl = ttk.Label(outpframe, textvariable=self.output,
        #                             font='TkFixedFont')
        # self.output_lbl.grid(column=0, row=0, sticky=(N, S, E, W), pady=(0, 50))
        outpframe.columnconfigure(0, weight=1)
        outpframe.columnconfigure(1, weight=0)
        outpframe.rowconfigure(0, weight=1)
        self.output_txt = Text(outpframe,
                               height=3,
                               relief='flat',
                               background='gray85',
                               font='TkFixedFont')
        self.output_sb = ttk.Scrollbar(outpframe,
                                       orient='vertical',
                                       command=self.output_txt.yview)
        self.output_txt.configure(yscrollcommand=self.output_sb.set)
        self.output_txt.grid(column=0, row=0, sticky=(N, S, W, E))
        self.output_sb.grid(column=1, row=0, sticky=(N, S, E))
        self.output_txt.insert('end', self.output)
        self.output_txt.configure(state='disabled')

    def fill_outp_btnsframe(self, outp_btnsframe):
        """Layout the output-dependent buttons in the output buttons frame."""
        outp_btnsframe.columnconfigure(0, weight=1)
        outp_btnsframe.columnconfigure(1, weight=1)
        outp_btnsframe.rowconfigure(0, weight=1)
        self.cutlist_button = ttk.Button(outp_btnsframe,
                                         text='Save Cutlist',
                                         command=self.save_cutlist)
        self.cutlist_button.state(['disabled'])
        self.panel_layout_btn = ttk.Button(outp_btnsframe,
                                           text='Optimize Panel Layout',
                                           command=self.optimize_panel_layout)
        self.panel_layout_btn.state(['disabled'])
        self.cutlist_button.grid(column=0, row=0, sticky=E, padx=2)
        self.panel_layout_btn.grid(column=1, row=0, sticky=W, padx=2)

    def validate_entry(self, value):
        """Enable the 'Calculate' button only when we have enough info."""
        if self.have_enough_info():
            self.calc_button.state(['!disabled'])
        else:
            self.calc_button.state(['disabled'])
        return True

    def have_enough_info(self):
        """Return True if we have enough info to calculate a job, False otherwise."""
        result = (self.jobname_ent.get() != ''
                  and self.fullwidth_ent.get() != ''
                  and self.height_ent.get() != ''
                  and self.depth_ent.get() != '')
        return result

    def prim_material_changed(self, e):
        """Handle the changing of the primary build material for the job."""
        self.prim_thickness.set(MATL_THICKNESSES[self.prim_material.get()][0])
        self.prim_material_cbx.selection_clear()
        if self.legs.get() == 'yes':
            self.btm_material.set(self.prim_material.get())
            btm_thicknesses = MATL_THICKNESSES[self.prim_material.get()][1]
            self.bottom_thickness.set(sum(btm_thicknesses))
            if len(btm_thicknesses) > 1:
                self.stacked_btm.set('yes')
                self.btmpanel1_thickness.set(btm_thicknesses[0])
                self.btmpanel1_thickness_ent.state(['!disabled'])
                self.btmpanel2_thickness.set(btm_thicknesses[1])
                self.btmpanel2_thickness_ent.state(['!disabled'])
                self.bottom_thickness_ent.state(['disabled'])
            else:
                self.stacked_btm.set('no')
                self.btmpanel1_thickness.set('')
                self.btmpanel1_thickness_ent.state(['disabled'])
                self.btmpanel2_thickness.set('')
                self.btmpanel2_thickness_ent.state(['disabled'])
                self.bottom_thickness_ent.state(['!disabled'])

    def door_material_changed(self, e):
        """Handle the changing of the door material for the job."""
        self.door_thickness.set(MATL_THICKNESSES[self.door_material.get()][0])
        self.door_material_cbx.selection_clear()

    def legs_changed(self):
        """Handle the changing of whether the cabinets will have legs or not."""
        if self.legs.get() == 'yes':
            self.legs_thicker_btm_lbl.state(['!disabled'])
            self.bottoms_lbl.state(['!disabled'])
            self.btm_material.set(self.prim_material.get())
            btm_thicknesses = MATL_THICKNESSES[self.prim_material.get()][1]
            self.bottom_thickness.set(sum(btm_thicknesses))
            self.bottom_thickness_ent.state(['!disabled'])
            self.stacked_btm.set('no')
            self.stacked_btm_chk.state(['!disabled'])
            if len(btm_thicknesses) > 1:
                self.stacked_btm.set('yes')
                self.btmpanel1_thickness.set(btm_thicknesses[0])
                self.btmpanel1_thickness_ent.state(['!disabled'])
                self.btmpanel2_thickness.set(btm_thicknesses[1])
                self.btmpanel2_thickness_ent.state(['!disabled'])
                self.bottom_thickness_ent.state(['disabled'])
        else:
            self.legs_thicker_btm_lbl.state(['disabled'])
            self.bottoms_lbl.state(['disabled'])
            self.btm_material.set('')
            self.bottom_thickness.set('')
            self.bottom_thickness_ent.state(['disabled'])
            self.btmpanel1_thickness.set('')
            self.btmpanel1_thickness_ent.state(['disabled'])
            self.btmpanel2_thickness.set('')
            self.btmpanel2_thickness_ent.state(['disabled'])
            self.stacked_btm.set('no')
            self.stacked_btm_chk.state(['disabled'])

    def stacked_btm_changed(self):
        """Handle the changing of whether cabinet bottoms will be stacked or not."""
        if self.stacked_btm.get() == 'yes':
            half_btm = float(self.bottom_thickness.get()) / 2
            self.btmpanel1_thickness_ent.state(['!disabled'])
            self.btmpanel1_thickness.set(half_btm)
            self.btmpanel2_thickness_ent.state(['!disabled'])
            self.btmpanel2_thickness.set(half_btm)
            self.bottom_thickness_ent.state(['disabled'])
        else:
            self.btmpanel1_thickness.set('')
            self.btmpanel1_thickness_ent.state(['disabled'])
            self.btmpanel2_thickness.set('')
            self.btmpanel2_thickness_ent.state(['disabled'])
            self.bottom_thickness_ent.state(['!disabled'])

    def btmpnl_thickness_changed(self, *args):
        """Handle the changing of the thickness of cabinet bottom panels."""
        if self.stacked_btm.get() == 'yes':
            if self.btmpanel1_thickness.get() == '':
                bp1 = 0.0
            else:
                bp1 = float(self.btmpanel1_thickness.get())
            if self.btmpanel2_thickness.get() == '':
                bp2 = 0.0
            else:
                bp2 = float(self.btmpanel2_thickness.get())
            new_thickness = bp1 + bp2
            if new_thickness == 0.0:
                thickness_str = ''
            else:
                thickness_str = str(new_thickness)
            self.bottom_thickness.set(thickness_str)

    def quit(self):
        """Quit the app; accomplished by destroying its top-level window."""
        self.root.destroy()

    def clear_input(self):
        """Clear and reset all input widgets to default values."""
        self.initialize_vars()
        self.legs_thicker_btm_lbl.state(['disabled'])
        self.bottoms_lbl.state(['disabled'])
        self.bottom_thickness_ent.state(['disabled'])
        self.btmpanel1_thickness_ent.state(['disabled'])
        self.btmpanel2_thickness_ent.state(['disabled'])
        self.stacked_btm_chk.state(['disabled'])
        self.calc_button.state(['disabled'])
        self.cutlist_button.state(['disabled'])
        self.panel_layout_btn.state(['disabled'])
        self.output_txt.configure(state='normal', height=3)
        self.output_txt.delete('1.0', 'end')
        self.output_txt.insert('end', self.output)
        self.output_txt.configure(state='disabled')

    def calculate_job(self):
        """Calculate a job, given all input parameters."""
        if self.legs.get() == 'no':
            bp_list = [float(self.prim_thickness.get())]
        else:
            if self.stacked_btm.get() == 'yes':
                bp1 = float(self.btmpanel1_thickness.get())
                bp2 = float(self.btmpanel2_thickness.get())
                bp_list = [bp1, bp2]
            else:
                bt = float(self.bottom_thickness.get())
                bp_list = [bt]
        cab_run = Run(float(self.fullwidth.get()),
                      float(self.height.get()),
                      float(self.depth.get()),
                      fillers=Ends.from_string(self.fillers.get()),
                      prim_material=self.prim_material.get(),
                      prim_thickness=float(self.prim_thickness.get()),
                      door_material=self.door_material.get(),
                      door_thickness=float(self.door_thickness.get()),
                      btmpanel_thicknesses=bp_list,
                      has_legs=yn_to_bool(self.legs.get()))
        if self.description.get() != '':
            self.job = job.Job(self.jobname.get(), cab_run,
                               self.description.get())
        else:
            self.job = job.Job(self.jobname.get(), cab_run)
        # Display the computed job specification, ensuring output lines are no
        # longer than 65 chars.
        self.output = ''
        for line in self.job.specification:
            self.output += textwrap.fill(line, width=65) + '\n'
        lines = self.output.count('\n') + 1
        self.output_txt.configure(state='normal')
        self.output_txt.delete('1.0', 'end')
        self.output_txt.insert('end', self.output)
        self.output_txt.configure(state='disabled', height=lines + 1)
        # self.output_txt.grid_configure(pady=0)
        self.cutlist_button.state(['!disabled'])

    def save_cutlist(self):
        """Generate a cutlist pdf for the job and save it in a file."""
        filename = filedialog.asksaveasfilename(
            title='Filename to Save Cutlist As',
            parent=self.root,
            filetypes=(('PDF Files', '*.pdf'), ('All Files', '*')))
        if filename != '':
            cutlist.save_cutlist(filename, self.job)

    def optimize_panel_layout(self):
        """Optimize the panel layout."""
        pass
示例#17
0
class FilePick(Frame):
    def __init__(self, master, file_mask, default_file, user_onChange = None, font = None, dirs = (".", ), allowNone = False):
        """ file_mask: file mask or list of file masks """
        self.master = master
        self.user_onChange = user_onChange
        Frame.__init__(self, master)
        self.columnconfigure(0, weight=1)
        self.unmodified = True
        self.file_extension = ""
        if "." in file_mask:
            self.file_extension = file_mask[file_mask.rfind('.'):]
        if type(file_mask) != list:
            file_mask = [file_mask]
        self.file_masks = file_mask
        self.allowNone = allowNone
        self.dirs = dirs
        # create list of files
        self.updateList()
        # pick default if applicable
        self.set(default_file)

    def onSelChange(self, name, index=0, mode=0):
        filename = self.picked_name.get()
        if self.user_onChange != None:
            self.user_onChange(filename)

    def updateList(self):
        prev_sel = self.get()
        # get list of files (paths)
        self.files = []
        if self.allowNone:
            self.files.append("")
        for fm in self.file_masks:
            for dir in self.dirs:
                try:
                    for filename in os.listdir(dir):
                        if fnmatch(filename, fm):
                            if dir != ".":
                                path = os.path.join(dir, filename)
                            else:
                                path = filename
                            self.files.append(path)
                except:
                    pass
        self.files.sort()
        if len(self.files) == 0: self.files.append("(no %s files found)" %  self.file_masks)
        # create list object
        self._makelist()
        # reselect
        self.set(prev_sel)

    def getList(self):
        """ returns the current list of files """
        return self.files

    def _makelist(self):
        if havePMW:
            self.list = ComboBox(self,
                    selectioncommand = self.onSelChange,
                    scrolledlist_items = self.files,
            )
            self.list.grid(row=0, column=0, padx=0, sticky="NEWS")
            self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised')
            self.picked_name = self.list
        else:
            self.picked_name = StringVar()
            self.list = OptionMenu(*(self, self.picked_name) + tuple(self.files))
            self.list.grid(row=0, column=0, sticky="NEW")
            self.picked_name.trace("w", self.onSelChange)

    def set(self, filename):
        default_file = filename
        if default_file in self.files:
            if not havePMW:
                self.picked_name.set(default_file) # default value
            else:
                self.list.selectitem(self.files.index(default_file))
                self.onSelChange(default_file)
                pass

    def get(self):
        if not hasattr(self, 'picked_name'):
            return None
        return self.picked_name.get()
示例#18
0
class Plastey(Tk):

    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)

        # Set window title
        self.wm_title('Plastey Configurator')

        # Create GUI driven variables
        self._mode       = BooleanVar()
        self._base       = BooleanVar()
        self._comm       = BooleanVar()
        self._pass       = StringVar()
        self._addressed  = StringVar()
        self._connected  = StringVar()
        self._this_host  = StringVar()
        self._this_port  = StringVar()
        self._other_host = StringVar()
        self._other_port = StringVar()

        # Create GUI
        self._build_gui()

        # Set default values for GUI driven variables
        self._mode.set(MODE_SINGLE_PLAYER)
        self._base.set(BASE_OPENED_GEOMETRY)
        self._comm.set(COMM_SOCKET_SERVER)
        self._pass.set('')
        self._addressed.set(ADDR_HAVE_ADDRESS if check(COMM_THIS_HOST) else ADDR_NO_ADDRESS)
        self._connected.set(CONN_NOT_CONNECTED)
        self._this_host.set(COMM_THIS_HOST)
        self._this_port.set(COMM_THIS_PORT)
        self._other_host.set(COMM_THIS_HOST)
        self._other_port.set(COMM_OTHER_PORT)

        # Follow changes on password
        self._pass.trace('w', self._on_bind_address)

        # Create folder structures if they don't exists yet
        makedirs(FILE_TEMPORARY_FOLDER,  exist_ok=True)
        makedirs(FILE_PERMANENT_FOLDER,  exist_ok=True)
        makedirs(FILE_TEMP_SAVE_FOLDER,  exist_ok=True)
        makedirs(FILE_AUTO_SAVE_FOLDER,  exist_ok=True)
        #makedirs(FILE_TEMP_STATE_FOLDER, exist_ok=True)
        #makedirs(FILE_TEMP_FEEDS_FOLDER, exist_ok=True)


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _build_gui(self):
        # Create GUI sections
        row = 0
        col = 0

        # Warning text
        Label(master  = self,
              text    = WARN_TEXT,
              anchor  = WEST,
              justify = CENTER).grid(row     = row,
                                     column  = col,
                                     sticky  = NORTH_WEST,
                                     rowspan = 16)

        # Set column spacing
        self.columnconfigure(index = col,
                             pad   = GUI_SECTION_PAD_X)
        row  = 0
        col += 1

        # Game mode options
        Label(master = self,
              text   = 'Game Mode:').grid(row    = row,
                                          column = col,
                                          sticky = WEST)
        row += 1
        Radiobutton(master   = self,
                    text     = 'Single Player',
                    value    = MODE_SINGLE_PLAYER,
                    variable = self._mode).grid(row    = row,
                                                column = col,
                                                sticky = WEST)
        row += 1
        Radiobutton(master   = self,
                    text     = 'Multi Player',
                    value    = MODE_MULTI_PLAYER,
                    variable = self._mode).grid(row    = row,
                                                column = col,
                                                sticky = WEST)
        row += 1

        # Base object modes
        Label(master = self,
              text   = 'Base Object:').grid(row    = row,
                                            column = col,
                                            sticky = WEST)
        row += 1
        Radiobutton(master   = self,
                    text     = 'Plane mesh',
                    value    = BASE_OPENED_GEOMETRY,
                    variable = self._base).grid(row    = row,
                                                column = col,
                                                sticky = WEST)
        row += 1
        Radiobutton(master   = self,
                    text     = 'Sphere mesh',
                    value    = BASE_CLOSED_GEOMETRY,
                    variable = self._base).grid(row    = row,
                                                column = col,
                                                sticky = WEST)
        row += 1

        # Start oculus-daemon
        Label(master = self,
              text   = 'Daemons:').grid(row    = row,
                                        column = col,
                                        sticky = WEST)
        row += 1
        Button(master  = self,
               text    = 'Start OVRD',
               command = self._on_start_oculus_daemon).grid(row    = row,
                                                            column = col,
                                                            sticky = WEST)

        # Set column spacing
        self.columnconfigure(index = col,
                             pad   = GUI_SECTION_PAD_X)
        row  = 0
        col += 1

        # Multiplayer mode options
        Label(master = self,
              text   = 'Multi Player Options:').grid(row        = row,
                                                     column     = col,
                                                     sticky     = WEST,
                                                     columnspan = 2)
        row += 1

        Label(master = self,
              text   = 'This role:').grid(row    = row,
                                          column = col,
                                          sticky = WEST)
        Radiobutton(master   = self,
                    text     = 'Server',
                    value    = COMM_SOCKET_SERVER,
                    variable = self._comm).grid(row    = row,
                                                column = col + 1,
                                                sticky = WEST)
        row += 1
        Radiobutton(master   = self,
                    text     = 'Client',
                    value    = COMM_SOCKET_CLIENT,
                    variable = self._comm).grid(row    = row,
                                                column = col + 1,
                                                sticky = WEST)
        row += 1

        Label(master = self,
              text   = 'This host:').grid(row    = row,
                                          column = col,
                                          sticky = WEST)
        Entry(master       = self,
              textvariable = self._this_host).grid(row    = row,
                                                   column = col + 1,
                                                   sticky = WEST)
        row += 1
        Label(master = self,
              text   = 'This port:').grid(row    = row,
                                          column = col,
                                          sticky = WEST)
        Entry(master       = self,
              textvariable = self._this_port).grid(row    = row,
                                                   column = col + 1,
                                                   sticky = WEST)
        row += 1

        Label(master = self,
              text   = 'Other host:').grid(row    = row,
                                           column = col,
                                           sticky = WEST)
        Entry(master       = self,
              textvariable = self._other_host).grid(row    = row,
                                                    column = col + 1,
                                                    sticky = WEST)
        row += 1
        Label(master = self,
              text   = 'Other port:').grid(row    = row,
                                           column = col,
                                           sticky = WEST)
        Entry(master       = self,
              textvariable = self._other_port).grid(row    = row,
                                                    column = col + 1,
                                                    sticky = WEST)
        row += 1

        Button(master  = self,
               text    = 'Bind address',
               command = self._on_ask_password).grid(row        = row,
                                                     column     = col,
                                                     sticky     = WEST + EAST)
        Label(master       = self,
              textvariable = self._addressed).grid(row    = row,
                                                   column = col + 1,
                                                   sticky = WEST)
        row += 1
        Button(master  = self,
               text    = 'Connect machines',
               command = self._on_bind_address).grid(row        = row,
                                                     column     = col,
                                                     sticky     = WEST + EAST)
        Label(master       = self,
              textvariable = self._connected).grid(row    = row,
                                                   column = col + 1,
                                                   sticky = WEST)

        # Set column spacing
        self.columnconfigure(index = col + 1,
                             pad   = GUI_SECTION_PAD_X)
        row  = 0
        col += 2

        # Controller buttons
        Label(master = self,
              text   = 'Controllers:').grid(row    = row,
                                            column = col,
                                            sticky = WEST)
        row += 1
        Button(master  = self,
               text    = 'Start game',
               command = self._on_start_game).grid(row    = row,
                                                   column = col,
                                                   sticky = WEST + EAST)
        row += 1
        Button(master  = self,
               text    = 'Restart game',
               command = self._on_restart_game).grid(row    = row,
                                                     column = col,
                                                     sticky = WEST + EAST)
        row += 1
        Button(master  = self,
               text    = 'Stop game',
               command = self._on_stop_game).grid(row    = row,
                                                  column = col,
                                                  sticky = WEST + EAST)
        row += 1
        Button(master  = self,
               text    = 'Save last mesh',
               command = self._on_save_mesh).grid(row    = row,
                                                  column = col,
                                                  sticky = WEST + EAST)
        row += 1
        Button(master  = self,
               text    = 'Load last mesh',
               command = self._on_load_mesh).grid(row    = row,
                                                  column = col,
                                                  sticky = WEST + EAST)
        row += 1
        Button(master  = self,
               text    = 'Save log file',
               command = self._on_save_log).grid(row     = row,
                                                  column = col,
                                                  sticky = WEST + EAST)
        row += 1


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_ask_password(self, *args, **kwargs):
        # Create a password-dialog
        self._dialog = Password(self._pass)


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_start_oculus_daemon(self, *args, **kwargs):
        print('starting daemon...')


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_bind_address(self, *args, **kwargs):
        # Check for status and if address is not bound
        if not check(COMM_THIS_HOST):
            # Bind address
            try:
                setup(self._this_host, user_pass=self._pass.get())
            except CommunicationSetupError as exception:
                Report(exception.error)
            # Check status and report to user
            self._addressed.set(ADDR_HAVE_ADDRESS if check(COMM_THIS_HOST)
                                                  else ADDR_NO_ADDRESS)


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_connect(self, *args, **kwargs):
        pass


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_start_game(self, *args, **kwargs):
        # HACK: Is this really the best option we have, to get into fullscreen,
        #       other than using the blender's fullscreen option, which will
        #       unfortunately resize the display's resolution??? :(
        window_command = ['sleep 1']
        window_command.append('wmctrl -r :ACTIVE: '
                              '-e 0,{},{},{},{}'.format(DRAW_DISPLAY_X,
                                                        DRAW_DISPLAY_Y,
                                                        DRAW_RESOLUTION_X,
                                                        DRAW_RESOLUTION_Y))
        if DRAW_FULL_SCREEN:
            window_command.append('wmctrl -r :ACTIVE: -b add,fullscreen')

        Popen(args   = ' && '.join(window_command),
              shell  = True,
              stdin  = PIPE,
              stderr = PIPE,
              universal_newlines=True)

        # Store subprocess, for further communication
        self._pipe = Popen(args   = './plastey',
                           stdin  = PIPE,
                           stdout = PIPE,
                           stderr = PIPE,
                           universal_newlines=True)


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_restart_game(self, *args, **kwargs):
        self._pipe.stdin.write('hello-world\n')
        #if not self._locked:
        #    self._locked = True
        #    with open(FILE_STATE_RESTART, mode='w') as file:
        #        file.write('')
        #    Thread(name   = 'feedbackd-restart',
        #           target = self._get_feedback_to_clean_up).start()


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_stop_game(self, *args, **kwargs):
        #if not self._locked:
        #    self._locked = True
        #    with open(FILE_STATE_SHUT_DOWN, mode='w') as file:
        #        file.write('')
        #    Thread(name   = 'feedbackd-shutdown',
        #           target = self._get_feedback_to_clean_up).start()
        self._pipe.communicate('hello-world\n')


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_save_mesh(self, *args, **kwargs):
        pass
        #if self._pipe.poll():
        #    print('saving inside game')
        #else:
        #    print('save last auto-saved')

        #print('parent says: hey there, daemon!\n')
        #self._pipe.stdin.write('hey there, daemon!\n')

        #self._pipe.stdin.close()
        #try:
        #    self._pipe.communicate('hey there, daemon!\n', timeout=0.1)
        ## Hack: since communicate waits for the subprocess to terminate, the
        ##       timeout value is necessary, however, after the timeout, the app
        ##       won't terminate either. One solution should be
        ##       self._pipe.stdin.write instead of the communicate method, but
        ##       unfortunately the process's stdin.read/input are not getting
        ##       anything.. is it because the value set to shell=True?
        #except TimeoutExpired:
        #    return


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_load_mesh(self, *args, **kwargs):
        pass


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def _on_save_log(self, *args, **kwargs):
        pass


    #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
    def run(self):
        self.mainloop()
示例#19
0
class PlaylistControl(Frame):
    def __init__(self, w, *args, **kwargs):
        self.EMPTY_SEARCH_TEXT = _(
            "Search song...")  #After defined _ by gettext

        self.playlist = w.playlist

        super().__init__(w, *args, **kwargs)

        #___

        self.playlist_handler_edit = TkButtonImgHoverBg(
            self,
            command=lambda: TopLevelPlaylistEdit(self)
            if config.general["playlist"] != "" else None,
            imgs=(PhotoImage(data=b64img.btn_configplaylist), ),
            bg=config.colors["BG"],
            bg_on_hover=config.colors["BTN_BG_HOVER"])
        self.playlist_handler_edit.grid(row=0, column=0, sticky="nsew")

        #___

        self.playlist_handler_set = PlaylistHandlerSet(self)
        self.playlist_handler_set.grid(row=0,
                                       column=1,
                                       sticky="nsew",
                                       padx=(5, 8),
                                       pady=5)

        #___

        #When the text is changed, the search function will be called
        self.state_entry_search = StringVar()
        self.state_entry_search.trace('w', self._search)

        self.entry_search = Entry(self,
                                  width=15,
                                  textvariable=self.state_entry_search)
        self.entry_search.grid(row=0, column=2, sticky="nsew", pady=5)

        self.entry_search.insert(0, self.EMPTY_SEARCH_TEXT)
        self.entry_search.bind("<FocusIn>", self._entryFocusEnter)
        self.entry_search.bind("<FocusOut>", self._entryFocusLeave)

        #___

        self.btn_search = TkButtonImgHoverBg(
            self,
            command=self._entryClear,
            imgs=(PhotoImage(data=b64img.btn_quitsearch), ),
            bg=config.colors["BG"],
            bg_on_hover=config.colors["BTN_BG_HOVER"])
        self.btn_search.grid(row=0,
                             column=3,
                             sticky="nsew",
                             padx=(0, 5),
                             pady=5)

        #___

        self.btn_sorttitle = TkButtonImgHoverBg(
            self,
            command=lambda: self._sortPlaylist(self.btn_sorttitle, "title"),
            imgs=(PhotoImage(data=b64img.btn_sorttitle),
                  PhotoImage(data=b64img.btn_sorttitle_up),
                  PhotoImage(data=b64img.btn_sorttitle_down)),
            bg=config.colors["BG"],
            bg_on_hover=config.colors["BTN_BG_HOVER"])
        self.btn_sorttitle.grid(row=0, column=4, sticky="nsew")

        #___

        self.btn_sortdate = TkButtonImgHoverBg(
            self,
            command=lambda: self._sortPlaylist(self.btn_sortdate, "date"),
            imgs=(PhotoImage(data=b64img.btn_sortdate),
                  PhotoImage(data=b64img.btn_sortdate_up),
                  PhotoImage(data=b64img.btn_sortdate_down)),
            bg=config.colors["BG"],
            bg_on_hover=config.colors["BTN_BG_HOVER"],
            change_img_on_click=True)
        self.btn_sortdate.grid(row=0, column=5, sticky="nsew")

        #___

        self.btn_sorttime = TkButtonImgHoverBg(
            self,
            command=lambda: self._sortPlaylist(self.btn_sorttime, "time"),
            imgs=(PhotoImage(data=b64img.btn_sorttime),
                  PhotoImage(data=b64img.btn_sorttime_up),
                  PhotoImage(data=b64img.btn_sorttime_down)),
            bg=config.colors["BG"],
            bg_on_hover=config.colors["BTN_BG_HOVER"],
            change_img_on_click=True)
        self.btn_sorttime.grid(row=0, column=6, sticky="nsew")

        #___

        self.btn_sorttitle.set_img(1)
        self.__btn_sort_active: Tuple[TkButtonImgHoverBg,
                                      str] = [self.btn_sorttitle, 1]

    #__________________________________________________

    def _entryFocusEnter(self, _event):
        #Delete default text
        if self.entry_search.get() == self.EMPTY_SEARCH_TEXT:
            self.entry_search.delete(0, "end")

    def _entryFocusLeave(self, _event):
        #Delete text and insert default text if is invalid text
        if not validEntryText(self.entry_search.get()):
            self.entry_search.delete(0, "end")
            self.entry_search.insert(0, self.EMPTY_SEARCH_TEXT)
            config.playlist["filter"] = ""

    def _entryClear(self):
        #Delete text and insert default text if there is no focus
        if self.entry_search.get() != self.EMPTY_SEARCH_TEXT:
            self.entry_search.delete(0, "end")
            config.playlist["filter"] = ""
            if self.focus_get() != self.entry_search:
                self.entry_search.insert(0, self.EMPTY_SEARCH_TEXT)

    def _search(self, *_event):
        song_name = self.state_entry_search.get()
        if song_name != self.EMPTY_SEARCH_TEXT:
            self.playlist.filterName(song_name)
            config.playlist["filter"] = song_name

    def setSearch(self, song_name: str):
        if validEntryText(song_name):
            self.entry_search.delete(0, "end")
            self.entry_search.insert(0, song_name)
        else:
            self._entryClear()

    #___

    def _sortPlaylist(self, btn: TkButtonImgHoverBg, atr: str):
        #If click on another sort btn
        if btn != self.__btn_sort_active[0]:
            self.__btn_sort_active[0].set_img(0)  #Previous btn to normal
            if btn == self.btn_sorttitle:
                btn.set_img(
                    1)  #Set title btn to up, the others are set automatically
            self.__btn_sort_active = [btn, 1]  #Status is updated
            self.playlist.sortBy(atr, False)
            config.playlist["orderby"] = [atr, 1]

        #If click on the same sort btn
        else:
            #If the btn was in up
            if self.__btn_sort_active[1] == 1:
                if btn == self.btn_sorttitle:
                    btn.set_img(
                        2
                    )  #Set title btn to down, the others are set automatically
                self.__btn_sort_active[1] = 2  #Status is updated
                self.playlist.sortBy(atr, True)
                config.playlist["orderby"] = [atr, 2]

            #If the btn was in down
            elif self.__btn_sort_active[1] == 2:
                self.btn_sorttitle.set_img(
                    1
                )  #Set title btn to down, the others are set automatically
                self.__btn_sort_active = [self.btn_sorttitle,
                                          1]  #Status is updated
                self.playlist.sortBy("title", False)
                config.playlist["orderby"] = ["title", 1]

    def sortPlaylistForced(self, atr: str, order: int):
        if atr == "date":
            self.btn_sortdate.set_img(order)
            self.btn_sorttitle.set_img(0)
            self.btn_sorttime.set_img(0)
            self.__btn_sort_active[0] = self.btn_sortdate

        elif atr == "time":
            self.btn_sorttime.set_img(order)
            self.btn_sorttitle.set_img(0)
            self.btn_sortdate.set_img(0)
            self.__btn_sort_active[0] = self.btn_sorttime

        else:
            self.btn_sorttitle.set_img(order)
            self.btn_sortdate.set_img(0)
            self.btn_sorttime.set_img(0)
            self.__btn_sort_active[0] = self.btn_sorttitle

        self.__btn_sort_active[1] = order
        self.playlist.sortBy(atr, order -
                             1)  #0(False) if order==1 | 1(True) if order==2
示例#20
0
文件: gui.py 项目: Sidnoea/pokeBridge
def fileWindow(root):
    '''Makes the window that lets the user specify save files and options.'''

    def nextPage():
        global oldGen2, oldGen3, newGame, language, gender

        oldGen2 = fromText.get()
        oldGen3 = toText.get()
        newGame = gameCombo.get()
        language = langCombo.get()
        gender = genderCombo.get()

        with open(oldGen2, 'br') as file:
            root.boxes = getBoxes(file.read())

        root.nextPage()

    def nextToggle(*args):
        if fromText.get() == '' or toText.get() == '':
            navFrame.disable('next', True)
        else:
            navFrame.disable('next', False)

    def fromDialog():
        askOpen = filedialog.askopenfilename
        file = askOpen(title='Gen II Save File', initialdir=root.dir,
                       filetypes=[('GB Save', '.sav'), ('All Files', '.*')])
        if file != '':
            fromText.set(file)
            fromEntry.after_idle(fromEntry.xview_moveto, 1)
            root.dir = getDir(file)
    
    def toDialog():
        askOpen = filedialog.askopenfilename
        file = askOpen(title='Gen III Save File', initialdir=root.dir,
                       filetypes=[('GBA Save', '.sav'), ('All Files', '.*')])
        if file != '':
            toText.set(file)
            toEntry.after_idle(toEntry.xview_moveto, 1)
            root.dir = getDir(file)

    def getBoxes(data):
        from pokeBridge import Box, OldSaveFile

        boxes = []
        for offset in OldSaveFile.BOX_OFFSETS:
            box = []
            count = data[offset]
            for i in range(count):
                box.append(data[offset + 1 + i])
            for i in range(Box.OLD_SIZE - len(box)): #pad with 0
                box.append(0x0)
            boxes.append(box)

        return boxes

    baseFrame = ttk.Frame(root)
    baseFrame.rowconfigure(0, weight=1)
    baseFrame.columnconfigure(0, weight=1)
    
    
    mainFrame = ttk.Frame(baseFrame, padding=MAIN_PAD)
    mainFrame.grid(row=0, column=0)
    mainFrame.rowconfigure(0, weight=1)
    mainFrame.columnconfigure(0, weight=1)
    

    pickerFrame = ttk.Frame(mainFrame)
    pickerFrame.grid(row=0, column=0, sticky='s')

    pickText = "Select the Gen II save file to transfer Pok\u00E9mon from and the Gen III save file to transfer Pok\u00E9mon to."
    pickLabel = ttk.Label(pickerFrame, text=pickText, wraplength=WIDTH-50,
                          justify='center')
    pickLabel.grid(row=0, column=0, columnspan=2, pady=10)

    fromButton = ttk.Button(pickerFrame, text='From...', command=fromDialog)
    fromButton.grid(row=1, column=0, sticky='e', padx=5, pady=5)

    fromText = StringVar()
    fromText.trace('w', nextToggle)
    fromEntry = ttk.Entry(pickerFrame, textvariable=fromText, state='readonly')
    fromEntry.grid(row=1, column=1, sticky='w', padx=5, pady=5)
    
    toButton = ttk.Button(pickerFrame, text='To...', command=toDialog)
    toButton.grid(row=2, column=0, sticky='e', padx=5, pady=5)

    toText = StringVar()
    toText.trace('w', nextToggle)
    toEntry = ttk.Entry(pickerFrame, textvariable=toText, state='readonly')
    toEntry.grid(row=2, column=1, sticky='w', padx=5, pady=5)


    optionFrame = ttk.Frame(mainFrame)
    optionFrame.grid(row=1, column=0)

    optionText = "Select the appropriate options from the drop-down menus below."
    optionLabel = ttk.Label(optionFrame, text=optionText)
    optionLabel.grid(row=0, column=0, columnspan=2, pady=10)

    gameChoices = ['Ruby', 'Sapphire', 'Emerald', 'FireRed', 'LeafGreen']
    langChoices = ['English', 'Japanese', 'French', 'Italian', 'German',
                   'Korean', 'Spanish']
    genderChoices = ['Male', 'Female']

    gameLabel = ttk.Label(optionFrame, text='Destination Game')
    gameLabel.grid(row=1, column=0, sticky='e', padx=5, pady=5)
    
    gameCombo = ttk.Combobox(optionFrame, values=gameChoices,
                             state='readonly')
    gameCombo.set(gameChoices[0])
    gameCombo.grid(row=1, column=1, sticky='w', padx=5, pady=5)
    
    langLabel = ttk.Label(optionFrame, text='Game Language')
    langLabel.grid(row=2, column=0, sticky='e', padx=5, pady=5)
    
    langCombo = ttk.Combobox(optionFrame, values=langChoices,
                             state='readonly')
    langCombo.set(langChoices[0])
    langCombo.grid(row=2, column=1, sticky='w', padx=5, pady=5)
    
    genderLabel = ttk.Label(optionFrame, text='OT Gender')
    genderLabel.grid(row=3, column=0, sticky='e', padx=5, pady=5)
    
    genderCombo = ttk.Combobox(optionFrame, values=genderChoices,
                               state='readonly')
    genderCombo.set(genderChoices[0])
    genderCombo.grid(row=3, column=1, sticky='w', padx=5, pady=5)


    navFrame = Nav(baseFrame, root.prevPage, nextPage)
    navFrame.grid(row=1, column=0, sticky='we')

    if debug:
        fromText.set('C:/Users/Sidnoea/Documents/GitHub/pokeBridge/Old Gen 2.sav')
        toText.set('C:/Users/Sidnoea/Documents/GitHub/pokeBridge/Old Gen 3.sav')

    nextToggle()

    return (baseFrame, 'Select Save Files', {'sticky':'nsew'})
class NewMorphLineWindow(Toplevel):
    def __init__(self, master=None):
        super().__init__(master=master)
        self.set_basic()
        self.set_widgets()

    def set_basic(self):
        self.minsize(600, 400)
        self.maxsize(600, 400)
        self.title("Ekstrakcja linii")
        self.protocol("WM_DELETE_WINDOW", lambda: self.cancel())

        self.handleBorder = {
            "Bez zmian (isolated)": 0,
            "Odbicie lustrzane (reflect)": 1,
            "Powielenie skrajnego piksela (replicate)": 2
        }

    def set_widgets(self):
        self.horizontalSizeW = StringVar(self, value="3")
        self.horizontalSizeH = StringVar(self, value="1")
        self.verticalSizeW = StringVar(self, value="3")
        self.verticalSizeH = StringVar(self, value="1")
        self.borderType = StringVar(self, list(self.handleBorder.keys())[0])
        self.cbVarHorizontal = IntVar(value=1)
        self.cbVarVertical = IntVar(value=1)
        self.cbVarOuter = IntVar(value=1)
        self.cbVarNegate = IntVar(value=0)

        self.sizeHorizontalWSpin = Spinbox(self,
                                           justify='center',
                                           font=("Helvetica", 15),
                                           from_=1,
                                           to=9999,
                                           textvariable=self.horizontalSizeW,
                                           command=self.update_preview,
                                           state='readonly',
                                           increment=2)
        self.sizeHorizontalHSpin = Spinbox(self,
                                           justify='center',
                                           font=("Helvetica", 15),
                                           from_=1,
                                           to=9999,
                                           textvariable=self.horizontalSizeH,
                                           command=self.update_preview,
                                           state='readonly',
                                           increment=2)
        self.sizeVerticalWSpin = Spinbox(self,
                                         justify='center',
                                         font=("Helvetica", 15),
                                         from_=1,
                                         to=9999,
                                         textvariable=self.verticalSizeW,
                                         command=self.update_preview,
                                         state='readonly',
                                         increment=2)
        self.sizeVerticalHSpin = Spinbox(self,
                                         justify='center',
                                         font=("Helvetica", 15),
                                         from_=1,
                                         to=9999,
                                         textvariable=self.verticalSizeH,
                                         command=self.update_preview,
                                         state='readonly',
                                         increment=2)

        self.horizontalSizeW.trace("w", self.update_preview)
        self.horizontalSizeH.trace("w", self.update_preview)
        self.verticalSizeW.trace("w", self.update_preview)
        self.verticalSizeH.trace("w", self.update_preview)
        self.borderType.trace("w", self.update_preview)
        self.cbVarHorizontal.trace("w", self.update_preview)
        self.cbVarVertical.trace("w", self.update_preview)
        self.cbVarOuter.trace("w", self.update_preview)
        self.cbVarNegate.trace("w", self.update_preview)

        self.cbHorizontal = Checkbutton(self,
                                        width=0,
                                        variable=self.cbVarHorizontal)
        self.cbVertical = Checkbutton(self,
                                      width=0,
                                      variable=self.cbVarVertical)
        self.cbOuterOnly = Checkbutton(self, width=0, variable=self.cbVarOuter)
        self.cbNegateFirst = Checkbutton(self,
                                         width=0,
                                         variable=self.cbVarNegate)

        self.borderList = OptionMenu(self, self.borderType)

        for border in self.handleBorder:
            self.borderList['menu'].add_command(
                label=border, command=lambda v=border: self.borderType.set(v))

        self.saveButton = Button(self,
                                 image=saveIcon,
                                 command=self.update_image)
        self.cancelButton = Button(self, image=closeIcon, command=self.cancel)

        self.update_preview()
        self.place_widgets()

    def update_image(self):
        self.master.image.cv2Image = copy.deepcopy(self.master.image.copy)
        self.master.image.morph_line(int(self.horizontalSizeW.get()),
                                     int(self.horizontalSizeH.get()),
                                     int(self.verticalSizeW.get()),
                                     int(self.verticalSizeH.get()),
                                     self.cbVarHorizontal.get(),
                                     self.cbVarVertical.get(),
                                     self.handleBorder[self.borderType.get()],
                                     self.cbVarOuter.get(),
                                     self.cbVarNegate.get())
        self.master.image.copy = copy.deepcopy(self.master.image.cv2Image)
        self.master.manager.new_state(self.master.image.cv2Image)
        self.master.update_visible_image()
        self.master.update_child_windows()
        self.destroy()

    def update_preview(self, *args):
        self.sizeHorizontalWSpin.config(from_=int(self.horizontalSizeH.get()) +
                                        2)
        self.sizeHorizontalHSpin.config(to=int(self.horizontalSizeW.get()) - 2)
        self.sizeVerticalWSpin.config(from_=int(self.verticalSizeH.get()) + 2)
        self.sizeVerticalHSpin.config(to=int(self.verticalSizeW.get()) - 2)
        self.master.image.cv2Image = copy.deepcopy(self.master.image.copy)
        self.master.image.morph_line(int(self.horizontalSizeW.get()),
                                     int(self.horizontalSizeH.get()),
                                     int(self.verticalSizeW.get()),
                                     int(self.verticalSizeH.get()),
                                     self.cbVarHorizontal.get(),
                                     self.cbVarVertical.get(),
                                     self.handleBorder[self.borderType.get()],
                                     self.cbVarOuter.get(),
                                     self.cbVarNegate.get())
        self.master.update_visible_image()
        self.master.update_child_windows()

    def place_widgets(self):
        Label(self, text="Poziome linie", font=("Helvetica", 15)).place(x=85,
                                                                        y=15)
        Label(self, text="Pionowe linie", font=("Helvetica", 15)).place(x=395,
                                                                        y=15)

        self.sizeHorizontalWSpin.place(width=100, height=50, x=150, y=60)
        self.sizeHorizontalHSpin.place(width=100, height=50, x=150, y=120)
        self.sizeVerticalWSpin.place(width=100, height=50, x=450, y=60)
        self.sizeVerticalHSpin.place(width=100, height=50, x=450, y=120)

        Label(self, text="Min. długość", font=("Helvetica", 15)).place(x=30,
                                                                       y=70)
        Label(self, text="Min. grubość", font=("Helvetica", 15)).place(x=30,
                                                                       y=130)
        Label(self, text="Min. długość", font=("Helvetica", 15)).place(x=330,
                                                                       y=70)
        Label(self, text="Min. grubość", font=("Helvetica", 15)).place(x=330,
                                                                       y=130)

        Label(self, text="Szukać poziomych?",
              font=("Helvetica", 9)).place(x=70, y=175)
        Label(self, text="Szukać pionowych?",
              font=("Helvetica", 9)).place(x=380, y=175)

        self.cbHorizontal.place(x=180, y=175)
        self.cbVertical.place(x=500, y=175)

        Label(self, text="Szukać tylko zewnętrznych?",
              font=("Helvetica", 11)).place(x=190, y=225)
        Label(self, text="Wstępnie zanegować?",
              font=("Helvetica", 11)).place(x=190, y=255)
        self.cbOuterOnly.place(x=390, y=225)
        self.cbNegateFirst.place(x=390, y=255)
        self.borderList.place(width=200, height=50, x=200, y=300)

        self.saveButton.place(width=40, height=40, x=220, y=355)
        self.cancelButton.place(width=40, height=40, x=340, y=355)

    def cancel(self):
        self.master.image.cv2Image = copy.deepcopy(self.master.image.copy)
        self.master.update_visible_image()
        self.master.image.fill_histogram()
        self.master.update_child_windows()
        self.destroy()
示例#22
0
class Selector(Frame):
    """The Selector class implements a selector, label and variable(to hold the data)
    """
    caption = None
    """The caption of the selector"""
    caption_orientation = None
    """The orientation of the selector, can be "LEFT", "RIGHT", "TOP", "BOTTOM"."""
    value = None
    """The current value of the selector"""
    values = None
    """The selectable values"""

    onchange = None
    """The onchange-event is triggered when the value is changed."""
    do_not_propagate = False
    """If True, the onchange event isn't triggered on changing the value."""


    def __init__(self, _master, _values=None, _caption=None, _caption_orientation=None, _relief=None, _onchange=None):
        super(Selector, self).__init__(_master, bd=1, relief=_relief)

        self.value = StringVar()

        if _values:
            self.values = _values
        else:
            self.values = None

        if _caption:
            self.caption = _caption
        else:
            self.caption = None

        if _caption_orientation:
            self.caption_orientation = _caption_orientation
        else:
            self.caption_orientation = LEFT

        if _onchange:
            self.onchange = _onchange
            # Add handling when type is changed

        else:
            self.onchange = None

        do_not_propagate = False

        self.init_widgets()


    def set_but_do_not_propagate(self, _value):
        """Sets the value, but by setting the do_not_propagate-flag, the onchange event will not fire.
        :param _value: The new value
        """
        self.do_not_propagate = True
        self.value.set(_value)


    def _do_onchange(self, *args):
        """
        Calls onchange if assigned.
        :param args: a list of arguments.
        """
        if self.do_not_propagate == False and self.onchange:
            self.onchange(_current_index=0, _current_value=self.cb.get())
        else:
            self.do_not_propagate = False


    def init_widgets(self):
        """
        Initialize visual elements.
        """

        self.value = StringVar()
        self.cb = ttk.Combobox(self, textvariable=self.value, state='readonly')
        self.cb['values'] = self.values
        self.cb.current(0)

        self.l_caption = ttk.Label(self, text=self.caption)

        _cb_o = None
        if self.caption_orientation == LEFT:
            _cb_o = RIGHT
        elif self.caption_orientation == RIGHT:
            _cb_o = LEFT
        elif self.caption_orientation == TOP:
            _cb_o = BOTTOM
        elif self.caption_orientation == BOTTOM:
            _cb_o = TOP

        self.cb.pack(side=_cb_o)
        self.l_caption.pack(side=self.caption_orientation)

        self.value.trace('w', self._do_onchange)
示例#23
0
class BIDSFile(FileInfo):
    """
    BIDSFiles are the main files which will contain the data that is to be
    converted to BIDS format.
    For KIT data this is the .con file.
    For Elekta data this is the .fif file.

    """
    def __init__(self, id_=None, file=None, settings=dict(), parent=None):
        super(BIDSFile, self).__init__(id_, file, parent)

        self._settings = settings

        self._create_vars()

        if 'emptyroom' in self.file.lower():
            self.is_empty_room.set(True)

    def _create_vars(self):
        # TODO: Fix
        # This is called multiple times...
        FileInfo._create_vars(self)
        self.run = StringVar(value='1')
        self.run.trace("w", self.validate)
        self.task = OptionsVar(options=['None'])
        self.task.trace("w", self._update_tasks)
        self.is_junk = BooleanVar()
        self.is_empty_room = BooleanVar()
        self.is_empty_room.trace("w", self.propagate_emptyroom_data)
        self.has_empty_room = BooleanVar()

        self.hpi = list()

        self.loaded = False

        self.extra_data = dict()

        # event info: a list of lists. The sub-lists contains the event number
        # and the event description
        self.event_info = list()
        # channel info: key - channel name (?), value - something
        self.channel_info = dict()

        self.raw = None
        self.container = None

        # Set all BIDS files to be saved by default
        self.requires_save = True

    def load_data(self):
        pass

    def validate(self, validate_container=True, *args):
        """
        Check whether the file is valid (ie. contains all the required info for
        BIDS exporting).

        """
        self.valid = self.check_valid()
        if self.container is not None and validate_container:
            self.container.validate()

    def check_valid(self):
        """
        Go over all the required settings and determine whether the file is
        ready to be exported to the bids format.

        """
        is_valid = super(BIDSFile, self).check_valid()
        # if empty room or junk we consider them good
        if self.is_empty_room.get() or self.is_junk.get():
            return is_valid
        is_valid &= self.run.get() != ''
        is_valid &= (self.hpi != list())
        return is_valid

    def get_event_data(self):
        return ['', '']

    def propagate_emptyroom_data(self, *args):
        """ Callback to propagate the empty room state

        This is used to tell the container object that the empty room status
        of this file has changed and change the 'has empty room' state of any
        other files in the same folder (for KIT).

        """
        if self.container is not None:
            emptyroom_set = self.container.autodetect_emptyroom()
            if not emptyroom_set:
                self.is_empty_room.set(False)
                self.associated_tab.is_emptyroom_info.value = self.is_empty_room  # noqa

    def _update_tasks(self, *args):
        """Update the EntryChoice that contains the task options"""
        if self.associated_tab is not None:
            self.associated_tab.task_info.value = self.task

    def __getstate__(self):
        data = super(BIDSFile, self).__getstate__()

        data['run'] = self.run.get()                                      # run
        data['tsk'] = self.task.get()                                    # task
        # marker coils:
        data['hpi'] = [hpi.file for hpi in self.hpi]
        data['ier'] = self.is_empty_room.get()            # is empty room data?
        data['her'] = self.has_empty_room.get()          # has empty room data?

        return data

    def __setstate__(self, state):
        super(BIDSFile, self).__setstate__(state)
        self.run.set(state.get('run', 0))
        task = state.get('tsk', '')
        self.task.options = [task]
        self.task.set(task)
        # support old and new format hpi storage
        self.hpi = state.get('hpi', list())
        self.is_empty_room.set(state.get('ier', False))
        self.has_empty_room.set(state.get('her', False))
示例#24
0
class MainFrame(Frame):
    ''' This class implements main GUI of the application.

        Attributes:
            parent (Tk object): parent of this frame (Tk()).
            params_frame (ParamsFrame): frame with parameters.
            data_frame (DataFrame): frame with data and solution.
            progress_bar (Progressbar): progress bar widget.
            increment (int): progress bar increment, it is modified
                in other classes that are responsible for solving
                the problem and update progress.
            weights_status_lbl (Label): label that displays if weight
                restrictions are feasible.
            weights_status_str (StringVar): StringVar object used for
                tracking if weight restrictions are feasible.
            current_categories (list of str): list of current categories.

        Args:
            parent (Tk object): parent of this frame (Tk()).
    '''
    def __init__(self, parent, *args, **kwargs):
        Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.params_frame = None
        self.data_frame = None
        self.progress_bar = None
        self.increment = 0
        self.weights_status_lbl = None
        self.weights_status_str = StringVar()
        self.weights_status_str.trace('w', self.on_weights_status_change)
        self.current_categories = []
        self.create_widgets()

    def create_widgets(self):
        ''' Creates all widgets that belong to this frame.
        '''
        self.parent.title('pyDEA')
        self.pack(fill=BOTH, expand=1)

        self.columnconfigure(0, weight=1, pad=5)
        self.columnconfigure(1, weight=0, pad=5)
        self.rowconfigure(0, pad=3, weight=1)
        self.rowconfigure(1, pad=3)
        self.rowconfigure(2, pad=3)
        self.rowconfigure(3, pad=3)

        self.current_categories = []
        data_from_params_file = StringVar()
        str_var_for_input_output_boxes = ObserverStringVar()
        self.params_frame = ParamsFrame(self, self.current_categories,
                                        data_from_params_file,
                                        str_var_for_input_output_boxes,
                                        self.weights_status_str)
        data_frame = DataFrame(self, self.params_frame, self.current_categories,
                               data_from_params_file,
                               str_var_for_input_output_boxes)
        self.data_frame = data_frame
        data_frame.grid(row=0, column=0, sticky=N+S+W+E, padx=15, pady=15)

        self.params_frame.grid(row=0, column=1, sticky=W+E+S+N, padx=15,
                               pady=15, columnspan=2)

        lbl_progress = Label(self, text='Progress')
        lbl_progress.grid(row=1, column=0, sticky=W, padx=10, pady=5)

        self.progress_bar = Progressbar(self, mode='determinate', maximum=100)
        self.progress_bar.grid(row=2, column=0, sticky=W+E, padx=10, pady=5)

        run_btn = Button(self, text='Run', command=self.run)
        run_btn.grid(row=2, column=1, sticky=W, padx=10, pady=10)

        self.weights_status_lbl = Label(self, text='', foreground='red')
        self.weights_status_lbl.grid(row=2, column=2, padx=10, pady=5, sticky=W)

    def on_weights_status_change(self, *args):
        ''' This method is called when weight restrictions status is changed.
        '''
        self.weights_status_lbl.config(text=self.weights_status_str.get())

    def run(self):
        ''' This method is called when the user presses Run button.
            Solves the problem and displays solution.
        '''
        clean_up_pickled_files()
        params = self.params_frame.params
        run_method = RunMethodGUI(self)
        run_method.run(params)

    def construct_categories(self):
        ''' Returns current categories.

            Returns:
                (list of str): list of current categories
        '''
        return [category.strip() for category in self.current_categories
                if category]

    def on_dmu_change(self, *args):
        ''' Updates progress bar.
        '''
        self.progress_bar.step(self.increment)
        self.progress_bar.update()
示例#25
0
class CharacterValueField(Entry):
    """
    Basic field type used to store character values.
    """
    def __init__(self, parent, validate_fun, **kwargs):
        """
        Initialise input field.
         - validate_fun:
            A function used to validate the field's input value.
        """
        # Variable for entered value
        if 'name' in kwargs:
            self.name = kwargs.get('name')
            self.value = StringVar(parent, name=self.name)
        else:
            self.value = StringVar(parent)

        self.value.set('')
        self.value.trace('w', self._follow_changes)
        self.validator = validate_fun

        if 'to_trace' in kwargs:
            self.reference = kwargs.get('to_trace')
            self.reference.trace('w', self._follow_ref_val)

        # Entry field
        Entry.__init__(self,
                       parent,
                       textvariable=self.value,
                       width=kwargs.get('width', FIELD_WIDTH))

    def _follow_ref_val(self, *_args):
        """
        If a master - or reference - value is specified
        for the field, it will update its value on changes
        to the master field.
        """
        self.value.set(self.reference.get())

    def _follow_changes(self, *_args):
        """
        Traces changes to the input value
        of the field.
        """
        # Get current background color of field.
        color = self.cget('bg')

        # It turns red on validation failures.
        # Any subsequent change must turn the color back
        # to the default color.
        if color == FIELD_COLOR_ERROR:
            self.config(bg=FIELD_COLOR)

    def enable(self):
        """
        Enables the field. I.e. it's value
        can be set.
        """
        self.config(state=NORMAL)
        self.value.set('')

    def disable(self):
        """
        Disables the field. It's value cannot
        be set or edited.
        """
        self.value.set('n/a')
        self.config(state=DISABLED)

    def get_validated(self, **kwargs):
        """
        Calls assigned validator function on the
        value of the field.

        If validation fails, turns the field to red.
        """
        try:
            value = self.validator(self.value.get(), **kwargs)
            return value

        except FieldValidationError:
            self.config(bg=FIELD_COLOR_ERROR)
            raise

    def reset_fld(self):
        """
        Cleans the field's value by setting
        it to an empty string.
        """
        self.value.set('')
示例#26
0
文件: config.py 项目: carmen890/FFGo
class Config:

    """Read/write and store all data from config files."""

    def __init__(self, cmdLineParams, master=None):
        self.cmdLineParams = cmdLineParams
        self.master = master

        self.ai_path = ''  # Path to FG_ROOT/AI directory.
        self.apt_path = ''  # Path to FG_ROOT/Airports/apt.dat.gz file.
        self.metar_path = ''  # Path to FG_ROOT/Airports/metar.dat.gz file.

        self.aircraft_dirs = [] # List of aircraft directories.
        # Dictionary whose keys are aircraft names. For each aircraft name 'n',
        # self.aircraftDict[n] is the list, in self.aircraft_dirs priority
        # order, of all Aircraft instances with that name.
        self.aircraftDict = {}
        self.aircraftList = []  # Sorted list of Aircraft instances.

        self.scenario_list = []  # List of selected scenarios.
        # List of all aircraft carriers found in AI scenario folder.
        # Each entry format is:
        # ["ship name", "parking position"... , "scenario name"]
        self.carrier_list = []

        self.settings = []  # List of basic settings read from config file.
        self.text = ''  # String to be shown in command line options window.

        # 'self.aircraftId' is the central variable telling which particular
        # aircraft is selected in FFGo's interface. It is a tuple of the form
        # (aircraftName, aircraftDir).
        self.aircraftId = misc.Observable()
        self.aircraft = StringVar()
        self.aircraftDir = StringVar()
        # Whenever 'self.aircraftId' is set, 'self.aircraft' and
        # 'self.aircraftDir' are automatically updated to reflect the new value
        # (and their observers called, even if the values didn't change).
        self.aircraftId.trace("w", self.updateAircraftNameAndDirFromAircraftId)
        # Note: the FFGo config file stores the values of 'self.aircraft' and
        #       'self.aircraftDir' separately (this makes the compatibility
        #       path easy with versions that don't know about aircraftDir).

        self.airport = StringVar() # ICAO code of the selected airport
        self.alreadyProposedChanges = StringVar()
        self.apt_data_source = IntVar()
        self.auto_update_apt = IntVar()
        self.carrier = StringVar() # when non-empty, we are in “carrier mode”
        self.FG_aircraft = StringVar()
        self.FG_bin = StringVar()
        self.FG_root = StringVar()
        self.FG_scenery = StringVar()
        self.FG_working_dir = StringVar()

        self.MagneticField_bin = StringVar()
        self.MagneticField_bin.trace('w', self.updateMagFieldProvider)

        self.filteredAptList = IntVar()
        self.language = StringVar()
        self.park = StringVar()
        self.rwy = StringVar()
        self.scenario = StringVar()
        self.mainWindowGeometry = StringVar()
        self.saveWindowPosition = IntVar()
        self.baseFontSize = StringVar()
        self.TkDefaultFontSize = IntVar()

        # tkinter.BooleanVar feels kind of messy. Sometimes, it prints out as
        # 'True', other times as '1'... IntVar seems more predictable.
        self.showFGCommand = IntVar()
        self.showFGCommandInSeparateWindow = IntVar()
        self.FGCommandGeometry = StringVar()
        self.showFGOutput = IntVar()
        self.showFGOutputInSeparateWindow = IntVar()
        self.FGOutputGeometry = StringVar()
        self.autoscrollFGOutput = IntVar()
        # Option to translate --parkpos into --lat, --lon and --heading (useful
        # when --parkpos is broken in FlightGear)
        self.fakeParkposOption = IntVar()

        self.airportStatsManager = None # will be initialized later
        self.aircraftStatsManager = None # ditto
        self.airportStatsShowPeriod = IntVar()
        self.airportStatsExpiryPeriod = IntVar()
        self.aircraftStatsShowPeriod = IntVar()
        self.aircraftStatsExpiryPeriod = IntVar()

        self.keywords = {'--aircraft=': self.aircraft,
                         '--airport=': self.airport,
                         '--fg-root=': self.FG_root,
                         '--fg-scenery=': self.FG_scenery,
                         '--carrier=': self.carrier,
                         '--parkpos=': self.park,
                         '--runway=': self.rwy,
                         'AIRCRAFT_DIR=': self.aircraftDir,
                         'AI_SCENARIOS=': self.scenario,
                         'ALREADY_PROPOSED_CHANGES=':
                                             self.alreadyProposedChanges,
                         'APT_DATA_SOURCE=': self.apt_data_source,
                         'AUTO_UPDATE_APT=': self.auto_update_apt,
                         'FG_BIN=': self.FG_bin,
                         'FG_AIRCRAFT=': self.FG_aircraft,
                         'FG_WORKING_DIR=': self.FG_working_dir,
                         'MAGNETICFIELD_BIN=': self.MagneticField_bin,
                         'FILTER_APT_LIST=': self.filteredAptList,
                         'LANG=': self.language,
                         'WINDOW_GEOMETRY=': self.mainWindowGeometry,
                         'SAVE_WINDOW_POSITION=': self.saveWindowPosition,
                         'BASE_FONT_SIZE=': self.baseFontSize,
                         'SHOW_FG_COMMAND=': self.showFGCommand,
                         'SHOW_FG_COMMAND_IN_SEPARATE_WINDOW=':
                         self.showFGCommandInSeparateWindow,
                         'FG_COMMAND_GEOMETRY=': self.FGCommandGeometry,
                         'SHOW_FG_OUTPUT=': self.showFGOutput,
                         'SHOW_FG_OUTPUT_IN_SEPARATE_WINDOW=':
                         self.showFGOutputInSeparateWindow,
                         'FG_OUTPUT_GEOMETRY=': self.FGOutputGeometry,
                         'AUTOSCROLL_FG_OUTPUT=': self.autoscrollFGOutput,
                         'FAKE_PARKPOS_OPTION=': self.fakeParkposOption,
                         'AIRPORT_STATS_SHOW_PERIOD=':
                         self.airportStatsShowPeriod,
                         'AIRPORT_STATS_EXPIRY_PERIOD=':
                         self.airportStatsExpiryPeriod,
                         'AIRCRAFT_STATS_SHOW_PERIOD=':
                         self.aircraftStatsShowPeriod,
                         'AIRCRAFT_STATS_EXPIRY_PERIOD=':
                         self.aircraftStatsExpiryPeriod}

        # In order to avoid using a lot of memory, detailed airport data is
        # only loaded on demand. Since this is quite slow, keep a cache of the
        # last retrieved data.
        self.aptDatCache = collections.deque(maxlen=50)

        self._earlyTranslationsSetup()
        self._createUserDirectories()
        self._maybeMigrateFromFGoConfig()
        # Not having the FlightGear version at this point is not important
        # enough to justify pestering the user about it. :-)
        # Defer logging of the detected FG version to fit nicely with
        # the other startup messages.
        self.update(ignoreFGVersionError=True, logFGVersion=False)

        self.setTkDefaultFontSize()
        self.setupFonts(init=True)

    def setTkDefaultFontSize(self):
        """Save unaltered TkDefaultFont size."""
        size = tkinter.font.nametofont("TkDefaultFont").actual()["size"]
        self.TkDefaultFontSize.set(size)

    def setupFonts(self, init=False):
        """Setup the default fonts.

        When called with init=True, custom fonts are created and
        stored as attributes of self. Otherwise, they are simply
        configured.

        """
        # According to <http://www.tcl.tk/man/tcl8.4/TkCmd/font.htm>, font
        # sizes are interpreted this way:
        #   - for positive values, the unit is points;
        #   - for negative values, the unit is pixels;
        #   - 0 is a special value for "a platform-dependent default size".
        #
        # Apparently, Tkinter doesn't accept floats for the 'size' parameter of
        # <font>.configure(), even when positive (tested with Python 2.7.3).
        baseSize = int(float(self.baseFontSize.get()))
        # Get the actual size when baseSize == 0, otherwise scaling won't work
        # since 0*factor == 0, regardless of the (finite) factor.
        if baseSize == 0:
            baseSize = self.TkDefaultFontSize.get()

        def scale(factor):
            return int(round(baseSize * factor))

        def configFontSize(style, factor):
            font = tkinter.font.nametofont("Tk%sFont" % style)
            font.configure(size=scale(factor))

        # Configure built-in fonts
        for style in ("Default", "Text", "Fixed", "Caption", "Tooltip"):
            # The 'if init:' here is a workaround for a weird problem: when
            # saving the settings from the Preferences dialog, even if the very
            # same font size is set here as the one that was used at program
            # initialization, the main window layout gets broken, with the
            # airport chooser Treeview taking more and more horizontal space
            # every time the settings are saved. Avoiding to reconfigure the
            # fonts in such "reinit" conditions works around the problem...
            if init:
                configFontSize(style, 1)

        for style, factor in (("Menu", 20 / 18.), ("Heading", 20 / 18.),
                              ("SmallCaption", 16 / 18.), ("Icon", 14 / 18.)):
            if init:            # Second part of the workaround mentioned above
                configFontSize(style, factor)

        # Create or configure custom fonts, depending on 'init'
        aboutTitleFontSize = scale(42 / 18.)
        if init:
            self.aboutTitleFont = tkinter.font.Font(
                family="Helvetica", weight="bold", size=aboutTitleFontSize)
        else:
            self.aboutTitleFont.configure(size=aboutTitleFontSize)

        # Final part of the workaround mentioned above. Normally, the code
        # should always be executed, regardless of the value of 'init'.
        if init:
            # For the ttk.Treeview widget
            treeviewHeadingFontSize = scale(1.)
            # Redundant test, right. Hopefully, one day, we'll be able to get
            # rid of the workaround and this test won't be redundant anymore.
            if init:
                self.treeviewHeadingFont = tkinter.font.Font(
                    weight="normal", size=treeviewHeadingFontSize)
            else:
                self.treeviewHeadingFont.configure(size=treeviewHeadingFontSize)

            style = ttk.Style()
            style.configure("Treeview.Heading", font=self.treeviewHeadingFont)

    def makeInstalledAptList(self):
        logger.notice(_("Building the list of installed airports "
                        "(this may take some time)..."))
        # writelines() used below doesn't automatically add line terminators
        airports = [ icao + '\n' for icao in self._findInstalledApt() ]
        logger.info("Opening '{}' for writing".format(INSTALLED_APT))
        with open(INSTALLED_APT, "w", encoding="utf-8") as fout:
            fout.writelines(airports)

    def readMetarDat(self):
        """Fetch METAR station list from metar.dat.gz file"""
        logger.info("Opening '{}' for reading".format(self.metar_path))
        res = []

        with gzip.open(self.metar_path, mode='rt', encoding='utf-8') as fin:
            for line in fin:
                if not line.startswith('#'):
                    res.append(line.strip())

        return res

    def rebuildApt(self):
        """Rebuild apt file."""
        self._makeAptDigest()

    def _computeAircraftDirList(self):
        FG_AIRCRAFT_env = os.getenv("FG_AIRCRAFT", "")
        if FG_AIRCRAFT_env:
            FG_AIRCRAFT_envList = FG_AIRCRAFT_env.split(os.pathsep)
        else:
            FG_AIRCRAFT_envList = []

        # FG_ROOT/Aircraft
        defaultAircraftDir = os.path.join(self.FG_root.get(),
                                          DEFAULT_AIRCRAFT_DIR)

        aircraft_dirs = (self.FG_aircraft.get().split(os.pathsep)
                         + FG_AIRCRAFT_envList + [defaultAircraftDir])
        return aircraft_dirs

    def logDetectedFlightGearVersion(self, logLevel=LogLevel.notice,
                                     prefix=True):
        if self.FG_version is not None:
            FG_version = str(self.FG_version)
        else:
            FG_version = pgettext("FlightGear version", "none")

        # Uses the same string as in App.about()
        message = _("Detected FlightGear version: {ver}").format(
            ver=FG_version)
        logger.log(logLevel, prefix, message)

    def getFlightGearVersion(self, ignoreFGVersionError=False, log=False):
        # This import requires the translation system [_() function] to be in
        # place.
        from .fgdata import fgversion

        self.FG_version = None  # in case an exception is raised below
        FG_bin = self.FG_bin.get()
        FG_root = self.FG_root.get()
        exc = None

        if FG_bin and FG_root:
            try:
                self.FG_version = fgversion.getFlightGearVersion(
                    FG_bin, FG_root, self.FG_working_dir.get())
            except fgversion.error as e:
                exc = e         # may need to be raised later

        if log:
            self.logDetectedFlightGearVersion()

        if exc is not None and not ignoreFGVersionError:
            raise exc

    # This is a callback for FFGo's misc.Observable class.
    def updateAircraftNameAndDirFromAircraftId(self, aircraftId):
        aircraftName, aircraftDir = aircraftId
        self.aircraft.set(aircraftName)
        self.aircraftDir.set(aircraftDir)

    def aircraftWithNameAndDir(self, name, dir_):
        """Get the Aircraft instance for a given name and directory."""
        try:
            aircrafts = self.aircraftDict[name]
        except KeyError:
            raise NoSuchAircraft(name, dir_)

        for aircraft in aircrafts:
            # The idea is that the directory 'dir_' passed here should have
            # been discovered earlier by a filesystem exploration, therefore
            # there must be one Aircraft instance that has an exact match for
            # both 'name' and 'dir_' (no need to use 'os.path.samefile()',
            # which would be slower, could raise errors...).
            if aircraft.dir == dir_:
                return aircraft
        else:
            raise NoSuchAircraft(name, dir_)

    def aircraftWithId(self, aircraftId):
        """Get the Aircraft instance for a given aircraft ID."""
        return self.aircraftWithNameAndDir(*self.aircraftId.get())

    def getCurrentAircraft(self):
        """Get the Aircraft instance for the currently-selected aircraft."""
        return self.aircraftWithId(self.aircraftId.get())

    def _findAircraft(self, acName, acDir):
        """Return an aircraft ID for 'acName' and 'acDir' if possible.

        If no aircraft is found with the given name and directory, fall
        back to:
          - an identically-named aircraft in a different directory
            (taking the first in FG_AIRCRAFT precedence order);
          - if this isn't possible either, fall back to the default
            aircraft. The returned aircraft ID will have an empty
            directory component if even the default aircraft isn't
            available in this case.

        Log an appropriate warning or notice when a fallback strategy is
        used.

        """
        if acName in self.aircraftDict:
            for ac in self.aircraftDict[acName]:
                if ac.dir == acDir:
                    aircraft = ac
                    break
            else:
                aircraft = self.aircraftDict[acName][0]
                logger.notice(
                    _("Could not find aircraft '{aircraft}' under '{dir}', "
                      "taking it from '{fallback}' instead").format(
                          aircraft=acName, dir=acDir, fallback=aircraft.dir))
        else:
            try:
                defaultAircrafts = self.aircraftDict[DEFAULT_AIRCRAFT]
            except KeyError:
                aircraft = None
                logger.warning(
                    _("Could not find the default aircraft: {aircraft}")
                    .format(aircraft=DEFAULT_AIRCRAFT))
            else:
                aircraft = defaultAircrafts[0]
                logger.notice(
                    _("Could not find aircraft '{aircraft}', using "
                      "'{fallback}' from '{dir}' instead").format(
                          aircraft=acName, fallback=aircraft.name,
                          dir=aircraft.dir))

        if aircraft is None:
            return (DEFAULT_AIRCRAFT, '')
        else:
            return (aircraft.name, aircraft.dir)

    def sanityChecks(self):
        status, *rest = self.decodeParkingSetting(self.park.get())
        if status == "invalid":
            logger.warning(
                _("Invalid syntax for the parking setting ({setting!r}), "
                  "resetting it.").format(setting=self.park.get()))
            self.park.set('')

        if self.rwy.get() and self.park.get():
            # Impossible to at the same time set a non-default runway and a
            # parking position. The latter wins. :-)
            self.rwy.set('')

    def update(self, path=None, ignoreFGVersionError=False, logFGVersion=True):
        """Read config file and update variables.

        path is a path to different than default config file

        """
        if self.aircraftStatsManager is None: # application init
            # Requires the translation system to be in place
            from . import stats_manager
            self.aircraftStatsManager = \
                                      stats_manager.AircraftStatsManager(self)
        else:
            # Save the in-memory statistics (from Aircraft instances) to
            # persistent storage. This expires old stats, according to
            # self.aircraftStatsExpiryPeriod.
            self.aircraftStatsManager.save()

        del self.settings
        del self.text
        del self.aircraft_dirs
        del self.apt_path
        del self.ai_path
        del self.metar_path
        del self.aircraftDict
        del self.aircraftList
        del self.scenario_list
        del self.carrier_list

        # The variable will be set again right after reading the config
        # file, therefore there is no need to run the callbacks now
        # (such as updating the aircraft image).
        self.aircraftId.set((DEFAULT_AIRCRAFT, ''), runCallbacks=False)
        self.airport.set(DEFAULT_AIRPORT)
        self.alreadyProposedChanges.set('')
        self.apt_data_source.set(1)
        self.auto_update_apt.set(1)
        self.carrier.set('')
        self.FG_aircraft.set('')
        self.FG_bin.set('')
        self.FG_root.set('')
        self.FG_scenery.set('')
        self.FG_working_dir.set('')
        self.MagneticField_bin.set('')
        self.language.set('')
        self.baseFontSize.set(DEFAULT_BASE_FONT_SIZE)
        self.mainWindowGeometry.set('')
        self.saveWindowPosition.set('1')
        self.showFGCommand.set('1')
        self.showFGCommandInSeparateWindow.set('0')
        self.FGCommandGeometry.set('')
        self.showFGOutput.set('1')
        self.showFGOutputInSeparateWindow.set('0')
        self.FGOutputGeometry.set('')
        self.autoscrollFGOutput.set('1')
        self.park.set('')
        self.fakeParkposOption.set('0')
        self.rwy.set('')
        self.scenario.set('')
        self.filteredAptList.set(0)
        self.airportStatsShowPeriod.set('365')    # approx. one year
        self.airportStatsExpiryPeriod.set('3652') # approx. ten years
        self.aircraftStatsShowPeriod.set('365')
        self.aircraftStatsExpiryPeriod.set('3652')

        self.settings, self.text = self._read(path)

        for line in self.settings:
            cut = line.find('=') + 1

            if cut:
                name = line[:cut]
                value = line[cut:]

                if value:
                    if name in self.keywords:
                        var = self.keywords[name]
                        var.set(value)

        # Useful to know when the airport has been changed
        self.previousAirport = self.airport.get()

        self._setLanguage(self.language.get())
        setupTranslationHelper(self)

        self.aircraft_dirs = self._computeAircraftDirList()
        self.apt_path = os.path.join(self.FG_root.get(), APT_DAT)
        self.ai_path = os.path.join(self.FG_root.get(), AI_DIR)
        self.metar_path = os.path.join(self.FG_root.get(), METAR_DAT)

        self.aircraftDict, self.aircraftList = self._readAircraft()
        # Load the saved statistics into the new in-memory Aircraft instances
        # (the set of aircrafts may have just changed, hence the need to save
        # the stats before the in-memory aircraft list is updated, and reload
        # them afterwards).
        self.aircraftStatsManager.load()
        # Choose a suitable aircraft, even if the one defined by
        # 'self.aircraft' and 'self.aircraftDir' isn't available.
        self.aircraftId.set(self._findAircraft(self.aircraft.get(),
                                               self.aircraftDir.get()))

        self.scenario_list, self.carrier_list = self._readScenarios()
        self.sanityChecks()
        self.getFlightGearVersion(ignoreFGVersionError=ignoreFGVersionError,
                                  log=logFGVersion)

    def write(self, text=None, path=None):
        """Write the configuration to a file.

        text -- content of text window processed by CondConfigParser
                (pass None to use the value of Config.text)
        path -- path to the file the config will be written to
                (the default config file is used if this argument is
                empty or None)

        """
        if not path:
            path = CONFIG
        if text is None:
            text = self.text

        options = []
        keys = list(self.keywords.keys())
        keys.sort()

        for k in keys:
            v = self.keywords[k]
            if k in ('--carrier=', '--airport=', '--parkpos=', '--runway='):
                if v.get():
                    options.append(k + v.get())
            else:
                options.append(k + str(v.get()))

        s = '\n'.join(options)
        logger.info("Opening config file for writing: '{}'".format(path))

        with open(path, mode='w', encoding='utf-8') as config_out:
            config_out.write(s + '\n' + CUT_LINE + '\n')
            # Make sure the config file has exactly one newline at the end
            while text.endswith('\n\n'):
                text = text[:-1]
            if not text.endswith('\n'):
                text += '\n'
            config_out.write(text)

    def _findInstalledApt(self):
        """Walk thru all scenery and find installed airports.

        Take geographic coordinates from directories names and compare them
        with airports coordinates in apt file.

        The result is a sorted list of ICAO codes for matching airports.

        """
        coord_dict = {}
        sceneries = self.FG_scenery.get().split(os.pathsep)

        for scenery in sceneries:
            path = os.path.join(scenery, 'Terrain')
            if os.path.exists(path):
                for dir in os.listdir(path):
                    p = os.path.join(path, dir)
                    for coords in os.listdir(p):
                        d = os.path.join(p, coords)
                        if not os.path.isdir(d):
                            continue

                        logger.debug("Exploring Terrain directory '{}' -> '{}'"
                                     .format(p, coords))
                        converted = self._stringToCoordinates(coords)
                        if converted is not None:
                            coord_dict[converted] = None
                        else:
                            logger.notice(
                                _("Ignoring directory '{}' (unexpected name)")
                                .format(d))

        coords = coord_dict.keys()
        res = []
        for icao in self.sortedIcao():
            airport = self.airports[icao]
            for c in coords:
                if (c[0][0] < airport.lat < c[0][1] and
                    c[1][0] < airport.lon < c[1][1]):
                    res.append(icao)

        return res

    def _calculateRange(self, coordinates):
        c = coordinates
        if c.startswith('s') or c.startswith('w'):
            c = int(c[1:]) * (-1)
            return c, c + 1
        else:
            c = int(c[1:])
            return c, c + 1

    def _createUserDirectories(self):
        """Create config, log and stats directories if they don't exist."""
        for d in USER_DATA_DIR, LOG_DIR, STATS_DIR:
            os.makedirs(d, exist_ok=True)

    def _maybeMigrateFromFGoConfig_dialogs(self, parent):
        message = _("Initialize {prg}'s configuration from your existing " \
                    "FGo! configuration?").format(prg=PROGNAME)
        detail = (_("""\
You have no {cfgfile} file but you do have a {fgo_cfgfile} file,
which normally belongs to FGo!. Except in rare circumstances
(such as using braces or backslashes, or opening brackets at the
beginning of a config line), a configuration file from
FGo! 1.5.5 or earlier should be usable as is by {prg}.""")
                  .replace('\n', ' ') + "\n\n" + _("""\
If {fgo_cfgfile} was written by FGo! 1.5.5 or earlier, you
should probably say “Yes” here in order to initialize {prg}'s
configuration based on your FGo! config file (precisely:
copy {fgo_cfgfile} to {cfgfile}).""")
                  .replace('\n', ' ') + "\n\n" + _("""\
If {fgo_cfgfile} was written by a version of FGo! that is greater
than 1.5.5, it is advised to say “No” here.""")
                  .replace('\n', ' ')
                 ).format(prg=PROGNAME, cfgfile=CONFIG, fgo_cfgfile=FGO_CONFIG)

        if askyesno(PROGNAME, message, detail=detail, parent=parent):
            choice = "migrate from FGo!"
        else:
            message = _("Create a default {prg} configuration?").format(
                prg=PROGNAME)
            detail = _("""\
Choose “Yes” to create a basic {prg} configuration now. If you
choose “No”, {prg} will exit and you'll have to create {cfgfile}
yourself, or restart {prg} to see the same questions again.""") \
                     .replace('\n', ' ').format(prg=PROGNAME, cfgfile=CONFIG)

            if askyesno(PROGNAME, message, detail=detail, parent=parent):
                choice = "create default cfg"
                message = _("Creating a default {prg} configuration.").format(
                    prg=PROGNAME)
                detail = (_("""\
It is suggested that you go to the Settings menu and choose
Preferences to review your newly-created configuration.""")
                          .replace('\n', ' ') + "\n\n" + _("""\
You can also reuse most, if not all FlightGear options you
had in FGo!'s main text box (the “options window”). Just copy
them to the corresponding {prg} text box.""")
                          .replace('\n', ' ') + "\n\n" + _("""\
Note: you may run both FGo! and {prg} simultaneously, as their
configurations are kept separate.""")
                          .replace('\n', ' ')
                         ).format(prg=PROGNAME)
                showinfo(PROGNAME, message, detail=detail, parent=parent)
            else:
                choice = "abort"

        return choice

    def _maybeMigrateFromFGoConfig(self):
        if os.path.isfile(FGO_CONFIG) and not os.path.isfile(CONFIG):
            baseSize = tkinter.font.nametofont("TkDefaultFont").actual()["size"]
            def configFontSize(val, absolute=False):
                for style in ("Default", "Text", "Fixed", "Caption", "Tooltip"):
                    font = tkinter.font.nametofont("Tk{}Font".format(style))
                    if absolute:
                        font.configure(size=val)
                    else:
                        font.configure(size=int(round(baseSize * val)))

            # Make sure most people can read the following dialogs (the
            # standard Tk size may be rather small): 140% increase
            configFontSize(1.4, absolute=False)

            choice = None       # user choice in the to-be-displayed dialogs
            # It seems we need an otherwise useless Toplevel window in order to
            # center the Tk standard dialogs...
            t = tkinter.Toplevel()
            try:
                # Transparent if the OS supports it
                t.attributes('-alpha', '0.0')
                # Center the Toplevel. To be effective, this would probably
                # need a visit to the Tk event loop, however it is enough to
                # have the child dialogs centered, which is what matters here.
                self.master.eval('tk::PlaceWindow {} center'.format(
                    t.winfo_pathname(t.winfo_id())))
                choice = self._maybeMigrateFromFGoConfig_dialogs(t)
            finally:
                t.destroy()

            # Restore font size for later self.setupFonts() call
            configFontSize(baseSize, absolute=True)

            if choice in (None, "abort"):
                raise AbortConfig
            elif choice == "migrate from FGo!":
                # shutil.copy() and shutil.copy2() attempt to preserve the file's
                # permission mode, which is undesirable here → manual copy.
                with open(FGO_CONFIG, "r", encoding='utf-8') as fgoConfig, \
                     open(CONFIG, "w", encoding='utf-8') as config:
                    config.write(fgoConfig.read())
            else:
                assert choice == "create default cfg", repr(choice)

    def _makeAptDigest(self, head=None):
        """Build apt database from apt.dat.gz"""
        if self.FG_root.get():
            _ProcessApt(self.master, self, self.apt_path, head)

    def _read(self, path=None):
        """Read the specified or a default configuration file.

        - If 'path' is None and CONFIG exists, load CONFIG;
        - if 'path' is None and CONFIG does not exist, load the
          configuration from the presets and default, localized
          config_ll resource;
        - otherwise, load configuration from the specified file.

        """
        try:
            # ExitStack not strictly necessary here, but allows clean and
            # convenient handling of the various files or resources the
            # configuration may be loaded from.
            with contextlib.ExitStack() as stack:
                res = self._read0(stack, path)
        except OSError as e:
            message = _('Error loading configuration')
            showerror(_('{prg}').format(prg=PROGNAME), message, detail=str(e))
            res = ([''], '')

        return res

    _presetsBlankLineOrCommentCre = re.compile(r"^[ \t]*(#|$)")

    def _read0(self, stack, path):
        # Data before the CUT_LINE in the config file, destined to
        # self.settings
        settings = []
        # Data after the CUT_LINE in the config file, destined to
        # self.text and to be parsed by CondConfigParser
        condConfLines = []

        if path is not None or (path is None and os.path.exists(CONFIG)):
            if path is None:
                path = CONFIG
            logger.info("Opening config file '{}' for reading".format(path))
            configStream = stack.enter_context(open(path, "r",
                                                    encoding="utf-8"))
            beforeCutLine = True
        else:                 # Use default config if no regular config exists.
            # Load presets if exists.
            if resourceExists(PRESETS):
                with textResourceStream(PRESETS) as presets:
                    for line in presets:
                        line = line.strip()
                        if not self._presetsBlankLineOrCommentCre.match(line):
                            settings.append(line)

            # Find the currently used language according to the environment.
            try:
                lang_code = gettext.translation(
                    MESSAGES, LOCALE_DIR).info()['language']
            except OSError:
                lang_code = 'en'

            if not resourceExists(DEFAULT_CONFIG_STEM + lang_code):
                lang_code = 'en'
            resPath = DEFAULT_CONFIG_STEM + lang_code

            configStream = stack.enter_context(textResourceStream(resPath))
            # There is no "cut line" in the template config files.
            beforeCutLine = False

        for line in configStream:
            if beforeCutLine:
                line = line.strip()

            if line != CUT_LINE:
                if beforeCutLine:
                    # Comments wouldn't be preserved on saving, therefore don't
                    # try to handle them before the "cut line".
                    if line:
                        settings.append(line)
                else:
                    condConfLines.append(line)
            else:
                beforeCutLine = False

        return (settings, ''.join(condConfLines))

    def _readAircraft(self):
        """
        Walk through Aircraft directories and return the available aircrafts.

        Return a tuple (aircraftDict, aircraftList) listing all
        aircrafts found via self.aircraft_dirs.

        aircraftDict is a dictionary whose keys are the names (derived
        from the -set.xml files) of all aircrafts. For each aircraft
        name 'n', aircraftDict[n] is the list, in self.aircraft_dirs
        priority order, of all Aircraft instances with that name.

        aircraftList is the sorted list of all Aircraft instances,
        suitable for quick building of the aircraft list in the GUI.

        """
        aircraftDict = {}
        for dir_ in self.aircraft_dirs:
            if os.path.isdir(dir_):
                for d in os.listdir(dir_):
                    self._readAircraftData(dir_, d, aircraftDict)

        aircraftList = []
        # First sort by lowercased aircraft name
        sortFunc = lambda s: (s.lower(), s)
        for acName in sorted(aircraftDict.keys(), key=sortFunc):
            # Then sort by position in self.aircraft_dirs
            aircraftList.extend(aircraftDict[acName])

        return (aircraftDict, aircraftList)

    def _readAircraftData(self, dir_, d, aircraftDict):
        path = os.path.join(dir_, d)
        if os.path.isdir(path):
            for f in os.listdir(path):
                self._appendAircraft(f, aircraftDict, path)

    def _appendAircraft(self, f, aircraftDict, path):
        if f.endswith('-set.xml'):
            # Dirty and ugly hack to prevent carrier-set.xml in
            # seahawk directory to be attached to the aircraft
            # list.
            if (not path.startswith('seahawk') and
                    f != 'carrier-set.xml'):
                name = f[:-8]
                if name not in aircraftDict:
                    aircraftDict[name] = []

                aircraft = Aircraft(name, path)
                aircraftDict[name].append(aircraft)

    def sortedIcao(self):
        return sorted(self.airports.keys())

    def _readApt(self):
        """Read the apt digest file (create a new one if none exists).

        Return a list of AirportStub instances.

        """
        from .fgdata import apt_dat

        if not os.path.exists(APT):
            # Create a new file if self.FG_root is non-empty
            self._makeAptDigest()

        if not os.path.isfile(APT): # may happen if self.FG_root was empty
            self.aptDatSize, self.airports = 0, {}
            return []

        for attempt in itertools.count(start=1):
            try:
                self.aptDatSize, self.airports = apt_dat.AptDatDigest.read(APT)
            except apt_dat.UnableToParseAptDigest:
                if attempt < 2:
                    self._makeAptDigest()
                else:
                    raise
            else:
                break

        if self.filteredAptList.get():
            installedApt = self._readInstalledAptSet()
            res = [ self.airports[icao] for icao in self.sortedIcao()
                    if icao in installedApt ]
        else:
            res = [ self.airports[icao] for icao in self.sortedIcao() ]

        return res

    def _readInstalledAptSet(self):
        """Read the set of locally installed airports from INSTALLED_APT.

        Create a new INSTALLED_APT file if none exists yet.
        Return a frozenset(), which offers very fast membership test
        compared to a list.

        """
        if not os.path.exists(INSTALLED_APT):
            self.makeInstalledAptList()

        logger.info("Opening installed apt file '{}' for reading".format(
            INSTALLED_APT))

        with open(INSTALLED_APT, "r", encoding="utf-8") as f:
            # Strip the newline char ending every line
            res = frozenset([ line[:-1] for line in f ])

        return res

    def _readScenarios(self):
        """Walk through AI scenarios and read carrier data.

        Return two lists:
            scenarios: [scenario name, ...]
            carrier data: [[name, parkking pos, ..., scenario name], ...]
        Return two empty lists if no scenario is found.
        """
        carriers = []
        scenarios = []
        if os.path.isdir(self.ai_path):
            for f in os.listdir(self.ai_path):
                path = os.path.join(self.ai_path, f)

                if os.path.isfile(path) and f.lower().endswith('.xml'):
                    scenario_name = f[:-4]
                    scenarios.append(scenario_name)
                    # Appends to 'carriers'
                    self._append_carrier_data(carriers, path, scenario_name)

        return sorted(scenarios), sorted(carriers)

    def _append_carrier_data(self, carriers, xmlFilePath, scenario_name):
        logger.info("Reading scenario data from '{}'".format(xmlFilePath))
        root = self._get_root(xmlFilePath)
        scenario = root.find('scenario')

        if scenario is not None:
            for e in scenario.iterfind('entry'):
                typeElt = e.find('type')
                if typeElt is not None and typeElt.text == 'carrier':
                    data = self._get_carrier_data(e, scenario_name)
                    carriers.append(data)

    def _get_root(self, xmlFilePath):
        tree = ElementTree.parse(xmlFilePath)
        return tree.getroot()

    def _get_carrier_data(self, e, scenario_name):
        nameElt = e.find('name')
        if nameElt is not None:
            data = [nameElt.text]
        else:
            data = ['unnamed']

        for child in e.iterfind('parking-pos'):
            parkingNameElt = child.find('name')
            if parkingNameElt is not None:
                data.append(parkingNameElt.text)

        data.append(scenario_name)
        return data

    # The '1' is the version number of this custom format for the contents of
    # Config.park, in case we need to change it.
    aptDatParkConfStart_cre = re.compile(r"::apt\.dat::1::(?P<nameLen>\d+),")
    aptDatParkConfEnd_cre = re.compile(
        r"""lat=(?P<lat>{floatRegexp}),
            lon=(?P<lon>{floatRegexp}),
            heading=(?P<heading>{floatRegexp})$""".format(
            floatRegexp=r"-?\d+(\.\d*)?"),
        re.VERBOSE)

    def decodeParkingSetting(self, parkConf):
        status = "invalid"      # will be overridden if correct in the end
        parkName = None
        options = []

        if not parkConf:
            status = "none"     # no parking position
        else:
            mo = self.aptDatParkConfStart_cre.match(parkConf)
            if mo:
                # Length of the following parking name (after the comma)
                nameLen = int(mo.group("nameLen"))
                i = mo.end("nameLen") + 1 + nameLen

                if len(parkConf) > i and parkConf[i] == ";":
                    mo2 = self.aptDatParkConfEnd_cre.match(parkConf[i+1:])
                    if mo2:
                        parkName = parkConf[mo.end("nameLen")+1:i]
                        options = ["--lat=" + mo2.group("lat"),
                                   "--lon=" + mo2.group("lon"),
                                   "--heading=" + mo2.group("heading")]
                        status = "apt.dat"
            else:                   # plain parking name
                parkName = parkConf
                options = ["--parkpos=" + parkName]
                status = "groundnet"

        return (status, parkName, options)

    def _earlyTranslationsSetup(self):
        """Setup translations before the config file has been read.

        The language is determined from the environment (LANGUAGE,
        LC_ALL, LC_MESSAGES, and LANG—cf. gettext.translation() and
        gettext.find()).

        """
        try:
            langCode = gettext.translation(
                MESSAGES, LOCALE_DIR).info()['language']
        except OSError:
            langCode = 'en'

        self._setLanguage(langCode)

    def _setLanguage(self, lang):
        # Initialize provided language...
        try:
            L = gettext.translation(MESSAGES, LOCALE_DIR, languages=[lang])
            L.install()
        # ...or fallback to system default.
        except Exception:
            gettext.install(MESSAGES, LOCALE_DIR)

    # Regexp for directory names such as w040n20
    _geoDirCre = re.compile(r"[we]\d{3}[ns]\d{2}$")

    def _stringToCoordinates(self, coordinates):
        """Convert geo coordinates to decimal format."""
        if not self._geoDirCre.match(coordinates):
            return None

        lat = coordinates[4:]
        lon = coordinates[:4]

        lat_range = self._calculateRange(lat)
        lon_range = self._calculateRange(lon)
        return lat_range, lon_range

    def _autoUpdateApt(self):
        if not self.auto_update_apt.get() or not os.path.exists(self.apt_path):
            return
        old_timestamp = self._readAptTimestamp()
        self._updateApt(old_timestamp)

    def _readAptTimestamp(self):
        if not os.path.exists(APT_TIMESTAMP):
            self._writeAptTimestamp('')

        logger.info("Opening apt timestamp file '{}' for reading".format(
            APT_TIMESTAMP))
        with open(APT_TIMESTAMP, "r", encoding="utf-8") as timestamp:
            old_modtime = timestamp.read()
        return old_modtime

    def _writeAptTimestamp(self, s=None):
        if s is None:
            s = self._getAptModTime()

        logger.info("Opening apt timestamp file '{}' for writing".format(
            APT_TIMESTAMP))
        with open(APT_TIMESTAMP, "w", encoding="utf-8") as timestamp:
            timestamp.write(s)

    def _getAptModTime(self):
        return str(os.path.getmtime(self.apt_path))

    def _updateApt(self, old_timestamp):
        if old_timestamp != self._getAptModTime():
            self._makeAptDigest(head=_('Modification of apt.dat.gz detected.'))
            # The new apt.dat may invalidate the current parking
            status, *rest = self.decodeParkingSetting(self.park.get())
            if status == "apt.dat":
                # This was a parking position obtained from apt.dat; it may be
                # invalid with the new file, reset.
                self.park.set('')

            # This is also outdated with respect to the new apt.dat.
            self.aptDatCache.clear()

    # Accept any arguments to allow safe use as a Tkinter variable observer
    def updateMagFieldProvider(self, *args):
        from .geo.magfield import EarthMagneticField, MagVarUnavailable
        try:
            self.earthMagneticField = EarthMagneticField(self)
        except MagVarUnavailable as e:
            self.earthMagneticField = None
            self.earthMagneticFieldLastProblem = e.message

        from .fgdata import airport as airport_mod
        from .fgdata import parking as parking_mod
        from .gui import airport_finder as airport_finder_mod
        from .gui import gps_tool as gps_tool_mod

        for module in (airport_mod, parking_mod, airport_finder_mod,
                       gps_tool_mod):
            module.setupEarthMagneticFieldProvider(self.earthMagneticField)
示例#27
0
    def __init__(self, args, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        self.configure(background='#2D303D')
        self.controller.title("CMC Video Recorder")

        camera_options = cameras.keys()

        global location
        location = StringVar()

        location.set('hall')

        loc_label = Label(self,
                          text="Choose a camera location",
                          background="#2D303D",
                          foreground="#ffffff",
                          padx="20",
                          pady="10",
                          font="16")

        loc_menu = OptionMenu(self, location, *camera_options)
        loc_menu.config(background="#21232d",
                        foreground="#ffffff",
                        activebackground="#E95420",
                        padx="20",
                        pady="10",
                        font="16")

        loc_label.place(relx=.25, rely=.25, anchor="c")
        loc_menu.place(relx=.25, rely=.35, anchor="c")

        path_label = Label(self,
                           text="Choose a path to save video",
                           background="#2D303D",
                           foreground="#ffffff",
                           padx="20",
                           pady="10",
                           font="16")

        button_path = Button(self,
                             text="Choose",
                             command=self.get_path,
                             bd=0,
                             highlightthickness=0,
                             background="#21232d",
                             foreground="#ffffff",
                             activebackground="#E95420",
                             padx="20",
                             pady="10",
                             font="16")

        path_label.place(relx=.75, rely=.25, anchor="c")
        button_path.place(relx=.75, rely=.35, anchor="c")

        def change_dropdown(*args):
            print(location.get())

        # link function to change dropdown
        location.trace('w', change_dropdown)

        button_record = Button(self,
                               text="Load camera",
                               command=self.load_camera,
                               bd=0,
                               highlightthickness=0,
                               background="#21232d",
                               foreground="#ffffff",
                               activebackground="#E95420",
                               padx="20",
                               pady="10",
                               font="16")
        button_record.place(relx=.5, rely=.5, anchor="c")
示例#28
0
文件: main.py 项目: qcaron/stampede
class WindowApp(object):
    """
    The PDF Stampede app window
    """
    def __init__(self, resizable=(True, True), geometry=(620, 220)):
        assert (isinstance(resizable, (tuple, list)))
        assert (isinstance(geometry, (tuple, list)))

        self.root = Tk()

        self.config = configparser.ConfigParser()
        self.config_file_name = "config.ini"
        self.config.read(self.config_file_name)

        self.default_case = StringVar(value=self.config["DEFAULT"].get("case", "CASE"))
        self.default_team = StringVar(value=self.config["DEFAULT"].get("team", "TEAM"))
        self.default_series = StringVar()
        self.default_last_index = StringVar()

        self.root.title("The Stampede")
        self.root.resizable(width=resizable[0], height=resizable[1])
        self.root.geometry('{}x{}'.format(geometry[0], geometry[1]))
        self.root.minsize(geometry[0], geometry[1])
        self.root.maxsize(geometry[0]+200, geometry[1])
        self.file_name = StringVar()
        self.file_name.trace("w", self.file_name_changed)
        self.stamp_button = None
        self.add_widgets()
        self.add_menus()
        self.center(self.root)

    def add_widgets(self):
        # File
        frame = Frame(self.root)
        frame.pack(side=TOP, fill=X, expand=True, ipady=5)
        file_label = Label(frame, text="PDF File", width=10)
        file_label.pack(side=LEFT, padx=5, pady=5)
        file_entry = Entry(frame, state=DISABLED, textvariable=self.file_name)
        file_entry.pack(padx=5, side=LEFT, fill=X, expand=True)
        file_button = Button(frame, text="Browse...", command=self.choose_pdf)
        file_button.pack(padx=5, side=RIGHT)

        # Case
        frame = Frame(self.root)
        frame.pack(side=TOP, fill=X, expand=True)
        case_label = Label(frame, text="Case", width=10)
        case_label.pack(side=LEFT, padx=5, pady=5)
        case_entry = Entry(frame, textvariable=self.default_case)
        case_entry.pack(fill=X, padx=5, expand=True)

        # Team
        frame = Frame(self.root)
        frame.pack(fill=BOTH, expand=True)
        team_label = Label(frame, text="Team", width=10)
        team_label.pack(side=LEFT, padx=5, pady=5)
        team_entry = Entry(frame, textvariable=self.default_team)
        team_entry.pack(fill=X, padx=5, expand=True)

        # Series
        frame = Frame(self.root)
        frame.pack(fill=BOTH, expand=True)
        series_label = Label(frame, text="Series", width=10)
        series_label.pack(side=LEFT, padx=5, pady=5)
        series_entry = Entry(frame, textvariable=self.default_series)
        series_entry.pack(fill=X, padx=5, expand=True)

        # Last index
        frame = Frame(self.root)
        frame.pack(fill=BOTH, expand=True)
        last_index_label = Label(frame, text="Last index", width=10)
        last_index_label.pack(side=LEFT, padx=5, pady=5)
        last_index_entry = Entry(frame, textvariable=self.default_last_index)
        last_index_entry.pack(fill=X, padx=5, expand=True)

        bottom_frame = Frame(self.root)
        bottom_frame.pack(side=BOTTOM, fill=X, ipady=5, padx=5)

        close_button = Button(bottom_frame, text="Quit", command=self.root.quit)
        close_button.pack(side=RIGHT)
        self.stamp_button = Button(bottom_frame, text="Stamp it!", state=DISABLED, command=self.stamp_it)
        self.stamp_button.pack(side=RIGHT)

    def stamp_it(self):
        stamp_it(
            self.file_name.get(),
            self.default_case.get(),
            self.default_team.get(),
            self.default_series.get(),
            self.default_last_index.get(),
        )

    def add_menus(self):
        menu_bar = Menu(self.root)
        stampede_menu = Menu(menu_bar, tearoff=0)
        stampede_menu.add_command(label="Settings", command=self.edit_default_settings)
        stampede_menu.add_separator()
        stampede_menu.add_command(label="Quit", command=self.root.quit)
        menu_bar.add_cascade(label="Stampede", menu=stampede_menu)

        self.root.config(menu=menu_bar)

    def run(self):
        self.root.mainloop()

    def center(self, window):
        window.update_idletasks()
        width = window.winfo_width()
        height = window.winfo_height()
        x = (window.winfo_screenwidth() // 2) - (width // 2)
        y = (window.winfo_screenheight() // 2) - (height // 2)
        window.geometry('{}x{}+{}+{}'.format(width, height, x, y))

    def edit_default_settings(self):
        SettingsDialog(self.root, config=self.config, config_file_name=self.config_file_name)

    def choose_pdf(self):
        self.file_name.set(filedialog.askopenfilename(filetypes=(("PDF files", "*.pdf"),)))

    def file_name_changed(self, *args):
        if self.file_name.get():
            self.stamp_button.configure(state=NORMAL)
        else:
            self.stamp_button.configure(state=DISABLED)
    def __init__(self, output_path="./"):
        """ Initialize application which uses OpenCV + Tkinter. It displays
            a video stream in a Tkinter window and stores current snapshot on disk """

        self.output_path = output_path  # store output path
        self.current_image = None  # current image from the camera

        self.root = Tk()  # initialize root window
        self.root.geometry('1200x600')
        self.root.title("Attendance")  # set window title
        self.destructor  #function gets fired when the window is closed
        self.root.protocol('WM_DELETE_WINDOW', self.destructor)
        self.panel = Label(self.root, background='maroon', padx=320,
                           pady=230)  # initialize image panel

        self.panel.pack(padx=10, pady=10)

        self.root.config(cursor="arrow")
        global cam, period, faculty, subject
        period = StringVar(self.root)
        faculty = StringVar(self.root)
        subject = StringVar(self.root)
        cam = StringVar(self.root)
        #create a button, that when pressed, will take the current frame and save it to file

        attdButton = Label(self.root,
                           text="ATTENDANCE",
                           font=("Arial", 20),
                           bg='maroon',
                           fg='white')
        attdButton.place(x=50, y=50)

        startButton = Button(self.root,
                             text="Start",
                             borderwidth=2,
                             relief='raised',
                             font=("Arial", 20),
                             padx=50,
                             bg='dark blue',
                             fg='white',
                             command=self.start_cam)
        startButton.place(x=970, y=160)

        closeButton = Button(self.root,
                             text="Close",
                             font=("Arial", 20),
                             padx=45,
                             bg="dark blue",
                             fg='white',
                             command=self.destructor)
        closeButton.place(x=970, y=430)

        updateButton = Button(self.root,
                              text="Update",
                              font=("Arial", 20),
                              padx=35,
                              bg="dark blue",
                              fg='white',
                              command=self.update)
        updateButton.place(x=970, y=250)

        emailButton = Button(self.root,
                             text='Email',
                             font=("Arial", 20),
                             padx=45,
                             bg='dark blue',
                             fg='white',
                             command=self.email)
        emailButton.place(x=970, y=340)

        cam = " "
        global camMenu
        camMenu = Entry(self.root)
        camMenu.place(x=50, y=410)

        camLabel = Label(self.root,
                         text='Choose Camera',
                         font=("Arial Bold", 10))
        camLabel.place(x=50, y=390)

        global lst_subject, lst_faculty
        facsub = pd.read_csv('Sub_fac.csv')
        subject_name = facsub['Subject']
        faculty_name = facsub['Faculty']
        lst_subject = subject_name.tolist()
        lst_faculty = faculty_name.tolist()

        periodLabel = Label(self.root,
                            text='Choose Period',
                            font=("Arial Bold", 10))
        periodLabel.place(x=50, y=180)

        choices_period = [
            "1" + " " * 30, "2" + " " * 30, "3" + " " * 30, "4" + " " * 30,
            "5" + " " * 30, "6" + " " * 30, "7" + " " * 30, "8" + " " * 30
        ]
        period.set("Period")
        popupMenu = OptionMenu(self.root, period, *choices_period)
        popupMenu.place(x=50, y=200)

        def change_period(*args):
            global selected_period
            selected_period = period.get()

        # link function to change dropdown
        period.trace('w', change_period)

        facultyLabel = Label(self.root,
                             text='Choose Faculty',
                             font=("Arial Bold", 10))
        facultyLabel.place(x=50, y=250)

        length = 25
        lst_faculty = [i + " " * (length - len(i)) for i in lst_faculty]
        choices_faculty = lst_faculty
        faculty.set("Faculty")
        popupMenu_f = OptionMenu(self.root, faculty, *choices_faculty)
        popupMenu_f.place(x=50, y=270)

        def change_faculty(*args):
            global selected_faculty
            selected_faculty = faculty.get()

        faculty.trace('w', change_faculty)

        subjectLabel = Label(self.root,
                             text='Choose Subject',
                             font=("Arial Bold", 10))
        subjectLabel.place(x=50, y=320)

        lst_subject = [i + " " * (length - len(i)) for i in lst_subject]
        choices_subject = lst_subject
        subject.set("Subject")
        popupMenu_s = OptionMenu(self.root, subject, *choices_subject)
        popupMenu_s.place(x=50, y=340)

        def change_subject(*args):
            global selected_subject
            selected_subject = subject.get()

        subject.trace('w', change_subject)

        datetimeButton = Label(
            self.root,
            borderwidth=2,
            relief='groove',
            text="Date : " + str(datetime.datetime.now().strftime("%d-%m-%Y")),
            font=("Arial Bold", 17),
            padx=30)
        datetimeButton.place(x=935, y=50)

        snapbtn = Button(self.root,
                         text="Snapshot!",
                         command=self.take_snapshot,
                         padx=50,
                         pady=10,
                         bg='dark blue',
                         font=("Arial Bold", 10),
                         fg='white')
        snapbtn.place(x=500, y=500)
示例#30
0
class DropdownList:
    def __init__(self, master, filemask='*.mln', default=None, allowNone=False, onselchange=None, directory='.'):
        self.allowNone = allowNone
        self.directory = directory
        self.list_frame = master
        self.onchange = onselchange
        if type(filemask) != list:
            filemask = [filemask]
        self.file_mask = filemask
        self.updateList()
        if havePMW:
            self.list = ComboBox(master, selectioncommand=onselchange, scrolledlist_items = self.files)
            self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised')
            self.picked_name = self.list
        else:
            self.picked_name = StringVar()
            self.list = OptionMenu(*(master, self.picked_name) + tuple(self.files))
            if onselchange is not None:
                self.picked_name.trace("w", self.onchange)
        if default is not None:
            self.select(default)
        else:
            self.select(self.files[0])


    def __getattr__(self, name):
        return getattr(self.list, name)


    def get(self):
        return self.picked_name.get()


    def select(self, item):
        if item in self.files:
            if not havePMW:
                self.picked_name.set(item)
            else:
                self.list.selectitem(item)


    def updateList(self):
        self.files = []
        if self.allowNone:
            self.files.append("")
        if os.path.exists(self.directory):
            for filename in os.listdir(self.directory):
                for fm in self.file_mask:
                    if fnmatch(filename, fm):
                        self.files.append(filename)
        self.files.sort()
        if len(self.files) == 0 and not self.allowNone: self.files.append("(no %s files found)" % str(self.file_mask))



    def makelist(self):
        if havePMW:
            self.list = ComboBox(self.list_frame,
                    selectioncommand = self.onSelChange,
                    scrolledlist_items = self.files,
            )
            self.list.grid(row=0, column=0, padx=0, pady=0, sticky="NEWS")
            self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised')
            self.picked_name = self.list
        else:
            self.list = OptionMenu(*(self.list_frame, self.picked_name) + tuple(self.files))
            self.list.grid(row=0, column=0, sticky="NEW")
            self.picked_name.trace("w", self.onSelChange)
        self.select(self.files[0])

    def setDirectory(self, directory, keep=False):
        self.directory = directory
        self.updateList()
        self.makelist()
        # if keep is true, only the files list will be updated but the content of the
        # text area will not be altered/removed
        if not keep: self.select("")


    def onSelChange(self, name, index=0, mode=0):
        filename = self.picked_name.get()
        if self.onchange != None:
            self.onchange(filename)
示例#31
0
class BotFrame(ttk.Frame):
    """Bottom part of the LeftFrame of the GUI. Handles all of the paths
    involved in the creation of a Job and updates the template in RightFrame
    when the template path changes.
    """
    def __init__(self, parent, row=2, col=0):
        ttk.Frame.__init__(self, parent)
        self.grid(row=row, column=col, pady=10)
        self.parent = parent

        title = ttk.Label(self,
                          text="Enviroment options",
                          font=("Helvetica", 16),
                          justify="center")
        title.grid(row=row, column=col, columnspan=2)

        self.job = self.parent.job

        #######################################################################
        #            Path to where job DQS files will be produced
        #######################################################################
        self.jobsavepath = StringVar()
        self.jobsavepath.set(self.job.save_path)

        a = ttk.Button(self,
                       text="Select Save Folder",
                       width=15,
                       command=self.setSavePathWithPrompt)
        a.grid(row=row + 1, column=col, pady=5, sticky=W)

        b = ttk.Entry(self, textvariable=self.jobsavepath, width=25)
        b.grid(row=row + 1, column=col + 1, pady=5, sticky=W + E)

        #######################################################################
        #            Path to where the current template is located
        #######################################################################
        self.tmpltpath = StringVar(self)
        self.tmpltpath.set(self.job.template_path)
        self.tmpltpath.trace("w", self.setTemplatePath)

        c = ttk.Button(self,
                       text="Select template",
                       width=15,
                       command=self.setTemplatePathWithPrompt)
        c.grid(row=row + 2, column=col, pady=5, sticky=W)

        d = ttk.Entry(self, textvariable=self.tmpltpath, width=25)
        d.grid(row=row + 2, column=col + 1, pady=5, sticky=W + E)

        #######################################################################
        #            Path to where the results will be saved on the cluster
        #######################################################################
        respathl = ttk.Label(self, text="Results save folder: ")
        respathl.grid(row=row + 6, column=col, pady=3, sticky=W)

        self.respath = ttk.Entry(self)
        self.respath.insert(0, self.job.res_path)
        self.respath.grid(row=row + 6, column=col + 1, pady=3, sticky=W + E)

        #######################################################################
        #            Edit template
        #######################################################################
        e = ttk.Button(self,
                       text="Edit template",
                       width=15,
                       command=self.editTemplate)
        e.grid(row=row + 3, column=col, pady=5, sticky=W + E)

        self.savetmpbtn = ttk.Button(self,
                                     text="Save template",
                                     width=15,
                                     state=DISABLED,
                                     command=self.saveTemplate)
        self.savetmpbtn.grid(row=row + 3, column=col + 1, pady=5, sticky=W + E)

    def setSavePathWithPrompt(self):
        """Callback that will spawn a directory selector through which a new
        path, where the job DQS files will be saved, can be selected.
        """
        newpath = filedialog.askdirectory(
            parent=self,
            title="Please select save destination.",
            initialdir=self.jobsavepath)
        # consider exiting via 'x' button the same as pressing cancel
        if newpath == ():
            self.jobsavepath.set(newpath)

    def setTemplatePath(self, *args):
        """Callback that will track the Entry box of the template path and upon
        modification will cause the RightFrame template display to reload the
        new template.
        """
        newpath = self.tmpltpath.get()
        self.updateTemplatePath(newpath)

    def setTemplatePathWithPrompt(self):
        """Callback that will spawn a file selector window through which a new
        template can be selected. See setTemplatePath.
        Will cause an update of the RightFrame to redisplay the newly selected
        template.
        """
        initdir = os.path.dirname(self.tmpltpath.get())
        newpath = filedialog.askopenfilename(parent=self,
                                             title="Please select a template.",
                                             initialdir=initdir)
        # consider exiting via 'x' button the same as pressing cancel
        if newpath != ():
            self.tmpltpath.set(newpath)
            self.updateTemplatePath(newpath, showerr=True)

    def updateTemplatePath(self, path, showerr=False):
        """Updates the RightFrame's template display and replaces the current
        content with content read from a file at the provided path. If showerr
        is supplied an error will be raised if the given path does not exist.
        This is useful if the directory will be created after the path
        selection or if the update is called from a callback tied to a
        StringVar/Entry trace methods as a way to silence errors untill the
        full path has been  manually inputed.

        Parameters
        ----------
        path : str
          path to the new template
        showerr : bool
          if False no error will be raised even if path does not exist, usefull
          when error needs to be raised later, on a callback initiated by a
          button click
        """
        tmppath = expandpath(path)
        activetmpl = self.parent.root.rightFrame.activetmpl

        if tmppath[0] and os.path.isfile(tmppath[1]):
            activetmpl.config(state=NORMAL)
            activetmpl.delete(1.0, END)
            activetmpl.insert(1.0, open(tmppath[1], "r").read())
            activetmpl.config(state=DISABLED)
            self.job.template_path = tmppath[1]
        else:
            if showerr:
                messagebox.showerror(("Input Error. Input path does not exist "
                                      "or is a folder! {}".format(path)))
            activetmpl.config(state=NORMAL)
            activetmpl.delete(1.0, END)
            activetmpl.config(state=DISABLED)

    def editTemplate(self):
        """A callback of a Button action that will change the state of the
        RightFrame Text box and make it editable.
        """
        self.savetmpbtn.config(state=NORMAL)
        self.activetmpl = self.parent.root.rightFrame.activetmpl
        self.activetmpl.config(state=NORMAL)

    def saveTemplate(self):
        """A Button callback that will save the current template to a file.
        Spawns a file dialog to retrieve the save location. Changes the state
        of the RightFrame Text box back to un-editable.
        """
        self.savetmpbtn.config(state=DISABLED)
        self.activetmpl.config(state=DISABLED)

        filename = filedialog.asksaveasfilename(initialdir=self.tmpltpath,
                                                confirmoverwrite=True)
        f = open(filename, "w")
        for line in self.activetmpl.get(1.0, END):
            f.write(line)
        f.close()

        self.tmpltpath.set(filename)
示例#32
0
class FilePickEdit(Frame):
    
    def __init__(self, master, file_mask, default_file, edit_height = None, user_onChange = None, 
                 rename_on_edit=0, font = None, coloring=True, allowNone=False, highlighter=None, directory='.'):
        """
            file_mask: file mask (e.g. "*.foo") or list of file masks (e.g. ["*.foo", "*.abl"])
        """
        self.master = master
        self.directory = directory
        self.user_onChange = user_onChange
        Frame.__init__(self, master)
        row = 0
        self.unmodified = True
        self.allowNone = allowNone
        self.file_extension = ""
        if type(file_mask) != list:
            file_mask = [file_mask]
        if "." in file_mask[0]:
            self.file_extension = file_mask[0][file_mask[0].rfind('.'):]
        # read filenames
        self.file_mask = file_mask
        self.updateList()
        # filename frame
        self.list_frame = Frame(self)
        self.list_frame.grid(row=row, column=0, sticky="WE")
        self.list_frame.columnconfigure(0, weight=1)
        # create list
        self.picked_name = StringVar()
        self.makelist()
        # refresh button
        self.refresh_button = Button(self.list_frame, text='<- refresh', command=self.refresh, height=1)
        self.refresh_button.grid(row=0, column=1, sticky='E')        
        # save button
        self.save_button = Button(self.list_frame, text="save", command=self.save, height=1)
        self.save_button.grid(row=0, column=2, sticky="E")
        # editor
        row += 1
        if coloring:
            self.editor = SyntaxHighlightingText(self, self.onEdit, highlighter=highlighter)
        else:
            self.editor = ScrolledText2(self, self.onEdit)
        if font is not None:
            self.editor.configure(font=font)
        if edit_height is not None:
            self.editor.configure(height=edit_height)
        self.editor.grid(row=row, column=0, sticky="NEWS")
        self.rowconfigure(row, weight=1)
        self.columnconfigure(0, weight=1)
        # option to change filename on edit
        row += 1
        self.options_frame = Frame(self)
        self.options_frame.grid(row=row, column=0, sticky=W)
        self.rename_on_edit = IntVar()
        self.cb = Checkbutton(self.options_frame, text="rename on edit", variable=self.rename_on_edit)
        self.cb.pack(side=LEFT)
        self.cb.configure(command=self.onChangeRename)
        self.rename_on_edit.set(rename_on_edit)
        # filename frame
        row += 1
        self.filename_frame = Frame(self)
        self.filename_frame.grid(row=row, column=0, sticky="WE")
        self.filename_frame.columnconfigure(0, weight=1)
        # save as filename
        self.save_name = StringVar()
        self.save_edit = Entry(self.filename_frame, textvariable = self.save_name)
        self.save_edit.grid(row=0, column=0, sticky="WE")
        self.save_name.trace("w", self.onSaveChange)
        # pick default if applicableButton
        self.select(default_file)
        self.row = row
        
    def setDirectory(self, directory, keep=False):
        self.directory = directory
        self.updateList()
        self.makelist()
#         menu = self.list["menu"] scrolledlist
#         menu = self.list.listbox#["scrolledlist"]
#         menu.delete(0, 'end')
        # add the new ones
#         for filename in self.files:
#             menu.add_command(label=filename, command=_setit(self.picked_name, filename, None))
        # if keep is true, only the files list will be updated but the content of the
        # text area will not be altered/removed
        if not keep: self.select("")
    
    def refresh(self):
        sel = self.get()
        self.updateList()
        self.select(sel, notify=False)
    
    def reloadFile(self):
        self.editor.delete("1.0", END)
        filename = self.picked_name.get()
        if os.path.exists(os.path.join(self.directory, filename)):
            new_text = open(os.path.join(self.directory, filename)).read()
            if new_text.strip() == "":
                new_text = "// %s is empty\n" % filename
            new_text = new_text.replace("\r", "")
        else:
            new_text = ""
        self.editor.insert(INSERT, new_text)
        
    def setText(self, txt):
        """
        Replaces the text in the edit field as by typing
        into it.
        """
        self.select("")
        if txt.strip() == "":
            txt = "// empty database\n"
        self.editor.insert(INSERT, txt)
        self.onEdit()
        

    def onSelChange(self):
        self.reloadFile()
        filename = self.picked_name.get()
        self.save_name.set(filename)
        self.save_edit.configure(state=DISABLED)
        self.unmodified = True
        if self.user_onChange is not None:
            self.user_onChange(filename)

    def onSaveChange(self, name, index, mode):
        pass

    def autoRename(self):
        # modify "save as" name
        filename = self.picked_name.get()
        if filename == "": filename = "new" + self.file_extension # if no file selected, create new filename
        ext = ""
        extpos = filename.rfind(".")
        if extpos != -1: ext = filename[extpos:]
        base = filename[:extpos]
        hpos = base.rfind("-")
        num = 0
        if hpos != -1:
            try:
                num = int(base[hpos+1:])
                base = base[:hpos]
            except:
                pass
        while True:
            num += 1
            filename = "%s-%d%s" % (base, num, ext)
            if not os.path.exists(filename):
                break
        self.save_name.set(filename)
        # user callback
        if self.user_onChange is not None:
            self.user_onChange(filename)

    def onEdit(self):
        if self.unmodified:
            self.unmodified = False
            # do auto rename if it's enabled or there is no file selected (editing new file)
            if self.rename_on_edit.get() == 1 or self.picked_name.get() == "":
                self.autoRename()
            # enable editing of save as name
            self.save_edit.configure(state=NORMAL)

    def onChangeRename(self):
        # called when clicking on "rename on edit" checkbox
        if self.rename_on_edit.get() == 1:
            if (not self.unmodified) and self.save_name.get() == self.picked_name.get():
                self.autoRename()
        else:
            self.save_name.set(self.picked_name.get())

    def updateList(self):
        self.files = []
        if self.allowNone:
            self.files.append("")
        if os.path.exists(self.directory):
            for filename in os.listdir(self.directory):
                for fm in self.file_mask:
                    if fnmatch(filename, fm):
                        self.files.append(filename)
        self.files.sort()
        if len(self.files) == 0 and not self.allowNone: self.files.append("(no %s files found)" % str(self.file_mask))
        

    def select(self, filename, notify=True):
        """ selects the item given by filename """
        if filename in self.files:
            if not havePMW:
                self.picked_name.set(filename)
            else:
                self.list.selectitem(self.files.index(filename))
                if notify: self.onSelChange(filename)
        else:
            self.editor.delete("1.0", END)
                

    def makelist(self):
        if havePMW:
            self.list = ComboBox(self.list_frame,
                    selectioncommand = self.onSelChange,
                    scrolledlist_items = self.files,
            )
            self.list.grid(row=0, column=0, padx=0, pady=0, sticky="NEWS")
            self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised')
            self.picked_name = self.list
        else:
            self.list = OptionMenu(*(self.list_frame, self.picked_name) + tuple(self.files))
            self.list.grid(row=0, column=0, sticky="NEW")
            self.picked_name.trace("w", self.onSelChange)

    def save(self):
        self.get()

    def set(self, selected_item):
        self.select(selected_item)

    def get(self):
        """ gets the name of the currently selected file, saving it first if necessary """
        filename = self.save_name.get()
        if self.unmodified == False:
            self.unmodified = True
            # save the file
            f = open(os.path.join(self.directory, filename), "w")
            f.write(self.editor.get("1.0", END).encode('utf-8'))
            f.close()
            # add it to the list of files
#             if not filename in self.files:
#                 self.files.append(filename)
#                 self.files.sort()
#                 self.list.destroy()
#                 self.makelist()
            # set it as the new pick
            #if havePMW:
            #    self.picked_name.selectitem(self.files.index(filename), 1)
            #else:
            #    self.picked_name.set(filename)
#             self.select(filename)
            self.refresh()
            self.select(filename, notify=False)
            self.save_edit.configure(state=DISABLED)
        return filename

    def get_text(self):
        return self.editor.get("1.0", END)

    def get_filename(self):
        return self.save_name.get()

    def set_enabled(self, state):
        self.editor.configure(state=state)
        if havePMW:
            self.list.component('entryfield_entry').configure(state=state)
#             self.list.component('arrowbutton').configure(state=state)
            self.list.component('arrowbutton').bind('<1>', (lambda a: 'break') if state==DISABLED else self.list._postList)
        else:
            self.list.configure(state=state)
        self.save_button.configure(state=state)
        self.cb.configure(state=state)
        self.save_edit.configure(state=state)
示例#33
0
class HistoryWindow:
    def __init__(self, parent, win, hist_dict):
        self.window = win
        self.parent_window = parent
        self.hist_dict = hist_dict
        self.window.title("Full history")
        self.window.resizable(False, False)

        frm_top = Frame(win)
        frm_bottom = Frame(win)

        self.search = StringVar()
        self.search.trace(
            "w", lambda name, index, mode, sv=self.search: self.on_search(sv))
        self.entry_search = Entry(frm_top, textvariable=self.search, width=57)
        self.entry_search.pack(side=LEFT, fill=BOTH, expand=1)

        self.btn_clear = Button(frm_top, text="Clear", command=self.on_clear)
        self.btn_clear.pack(side=RIGHT, fill=BOTH, expand=1)

        self.list_box = Listbox(frm_bottom,
                                width=60,
                                height=40,
                                selectmode=SINGLE)
        self.list_box.pack(side=LEFT, fill=BOTH, expand=1)
        scroll = Scrollbar(frm_bottom,
                           command=self.list_box.yview,
                           orient=VERTICAL)
        scroll.pack(side=RIGHT, fill=Y)
        self.list_box.config(yscrollcommand=scroll.set)
        self.list_box.bind('<<ListboxSelect>>', self.on_listbox_select)

        frm_top.pack()
        frm_bottom.pack()

        self.window.bind("<FocusIn>", self.focus_callback)
        self.window.protocol("WM_DELETE_WINDOW", self.on_close)

        self.fill_list_box()

    def on_clear(self):
        self.search.set("")
        self.on_search(self.search)

    def on_search(self, search):
        query = search.get().strip().lower()
        if len(query) < 2:
            self.fill_list_box()
            return

        self.list_box.delete(0, END)
        search_results = []
        for key in self.hist_dict:
            pos = key.lower().find(query)
            if pos == -1:
                continue

            search_results.append((key, pos))

        search_results.sort(key=lambda x: x[1])
        self.list_box.insert(END, *[x[0] for x in search_results])

    def fill_list_box(self):
        self.list_box.delete(0, END)
        hist = sorted(self.hist_dict.items(), key=lambda x: x[1], reverse=True)
        self.list_box.insert(END, *[x[0] for x in hist])

    def on_listbox_select(self, event):
        w = event.widget
        selected = w.curselection()
        if len(selected) == 0:
            return

        index = selected[0]
        value = w.get(index)
        self.parent_window.cb_model.set(value)

    def lift(self):
        self.window.lift()

    def on_close(self):
        self.parent_window.hist_window = None
        self.window.update_idletasks()
        self.window.destroy()

    def focus_callback(self, event):
        self.entry_search.selection_range(0, END)
        root.lift()
示例#34
0
    def __init__(self, master, par=False):
        """
        GUI for selecting default parameters - will write parameters to file \
        of users choosing.

        :type master: Tk
        :param master: Tkinter window
        :type par: EQcorrscanParameters
        :param par: Default parameters to start-up with.
        """
        from tkinter import Label, Button, Entry, DoubleVar, StringVar, IntVar
        from tkinter import BooleanVar, OptionMenu, Checkbutton
        import tkMessageBox
        from eqcorrscan.utils import parameters
        from obspy import UTCDateTime
        import warnings

        # Set the default par, only if they don't already exist.
        if not par:
            par = parameters.EQcorrscanParameters([''], 2, 10, 4, 100, 2,
                                                  '1900-01-01', '2300-01-01',
                                                  '', 'seishub', 4, False, '',
                                                  'jpg', False, 8, 'MAD', 6)
        # Callback functions for all variables (ugly)

        def update_template_names(*args):
            par.template_names = [name.strip() for name in
                                  template_names.get().split(',')]
            template_names.set(', '.join(par.template_names))

        def update_lowcut(*args):
            par.lowcut = lowcut.get()
            lowcut.set(par.lowcut)

        def update_highcut(*args):
            par.highcut = highcut.get()
            if par.highcut >= 0.5 * par.samp_rate:
                msg = ('Highcut must be less than the Nyquist, setting to ' +
                       str((par.samp_rate / 2.0) - 1))
                tkMessageBox.showwarning(title="Nyquist error",
                                         message=msg)
                par.highcut = (par.samp_rate / 2.0) - 1
            highcut.set(par.highcut)

        def update_filt_order(*args):
            par.filt_order = filt_order.get()
            filt_order.set(par.filt_order)

        def update_samp_rate(*args):
            par.samp_rate = samp_rate.get()
            if par.highcut >= 0.5 * par.samp_rate:
                msg = ('Highcut must be less than the Nyquist, setting to ' +
                       str((par.samp_rate / 2.0) - 1))
                tkMessageBox.showwarning(title="Nyquist error",
                                         message=msg)
                par.highcut = (par.samp_rate / 2.0) - 1
                highcut.set(par.highcut)
            samp_rate.set(par.samp_rate)

        def update_debug(*args):
            par.debug = debug.get()
            debug.set(par.debug)

        def update_startdate(*args):
            par.startdate = UTCDateTime(startdate.get())
            startdate.set(str(par.startdate))

        def update_enddate(*args):
            par.enddate = UTCDateTime(enddate.get())
            enddate.set(str(par.enddate))

        def update_archive(*args):
            par.archive = archive.get()
            archive.set(par.archive)

        def update_arc_type(*args):
            par.arc_type = arc_type.get()
            arc_type.set(par.arc_type)

        def update_cores(*args):
            par.cores = cores.get()
            cores.set(par.cores)

        def update_plotvar(*args):
            par.plotvar = plotvar.get()
            plotvar.set(par.plotvar)

        def update_plot_format(*args):
            par.plot_format = plot_format.get()
            plot_format.set(par.plot_format)

        def update_tempdir(*args):
            par.tempdir = tempdir.get()
            tempdir.set(par.tempdir)

        def update_threshold(*args):
            par.threshold = threshold.get()
            threshold.set(par.threshold)

        def update_threshold_type(*args):
            par.threshold_type = threshold_type.get()
            threshold_type.set(par.threshold_type)

        def update_plotdir(*args):
            par.plotdir = plotdir.get()
            plotdir.set(par.plotdir)

        def update_trigger_interval(*args):
            par.trigger_interval = trigger_interval.get()
            trigger_interval.set(par.trigger_interval)
        # Set some grid parameters
        nrows = 25
        ncolumns = 3
        self.master = master
        master.title("EQcorrscan parameter setup")
        self.label = Label(master, text="Alpha GUI for default setup")
        self.label.grid(column=0, columnspan=ncolumns, row=0)

        # Set up parameter input
        self.t_names_label = Label(master, text="Template names", anchor='e')
        self.t_names_label.grid(column=0, row=1, sticky='e')
        template_names = StringVar()
        template_names.set(', '.join(par.template_names))
        self.t_names_box = Entry(master, bd=2, textvariable=template_names)
        self.t_names_box.grid(column=1, row=1)
        template_names.trace("w", update_template_names)
        self.t_names_lookup = Button(master, text="Lookup",
                                     command=lambda: self.get_template_names(par))
        self.t_names_lookup.grid(column=2, row=1)

        self.lowcut_label = Label(master, text="Lowcut (Hz)", anchor='e')
        self.lowcut_label.grid(column=0, row=2, sticky='e')
        lowcut = DoubleVar()
        lowcut.set(par.lowcut)
        self.lowcut_box = Entry(master, bd=2, textvariable=lowcut)
        self.lowcut_box.grid(column=1, row=2)
        lowcut.trace("w", update_lowcut)

        self.highcut_label = Label(master, text="Highcut (Hz)", anchor='e')
        self.highcut_label.grid(column=0, row=3, sticky='e')
        highcut = DoubleVar()
        highcut.set(par.highcut)
        self.highcut_box = Entry(master, bd=2, textvariable=highcut)
        self.highcut_box.grid(column=1, row=3)
        highcut.trace("w", update_highcut)

        self.filt_order_label = Label(master, text="Filter order")
        self.filt_order_label.grid(column=0, row=4, sticky='e')
        filt_order = DoubleVar()
        filt_order.set(par.filt_order)
        self.filt_order_box = Entry(master, bd=2, textvariable=filt_order)
        self.filt_order_box.grid(column=1, row=4)
        filt_order.trace("w", update_filt_order)

        self.samp_rate_label = Label(master, text="Sample rate (Hz)")
        self.samp_rate_label.grid(column=0, row=5, sticky='e')
        samp_rate = DoubleVar()
        samp_rate.set(par.samp_rate)
        self.samp_rate_box = Entry(master, bd=2, textvariable=samp_rate)
        self.samp_rate_box.grid(column=1, row=5)
        samp_rate.trace("w", update_samp_rate)

        self.debug_label = Label(master, text="Debug")
        self.debug_label.grid(column=0, row=6, sticky='e')
        debug = IntVar()
        debug.set(par.debug)
        self.debug_box = Entry(master, bd=2, textvariable=debug)
        self.debug_box.grid(column=1, row=6)
        debug.trace("w", update_debug)

        self.startdate_label = Label(master, text="Start date (yyyy-mm-dd)")
        self.startdate_label.grid(column=0, row=6, sticky='e')
        startdate = StringVar()
        startdate.set(par.startdate)
        self.startdate_box = Entry(master, bd=2, textvariable=startdate)
        self.startdate_box.grid(column=1, row=6)
        startdate.trace("w", update_startdate)

        self.enddate_label = Label(master, text="End date (yyyy-mm-dd)")
        self.enddate_label.grid(column=0, row=8, sticky='e')
        enddate = StringVar()
        enddate.set(par.enddate)
        self.enddate_box = Entry(master, bd=2, textvariable=enddate)
        self.enddate_box.grid(column=1, row=8)
        enddate.trace("w", update_enddate)

        self.archive_label = Label(master, text="Archive")
        self.archive_label.grid(column=0, row=9, sticky='e')
        archive = StringVar()
        archive.set(par.archive)
        self.archive_box = Entry(master, bd=2, textvariable=archive)
        self.archive_box.grid(column=1, row=9)
        archive.trace("w", update_archive)
        self.archive_lookup = Button(master, text="Lookup",
                                     command=lambda: self.get_archive(par))
        self.archive_lookup.grid(column=2, row=9)


        self.arc_type_label = Label(master, text="Archive type")
        self.arc_type_label.grid(column=0, row=10, sticky='e')
        arc_type = StringVar()
        arc_type.set(par.arc_type)
        self.arc_type_box = OptionMenu(master, arc_type,
                                       "seishub", "fdsn", "day_vols")
        self.arc_type_box.grid(column=1, row=10, sticky='w,e')
        arc_type.trace("w", update_arc_type)

        self.cores_label = Label(master, text="Number of cores")
        self.cores_label.grid(column=0, row=11, sticky='e')
        cores = IntVar()
        cores.set(par.cores)
        self.cores_box = Entry(master, bd=2, textvariable=cores)
        self.cores_box.grid(column=1, row=11)
        cores.trace("w", update_cores)

        self.plotvar_label = Label(master, text="Plotting on/off")
        self.plotvar_label.grid(column=0, row=12, sticky='e')
        plotvar = BooleanVar()
        plotvar.set(par.plotvar)
        self.plotvar_box = Checkbutton(master, text='Plot on', var=plotvar,
                                       onvalue=True, offvalue=False)
        self.plotvar_box.grid(column=1, row=12)
        plotvar.trace("w", update_plotvar)

        self.plotdir_label = Label(master, text="Plot directory")
        self.plotdir_label.grid(column=0, row=13, sticky='e')
        plotdir = StringVar()
        plotdir.set(par.plotdir)
        self.plotdir_box = Entry(master, bd=2, textvariable=plotdir)
        self.plotdir_box.grid(column=1, row=13)
        plotdir.trace("w", update_plotdir)
        self.plotdir_lookup = Button(master, text="Lookup",
                                     command=lambda: self.get_plotdir(par))
        self.plotdir_lookup.grid(column=2, row=13)

        self.plot_format_label = Label(master, text="Plot format")
        self.plot_format_label.grid(column=0, row=14, sticky='e')
        plot_format = StringVar()
        plot_format.set(par.plot_format)
        self.plot_format_box = OptionMenu(master, plot_format,
                                          "jpg", "eps", "pdf", "png")
        self.plot_format_box.grid(column=1, row=14, sticky='w,e')
        plot_format.trace("w", update_plot_format)

        self.tempdir_label = Label(master, text="Temporary directory")
        self.tempdir_label.grid(column=0, row=15, sticky='e')
        tempdir = StringVar()
        tempdir.set(par.tempdir)
        self.tempdir_box = Entry(master, bd=2, textvariable=tempdir)
        self.tempdir_box.grid(column=1, row=15)
        tempdir.trace("w", update_tempdir)
        self.tempdir_lookup = Button(master, text="Lookup",
                                     command=lambda: self.get_tempdir(par))
        self.tempdir_lookup.grid(column=2, row=15)

        self.threshold_label = Label(master, text="Threshold")
        self.threshold_label.grid(column=0, row=16, sticky='e')
        threshold = DoubleVar()
        threshold.set(par.threshold)
        self.threshold_box = Entry(master, bd=2, textvariable=threshold)
        self.threshold_box.grid(column=1, row=16)
        threshold.trace("w", update_threshold)

        self.threshold_type_label = Label(master, text="Threshold type")
        self.threshold_type_label.grid(column=0, row=17, sticky='e')
        threshold_type = StringVar()
        threshold_type.set(par.threshold_type)
        self.threshold_type_box = OptionMenu(master, threshold_type,
                                             "MAD", "absolute", "av_chan_corr")
        self.threshold_type_box.grid(column=1, row=17, sticky='w,e')
        threshold_type.trace("w", update_threshold_type)

        self.trigger_interval_label = Label(master,
                                            text="Minimum trigger " +
                                            "interval (s)")
        self.trigger_interval_label.grid(column=0, row=18, sticky='e')
        trigger_interval = DoubleVar()
        trigger_interval.set(par.trigger_interval)
        self.trigger_interval_box = Entry(master, bd=2,
                                          textvariable=trigger_interval)
        self.trigger_interval_box.grid(column=1, row=18)
        trigger_interval.trace("w", update_trigger_interval)

        # End of user editable section, now we have read/write buttons
        self.read_button = Button(master, text="Read parameters",
                                  command=lambda: self.read_par(master))
        self.read_button.grid(column=0, row=nrows-2, sticky='w,e')

        self.write_button = Button(master, text="Write parameters",
                                   command=lambda: self.write_par(par))
        self.write_button.grid(column=1, row=nrows-2, sticky='w,e')
示例#35
0
                       borderwidth=1)
frame_entry.grid(row=0, column=0)

frame_search = tk.Frame(master=window, relief=tk.RAISED, borderwidth=1)
frame_search.grid(row=0, column=1)

sub_frame_search = tk.Frame(master=frame_search, relief=tk.RAISED)

########### Entry Frame ###############
label_name = tk.Label(master=frame_entry, text="Name")
entry_name = tk.Entry(master=frame_entry)

label_barcode = tk.Label(master=frame_entry, text="Barcode")
sv_barcode = StringVar()
sv_barcode.trace("w",
                 lambda name, index, mode, sv_barcode=sv_barcode:
                 entry_update_search(sv_barcode))
entry_barcode = tk.Entry(master=frame_entry, textvariable=sv_barcode)

label_length = tk.Label(master=frame_entry, text='Raw Length')
entry_length = tk.Entry(master=frame_entry)

label_slength = tk.Label(master=frame_entry, text='Swage Length')
entry_slength = tk.Entry(master=frame_entry)

label_cleancode = tk.Label(master=frame_entry, text='Clean Code')
sv_cleanCode = StringVar(window)
cleanOptions = [
    "0: Not Cleaned", "1: Cleaning described in comment",
    "2: Wiped with Ethanol", "3: Only Vacuumed",
    "4: Vacuumed and Wiped with Ethanol", "5: Vacuumed with Nitrogen"
示例#36
0
class Main():
    def __init__(self, master):
        global profiles
        
        self.master = master
        master.title("Anime Tracker")

        topFrame = Frame(master,width=300,height=250)
        topFrame.grid()
        bottomFrame = Frame(master)
        bottomFrame.grid()

        if os.path.isfile("bg.png") == True:
            background_image=PhotoImage(file="bg.png")
            background_label=Label(master,image=background_image)
            background_label.photo=background_image
            background_label.place(x=0,y=0,relwidth=1,relheight=1)

        self.eps = StringVar(master)
        self.time = StringVar(master)

        self.var = StringVar(master)
        self.var.trace("w", self.crawl)
        self.var.set(profiles[0])
        o = OptionMenu(master, self.var, *profiles)
        o.grid(sticky='s',pady=5,column=0,row=0)

        self.l1 = Label(master, textvariable = self.eps)
        self.l1.grid(column=0,row=1,pady=2,sticky='s')
        
        self.l2 = Label(master, textvariable = self.time)
        self.l2.grid(column=0,row=2,pady=2,sticky='s')

        self.b = Button(master, text = "+1", command = self.add)
        self.b.grid(column=0,row=3,pady=10)

    def crawl(self, *args):
        global timeFormat
        
        for i in range(len(profiles)):
            if profiles[i] == self.var.get():
                f = open("Profiles/" + profiles[i] + ".txt","r")
        data = []
        for line in f:
            if len(line) > 0 and line[0] != '#':
                linesplit = line.split(":")
                data.append(linesplit[1][:len(linesplit[1])-1])
        f.close()
        complete = False
        if int(data[0])-int(data[2]) == 0:
            complete = True
        if complete == True:
            epsvar = "Complete!)"
            timevar = "Complete!)"
        else:
            epsvar = str(int(data[0])-int(data[2])) + " remaining)"
            if timeFormat == 0:
                timevar = str((int(data[0])*int(data[1]))-(int(data[1])*int(data[2]))) + " remaining)"
            elif timeFormat == 1:
                timevar = str(int(((int(data[0])*int(data[1]))-(int(data[1])*int(data[2])))/60)) + " hours " + str(((int(data[0])*int(data[1]))-(int(data[1])*int(data[2])))%60) + " minutes remaining)"
            elif timeFormat == 2:
                timevar = str(((int(data[0])*int(data[1]))-(int(data[1])*int(data[2])))/60) + " hours remaining)"
        self.eps.set(data[2] + '/' + data[0] + " episodes watched (" + epsvar)
        if timeFormat == 0:
            self.time.set(str(int(data[1])*int(data[2])) + "/" + str(int(data[0])*int(data[1])) + " minutes watched (" + timevar)
        elif timeFormat == 1:
            self.time.set(str(int(int(data[1])*int(data[2])/60)) + "h" + str(int(data[1])*int(data[2])%60) + "m/" + str(int(int(data[0])*int(data[1])/60)) + "h" + str(int(data[0])*int(data[1])%60) + "m (" + timevar)
        elif timeFormat == 2:
            self.time.set(str(int(data[1])*int(data[2])/60) + "h/" + str(int(data[0])*int(data[1])/60) + "h (" + timevar)

    def add(self):
        all_data = []

        with open("Profiles/" + self.var.get() + ".txt") as f:
            for line in f:
                name, value = line.split(":")
                all_data.append((name, int(value)))
        a=all_data[0]
        b=all_data[2]
        if a[1] == b[1]:
            messagebox.showinfo("Oops!", "This is already complete!")
        else:
            if os.path.exists('temp') == False:
                os.mkdir('temp')
            with tempfile.NamedTemporaryFile(mode='w', delete=False, dir="temp") as f:
                for name, value in all_data:
                    if name == "WATCHED":
                        print(f"{name}:{value + 1}", file=f)
                    else:
                        print(f"{name}:{value}", file=f)
            os.replace(f.name, "Profiles/" + self.var.get() + ".txt")
            self.crawl
            shutil.rmtree('temp')
            self.var.set(self.var.get())
示例#37
0
class EditInjectorGUI:
    """Class representing a window for editing a currently loaded install config in the GUI.

    Attributes
    ----------
    root : InstallSynAppsGUI
        The top TK instance that opened this window
    master : Toplevel
        The main container Tk object
    viewFrame
        Tk frame that contains all widgets
    dropdown : OptionMenu
        dropdown menu for selecting from injector files
    applyButton : Button
        button that runs the apply method
    editPanel : ScrolledText
        Panel for editing the loaded injector file.
    """
    def __init__(self, root, install_config):
        """Initializer for the EditInjectorGUI class
        """

        self.root = root
        self.master = Toplevel()
        self.master.title('Edit Injector Files')
        self.master.resizable(False, False)

        self.smallFont = tkFont.Font(family="Helvetica", size=10)
        self.largeFont = tkFont.Font(family="Helvetica", size=14)

        self.install_config = install_config

        self.viewFrame = Frame(self.master, relief=GROOVE, padx=10, pady=10)
        self.viewFrame.pack()

        self.injectorList = []
        for file in self.install_config.injector_files:
            self.injectorList.append(file.name)

        self.currentEditVar = StringVar()
        self.currentEditVar.set(self.injectorList[0])

        self.dropdown = OptionMenu(self.viewFrame, self.currentEditVar,
                                   self.injectorList[0], *self.injectorList)
        self.dropdown.config(width=20)
        self.dropdown.grid(row=0, column=0, columnspan=1, padx=5, pady=5)
        self.currentEditVar.trace('w', self.updateEditPanel)

        Button(self.viewFrame,
               text='New Injector',
               command=self.newInjector,
               width=10).grid(row=0, column=1, columnspan=1)
        Button(self.viewFrame,
               text='Apply Changes',
               command=self.applyChanges,
               width=10).grid(row=0, column=2, columnspan=1)
        Button(self.viewFrame,
               text='Apply and Exit',
               command=self.applyExit,
               width=10).grid(row=0, column=3, columnspan=1)
        Button(self.viewFrame,
               text='Reload',
               command=self.reloadPanel,
               width=10).grid(row=0, column=4, columnspan=1)

        self.editPanel = ScrolledText.ScrolledText(self.viewFrame,
                                                   height=37,
                                                   width=100)
        self.editPanel.grid(row=1, column=0, columnspan=5)

        self.updateEditPanel()

        self.master.mainloop()

    def newInjector(self):
        """Function for creating new injector files from within the GUI
        """

        new_name = simpledialog.askstring(
            'New Injector', 'Please enter a new injector filename')
        if new_name is not None:
            new_target = simpledialog.askstring(
                'New Target',
                'Please enter an injector target relative path using $(INSTALL), $(SUPPORT), $(AREA_DETECTOR), or $(MOTOR)'
            )
            if new_target is not None:
                if not new_target.startswith(
                        '$(INSTALL)') and not new_target.startswith(
                            '$(SUPPORT)') and not new_target.startswith(
                                '$(AREA_DETECTOR)'
                            ) and not new_target.startswith('$(MOTOR)'):
                    messagebox.showerror(
                        'ERROR', 'Please enter a valid relative path.')
                    return
                self.install_config.add_injector_file(new_name, '', new_target)
                self.root.updateAllRefs(self.install_config)
                del self.injectorList[:]
                for file in self.install_config.injector_files:
                    self.injectorList.append(file.name)

                self.currentEditVar.set(self.injectorList[0])
                self.dropdown = OptionMenu(self.viewFrame, self.currentEditVar,
                                           self.injectorList[0],
                                           *self.injectorList)
                self.dropdown.config(width=20)
                self.dropdown.grid(row=0,
                                   column=0,
                                   columnspan=1,
                                   padx=5,
                                   pady=5)
                self.reloadPanel()

    def updateEditPanel(self, *args):
        """Wrapper that reloads the panel based on selection
        """

        self.reloadPanel()

    def reloadPanel(self):
        """Reloads Panel based on selection
        """

        target_file = self.currentEditVar.get()
        contents = ''
        link = ''
        for file in self.install_config.injector_files:
            if file.name == target_file:
                contents = file.contents
                link = file.target
        self.editPanel.delete('1.0', END)
        self.editPanel.insert(INSERT, '#\n')
        self.editPanel.insert(INSERT,
                              '# The below contents will be injected into:\n')
        self.editPanel.insert(INSERT, '# {}\n'.format(link))
        self.editPanel.insert(INSERT, '#\n\n')
        self.editPanel.insert(INSERT, contents)

    def applyChanges(self):
        """Method that reads the edit panel, and sets the injector contents to whatever the user wrote.
        
        Note that there are no checks to see if the injection will be valid.
        """

        temp = self.editPanel.get('1.0', END).splitlines()
        new_contents = ''
        for line in temp:
            if not line.startswith('#'):
                new_contents = new_contents + line + '\n'
        target = self.currentEditVar.get()
        for file in self.install_config.injector_files:
            if file.name == target:
                file.contents = new_contents
        self.root.writeToLog('Applied updated injector file contents.\n')
        self.root.unsaved_changes = True
        self.root.updateAllRefs(self.install_config)

    def applyExit(self):
        """Applies changes and exits window
        """

        self.applyChanges()
        self.master.destroy()
示例#38
0
class OptionsFrame(LabelFrame):
    ''' This class creates Checkbuttons and Radiobuttons for displaying
        and modifying some of the parameters.

        Attributes:
            params (Parameters): object with all parameters. Some of the
                parameter values are modified in this class.
            current_categories (list of str): list of categories.
            input_categories_frame (CategoriesCheckBox): frame with input
                categories. It is needed in this class to read what
                categories are input.
            output_categories_frame (CategoriesCheckBox): frame with
                output categories. It is needed in this class to read what
                categories are output.
            categorical_box (Combobox): Combobox for choosing categorical
                category.
            combobox_text_var (StringVar): text variable of categorical_box.
            options (dict of str to IntVar): dictionary that stores IntVars
                of Radiobuttons and Checkbuttons.

                Example:
                    >>> options = {"RETURN_TO_SCALE": IntVar(),
                    "ORIENTATION": IntVar()}

            multi_tol_strvar (StringVar): StringVar object that stores
                tolerance of multiplier model.
            max_slack_box (Checkbutton): Checkbutton for the option "Two phase".

        Args:
            parent (Tk object): parent of this widget.
            params (Parameters): object with all parameters. Some of
                the parameter values are modified in this class.
            current_categories (list of str): list of categories.
            input_categories_frame (CategoriesCheckBox): frame with input
                categories. It is needed in this class to read what
                categories are input.
            output_categories_frame (CategoriesCheckBox): frame with output
                categories. It is needed in this class to read what
                categories are output.
            name (str, optional): name of the LabelFrame that this class
                represents, defaults to Options.
    '''
    def __init__(self, parent, params, current_categories,
                 input_categories_frame,
                 output_categories_frame, name='Options', *args, **kw):
        super().__init__(parent, text=name, *args, **kw)
        self.params = params
        self.current_categories = current_categories
        self.input_categories_frame = input_categories_frame
        self.output_categories_frame = output_categories_frame
        self.categorical_box = None
        self.combobox_text_var = StringVar()
        self.combobox_text_var.trace('w', self.on_categorical_box_change)
        self.options = dict()
        self.multi_tol_strvar = StringVar()
        self.multi_tol_strvar.trace('w', self.on_multi_tol_change)
        self.max_slack_box = None
        self.create_widgets()

    def create_widgets(self):
        ''' Creates all widgets.
        '''
        rts_lbl = Label(self, text='Return to scale:')
        rts_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE,
                     sticky=W)
        self._create_frame_with_radio_btns(self, 'RETURN_TO_SCALE',
                                           ['VRS', 'CRS'],
                                           row_index=1, column_index=0)

        orientation_lbl = Label(self, text='Orientation:')
        orientation_lbl.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE,
                             pady=YPAD_VALUE)
        self._create_frame_with_radio_btns(self, 'ORIENTATION',
                                           ['Input', 'Output'],
                                           row_index=1, column_index=1)

        model_lbl = Label(self, text='Model:')
        model_lbl.grid(row=0, column=2, padx=XPAD_VALUE, pady=YPAD_VALUE,
                       sticky=W)
        self._create_frame_with_radio_btns(self, 'DEA_FORM',
                                           ['Envelopment', 'Multiplier'],
                                           row_index=1, column_index=2,
                                           add_both=False)

        other_lbl = Label(self, text='Others:')
        other_lbl.grid(row=0, column=3, sticky=W, padx=XPAD_VALUE)

        max_slacks = IntVar()
        self.options['MAXIMIZE_SLACKS'] = max_slacks
        frame_other_options = Frame(self)
        self.max_slack_box = max_slacks_check_btn = Checkbutton(
            frame_other_options, text='Two phase', variable=max_slacks,
            command=(lambda: self.on_check_box_click(
                max_slacks, 'MAXIMIZE_SLACKS')))
        max_slacks_check_btn.grid(row=1, column=0, sticky=W)
        super_efficiency = IntVar()
        self.options['USE_SUPER_EFFICIENCY'] = super_efficiency
        super_efficiency_check_btn = Checkbutton(frame_other_options,
                                                 text='Super efficiency',
                                                 variable=super_efficiency,
                                                 command=(
                                                 lambda: self.on_check_box_click(
                                                 super_efficiency,
                                                 'USE_SUPER_EFFICIENCY')))
        super_efficiency_check_btn.grid(row=2, column=0, sticky=W)
        peel_the_onion = IntVar()
        self.options['PEEL_THE_ONION'] = peel_the_onion
        peel_the_onion_check_btn = Checkbutton(
            frame_other_options, text='Peel the onion', variable=peel_the_onion,
            command=(lambda: self.on_check_box_click(peel_the_onion,
                     'PEEL_THE_ONION')))
        peel_the_onion_check_btn.grid(row=3, column=0, sticky=W)
        frame_other_options.grid(row=1, column=3, padx=XPAD_VALUE,
                                 pady=YPAD_VALUE, sticky=W)

        frame_for_toleramce = Frame(self)
        tolerance_lbl = Label(frame_for_toleramce,
                              text='Multiplier model tolerance:')
        tolerance_lbl.grid(row=0, column=0, padx=XPAD_VALUE, pady=YPAD_VALUE,
                           sticky=W)
        tolerance_ent = Entry(frame_for_toleramce, width=5,
                              textvariable=self.multi_tol_strvar)
        tolerance_ent.insert(END, 0)
        tolerance_ent.grid(row=0, column=1, sticky=W, padx=XPAD_VALUE)
        categorical_lbl = Label(frame_for_toleramce, text='Categorical:')
        categorical_lbl.grid(row=1, column=0, padx=XPAD_VALUE,
                             pady=YPAD_VALUE, sticky=W)
        self.categorical_box = categorical_box = Combobox(
            frame_for_toleramce, textvariable=self.combobox_text_var,
            exportselection=0, state="readonly",
            width=20, values=(''),
            postcommand=self.change_categorical_box)
        categorical_box.grid(row=1, column=1, padx=XPAD_VALUE,
                             pady=YPAD_VALUE, sticky=W)
        frame_for_toleramce.grid(row=5, column=0, sticky=W, padx=XPAD_VALUE,
                                 pady=YPAD_VALUE, columnspan=4)

    def _create_frame_with_radio_btns(self, parent, name, text, row_index,
                                      column_index, add_both=True):
        ''' Creates frame with one set of Radiobuttons.

            Args:
                parent (Tk object): parent of the frame.
                name (str): name of the parameter that will a key in options
                    dictionary.
                text (list of str): list with two parameter values that should
                    be displayed next to the first two Radiobuttons.
                row_index (int): index of the row where the frame should
                    be placed using grid method.
                column_index (int): index of the column where the frame
                    should be placed using grid method.
                add_both (bool, optional): True if the third Radiobutton
                    with text "both" must be displayed, False otherwise,
                    defaults to True.
        '''
        assert len(text) == 2
        v = IntVar()
        self.options[name] = v
        self.options[name].trace(
            'w', (lambda *args: self.radio_btn_change(name)))
        frame_with_radio_btns = Frame(parent)
        first_option = Radiobutton(frame_with_radio_btns,
                                   text=text[0], variable=v, value=1)
        first_option.grid(row=0, column=0, sticky=W+N, padx=2)
        v.set(1)
        second_option = Radiobutton(frame_with_radio_btns,
                                    text=text[1], variable=v, value=2)
        second_option.grid(row=1, column=0, sticky=W+N, padx=2)
        if add_both:
            both = Radiobutton(frame_with_radio_btns, text='Both',
                               variable=v, value=3)
            both.grid(row=3, column=0, sticky=W+N, padx=2)
        frame_with_radio_btns.grid(row=row_index, column=column_index,
                                   padx=1, pady=5, sticky=W+N)

    def radio_btn_change(self, name, *args):
        ''' Actions that happen when user clicks on a Radiobutton.
            Changes the corresponding parameter values and options.

            Args:
                name (str): name of the parameter that is a key in
                    options dictionary.
                *args: are provided by IntVar trace method and are
                    ignored in this method.
        '''
        count = self.options[name].get()
        self.params.update_parameter(name, COUNT_TO_NAME_RADIO_BTN[name, count])
        dea_form = COUNT_TO_NAME_RADIO_BTN[name, count]
        if self.max_slack_box:  # on creation it is None
            if dea_form == 'multi':
                # disable max slacks
                self.max_slack_box.config(state=DISABLED)
                self.params.update_parameter('MAXIMIZE_SLACKS', '')
            elif dea_form == 'env':
                self.max_slack_box.config(state=NORMAL)
                if self.options['MAXIMIZE_SLACKS'].get() == 1:
                    self.params.update_parameter('MAXIMIZE_SLACKS', 'yes')

    def change_categorical_box(self):
        ''' Updates categories that can be chosen as categorical category
            when the user clicks on the Combobox.
        '''
        values = [category for category in self.current_categories if
                  category and category not in
                  self.input_categories_frame.category_objects.keys() and
                  category not in
                  self.output_categories_frame.category_objects.keys()]
        values.append('')
        self.categorical_box.config(values=values)

    def on_categorical_box_change(self, *args):
        ''' Updates value of the CATEGORICAL_CATEGORY in parameters.
            This method is called when the user clicks on the Combobox and
            chooses one item from the drop-down list.

            Args:
                *args: are provided by the StringVar trace method and are
                    ignored in this method.
        '''
        categorical_var = self.combobox_text_var.get()
        self.params.update_parameter('CATEGORICAL_CATEGORY', categorical_var)

    def set_params_values(self):
        ''' Reads all parameter values from the parameter object (params)
            and sets all widgets
            and options to these read values. Might display warnings if
            invalid values are stored in parameter object.
        '''
        self.set_radio_btns()
        self.set_check_btns()
        self.change_categorical_box()
        self.set_categorical_box(self.params.get_parameter_value(
            'CATEGORICAL_CATEGORY'))
        self.set_multi_tol()

    def set_radio_btns(self):
        ''' Goes through all Radiobuttons and changes their values
            according to the values stored in parameter object.
            Might display warnings.
        '''
        self.set_one_radio_btn('RETURN_TO_SCALE', ['VRS', 'CRS', 'both'])
        self.set_one_radio_btn('ORIENTATION', ['input', 'output', 'both'])
        self.set_one_radio_btn('DEA_FORM', ['env', 'multi'])

    def set_one_radio_btn(self, param_name, valid_values):
        ''' Sets value of a given set of Radiobuttons according to its value
            stored in parameter object if this value is valid.
            Might display warnings.

            Args:
                param_name (str): name of parameter whose value must be changed.
                valid_values (list of str): list of valid values that this
                    parameter might take.
        '''
        param_value = self.params.get_parameter_value(param_name)
        for count, value in enumerate(valid_values):
            if param_value == value:
                self.options[param_name].set(count + 1)
                return
        self._show_warning(param_name)
        self.options[param_name].set(1)

    def _show_warning(self, param_name):
        ''' Displays a warning saying that a value of a given parameter
            is not valid.

            Args:
                param_name (str): name of the parameter.
        '''
        showwarning('Warning', 'Parameter <{0}> does not have valid values.'
                    ' It will be set to default'.
                    format(param_name))

    def set_check_btns(self):
        ''' Goes through all Checkbuttons and changes their values
            according to the values
            stored in parameter object. Might display warnings.
        '''
        self.set_one_check_btn('MAXIMIZE_SLACKS')
        self.set_one_check_btn('PEEL_THE_ONION')
        self.set_one_check_btn('USE_SUPER_EFFICIENCY')

    def set_one_check_btn(self, param_name):
        ''' Sets value of a given set of Checkbutton according to its value
            stored in parameter object if this value is valid. Might
            display warnings.

            Args:
                param_name (str): name of parameter whose value must be changed.
        '''
        param_value = self.params.get_parameter_value(param_name)
        if param_value:
            self.options[param_name].set(1)

    def set_categorical_box(self, categorical_param):
        ''' Sets the value of Combobox with categorical category according
            to a given value
            if this value is in the list of values of this Combobox.
            If the given value
            is not in the list of values, a warning is displayed.

            Args:
                categorical_param (str): value of the categorical category.
        '''
        if categorical_param in self.categorical_box.cget('values'):
            self.combobox_text_var.set(categorical_param)
        else:
            self._show_warning_combobox(categorical_param)

    def _show_warning_combobox(self, categorical_param):
        ''' Displays a warning saying that a value of a given parameter is
            not a valid categorical category.

            Args:
                categorical_param (str): name of the categorical category.
        '''
        showwarning('Warning', 'Category: <{0}> cannot be chosen as a '
                    'categorical variable'.
                    format(categorical_param))

    def set_multi_tol(self):
        ''' Sets the value of Entry with multiplier model tolerance
            according to a given value
            if this value is valid (non-negative float). If the given value
            is invalid, a warning is displayed.
        '''
        tol_str = self.params.get_parameter_value('MULTIPLIER_MODEL_TOLERANCE')
        try:
            tol = float(tol_str)
            if (tol < 0):
                self._show_multi_tol_warning(tol_str)
                self.multi_tol_strvar.set('0')
            else:
                self.multi_tol_strvar.set(tol_str)
        except ValueError:
            self._show_multi_tol_warning(tol_str)
            self.multi_tol_strvar.set('0')

    def _show_multi_tol_warning(self, tol_str):
        ''' Displays a warning saying that a value of a multiplier model
            tolerance is invalid.

            Args:
                tol_str (str): value of the multiplier model tolerance.
        '''
        showwarning('Warning', 'Value: <{0}> is not valid as a multiplier'
                    ' model tolerance'.
                    format(tol_str))

    def on_multi_tol_change(self, *args):
        ''' Updates parameter MULTIPLIER_MODEL_TOLERANCE in the parameter
            object when the user
            modifies the content of the Entry widget that stores
            multiplier model tolerance.

            Args:
                *args: are provided by the StringVar trace method and are
                    ignored in this method.
        '''
        # this parameter will be validated before run
        tol_str = self.multi_tol_strvar.get()
        self.params.update_parameter('MULTIPLIER_MODEL_TOLERANCE', tol_str)

    def on_check_box_click(self, var, name):
        ''' Updates parameter specified by the Checkbutton in the parameter
            object when the user clicks on the Checkbutton.

            Args:
                var (IntVar): IntVar of the Checkbutton.
                name (str): name of the parameter that is the key in options
                    dictionary.
        '''
        if var.get() == 1:
            self.params.update_parameter(name, 'yes')
        else:
            self.params.update_parameter(name, '')
示例#39
0
    def __init__(self):
        Cursante.__init__(self)

        Form.__init__(self)

        self.id_register = None

        self.fieldsFrame = Frame(self.root, relief="groove", padding=(15, 15))
        self.fieldsFrame.grid(row=0, column=0, padx=10, pady=10)

        lbl_dni = Label(self.fieldsFrame, text="DNI: ", width=10)
        lbl_dni.grid(row=1, column=0, columnspan=10)

        dni = StringVar()
        e_dni = Entry(self.fieldsFrame, textvariable=dni, width=40)
        e_dni.grid(row=2, column=0, columnspan=40, pady=(0, 15))

        lbl_name = Label(self.fieldsFrame, text="Nombre: ", width=10)
        lbl_name.grid(row=3, column=0, columnspan=10)

        name = StringVar()
        e_name = Entry(self.fieldsFrame, textvariable=name, width=40)
        e_name.grid(row=4, column=0, columnspan=40, pady=(0, 15))

        lbl_surname = Label(self.fieldsFrame, text="Apellido: ", width=10)
        lbl_surname.grid(row=5, column=0, columnspan=10)

        surname = StringVar()
        e_surname = Entry(self.fieldsFrame, textvariable=surname, width=40)
        e_surname.grid(row=6, column=0, columnspan=40, pady=(0, 15))

        lbl_email = Label(self.fieldsFrame, text="Email: ", width=10)
        lbl_email.grid(row=7, column=0, columnspan=10)

        email = StringVar()
        e_email = Entry(self.fieldsFrame, textvariable=email, width=40)
        e_email.grid(row=8, column=0, columnspan=40, pady=(0, 15))

        lbl_phone = Label(self.fieldsFrame, text="Teléfono: ", width=10)
        lbl_phone.grid(row=9, column=0, columnspan=10)

        phone = StringVar()
        e_phone = Entry(self.fieldsFrame, textvariable=phone, width=40)
        e_phone.grid(row=10, column=0, columnspan=40, pady=(0, 15))

        lbl_institute = Label(self.fieldsFrame, text="Institución: ", width=10)
        lbl_institute.grid(row=11, column=0, columnspan=10)

        institute = StringVar()
        e_institute = Combobox(self.fieldsFrame,
                               textvariable=institute,
                               width=37,
                               values=("UNTDF", "UTN", "OTRO"),
                               state="readonly")
        e_institute.current(0)
        e_institute.grid(row=12, column=0, columnspan=40, pady=(0, 15))

        super().set_fields({
            "dni": dni,
            "nombre": name,
            "apellido": surname,
            "email": email,
            "telefono": phone,
            "institucion": institute
        })

        dni.trace("w", lambda *args: self.validate_dni(dni, *args))
        name.trace("w", lambda *args: self.validate_str(name, *args))
        surname.trace("w", lambda *args: self.validate_str(surname, *args))
        phone.trace("w", lambda *args: self.validate_phone(phone, *args))
示例#40
0
文件: gui.py 项目: Sidnoea/pokeBridge
def overwriteWindow(root):
    '''Creates the window for deciding to overwrite or not.'''

    def toggle(*args):    
        setState(choice.get(), 'disabled', [gen2Label, gen3Label,
                                            gen2Button, gen3Button,
                                            gen2Entry, gen3Entry])
        setState(not choice.get(), 'disabled', [warningLabel])

        if not choice.get() and (gen2Text.get() == '' or gen3Text.get() == ''):
            navFrame.disable('next', True)
        else:
            navFrame.disable('next', False)

    def gen2Dialog():
        askSave = filedialog.asksaveasfilename
        file = askSave(title='Gen II Save File', initialdir=root.dir,
                       filetypes=[('GB Save', '.sav'), ('All Files', '.*')],
                       defaultextension='.sav')
        if file != '':
            gen2Text.set(file)
            gen2Entry.after_idle(gen2Entry.xview_moveto, 1)
            root.dir = getDir(file)

    def gen3Dialog():
        askSave = filedialog.asksaveasfilename
        file = askSave(title='Gen III Save File', initialdir=root.dir,
                       filetypes=[('GBA Save', '.sav'), ('All Files', '.*')],
                       defaultextension='.sav')
        if file != '':
            gen3Text.set(file)
            gen3Entry.after_idle(gen3Entry.xview_moveto, 1)
            root.dir = getDir(file)

    def nextPage():
        global newGen2, newGen3, oldGen2, oldGen3

        if choice.get():
            newGen2 = oldGen2
            newGen3 = oldGen3
        else:
            newGen2 = gen2Entry.get()
            newGen3 = gen3Entry.get()

        root.nextPage()

    baseFrame = ttk.Frame(root)
    baseFrame.rowconfigure(0, weight=1)
    baseFrame.columnconfigure(0, weight=1)
    
    
    mainFrame = ttk.Frame(baseFrame, padding=MAIN_PAD)
    mainFrame.grid(row=0, column=0, sticky='ns')
    mainFrame.rowconfigure(0, weight=2)
    mainFrame.rowconfigure(3, weight=1)

    instrText = 'Select whether to overwrite the original save files, or to create new save files.'
    instrLabel = ttk.Label(mainFrame, text=instrText)
    instrLabel.grid(row=0, column=0)


    choiceFrame = ttk.Frame(mainFrame)
    choiceFrame.grid(row=1, column=0)

    choice = BooleanVar(value=True)
    choice1Radio = ttk.Radiobutton(choiceFrame, text='Overwrite',
                                   variable=choice, command=toggle,
                                   value=True)
    choice1Radio.grid(row=0, column=0, pady=5, sticky='w')

    warningText = 'WARNING! Once new data is created, this program can not recover old save data.'
    warningLabel = ttk.Label(choiceFrame, text=warningText, wraplength=300)
    warningLabel.grid(row=1, column=0, pady=5)
    
    choice2Radio = ttk.Radiobutton(choiceFrame, text='Do not overwrite',
                                   variable=choice, command=toggle,
                                   value=False)
    choice2Radio.grid(row=2, column=0, pady=5, sticky='w')


    pickerFrame = ttk.Frame(mainFrame)
    pickerFrame.grid(row=2, column=0)

    gen2Label = ttk.Label(pickerFrame, text='New Gen II file:')
    gen2Label.grid(row=0, column=0, columnspan=2)
    
    gen2Button = ttk.Button(pickerFrame, text='To...', command=gen2Dialog)
    gen2Button.grid(row=1, column=0, sticky='e', padx=5, pady=5)

    gen2Text = StringVar(pickerFrame)
    gen2Text.trace('w', toggle)
    gen2Entry = ttk.Entry(pickerFrame, textvariable=gen2Text, state='readonly')
    gen2Entry.grid(row=1, column=1, sticky='w', padx=5, pady=5)

    gen3Label = ttk.Label(pickerFrame, text='New Gen III file:')
    gen3Label.grid(row=2, column=0, columnspan=2)
    
    gen3Button = ttk.Button(pickerFrame, text='To...', command=gen3Dialog)
    gen3Button.grid(row=3, column=0, sticky='e', padx=5, pady=5)

    gen3Text = StringVar(pickerFrame)
    gen3Text.trace('w', toggle)
    gen3Entry = ttk.Entry(pickerFrame, textvariable=gen3Text, state='readonly')
    gen3Entry.grid(row=3, column=1, sticky='w', padx=5, pady=5)
    #todo: make sure user doesn't put the same file for both entries


    fillerFrame = ttk.Frame(mainFrame)
    fillerFrame.grid(row=3, column=0, sticky='ns')


    navFrame = Nav(baseFrame, root.prevPage, nextPage)
    navFrame.grid(row=1, column=0, sticky='we')

    if debug:
        gen2Text.set('C:/Users/Sidnoea/Documents/GitHub/pokeBridge/New Gen 2.sav')
        gen3Text.set('C:/Users/Sidnoea/Documents/GitHub/pokeBridge/New Gen 3.sav')
        choice.set(False)

    toggle()

    return (baseFrame, 'Overwrite?', {'sticky':'nsew'})
示例#41
0
#iconlabel
imgWeb = PhotoImage(file="img/web.png")
imgAvatar = PhotoImage(file="img/avatar.png")
imgSend = PhotoImage(file="img/document-send.png")
imgAtt = PhotoImage(file="img/attachment.png")
imageLabel = Label(frame, image=imgWeb, bg="cyan4")
imageLabel.place(x=16, y=60)

#userid label
emailLabel = Label(frame, text="Email  \t\t\t\t", bg="SkyBlue3", font=('times', 11))
emailLabel.pack(padx=0, pady=0, ipadx=36, ipady=0, fill=BOTH)

#userid entry
valid = StringVar()
valid.trace('w', met_valid)
emailId = Entry(frame, font=('times', 12), bg="white", fg="black", textvariable=valid)
emailId.image = PhotoImage(file="img/sAvatar.png")
emailId.image2 = PhotoImage(file="img/pass.png")
passLabel = Button(frame, image=emailId.image, bg="white", bd=0, command=validateId)
passLabel.place(x=266, y=204)
passLabel.bind("<Return>", validateId)
emailId.pack(padx=10, ipadx=34, ipady=4, pady=2)
emailId.focus()
emailId.bind("<Return>", validateId)

#warning label
warnLabel = Label(frame, text="", bg="SkyBlue3", fg='red', font=('times', 11))
warnLabel.pack(padx=0, pady=0, ipadx=36, ipady=0, fill=BOTH)

# login button
示例#42
0
class ConfigurationWindow(Frame):
    """
    Klasa GUI konfiguratora roweru

    w metodzie 'createBike' jest tworzony obiekt roweru
    z wykorzystaniem dekoratorów
    """
    def __init__(self, parent, frames, forks, wheelsets, groups, components):
        """
        inicjalizacja obiektu okna - nieistotne dla idei zdania
        """
        super(ConfigurationWindow, self).__init__(parent)
        self._bike = None
        self.parent = parent
        self.frames = frames
        self.forks = forks
        self.wheelsets = wheelsets
        self.groups = groups
        self.components = components
        self.parent.title("Bicycle configurator")
        self._bike_price = StringVar(self.parent)
        self._bike_weight = StringVar(self.parent)
        self._bike_travel = StringVar(self.parent)
        self.price_label = Label(self.parent, textvariable=self._bike_price)
        self.weight_label = Label(self.parent, textvariable=self._bike_weight)
        self.travel_label = Label(self.parent, textvariable=self._bike_travel)

        self.createInterface()
        self.createBike()

        self.price_label.pack()
        self.weight_label.pack()
        self.travel_label.pack()
        
        self.pack(fill=BOTH, expand=1)
        
    def createInterface(self):
        """
        Tworzenie interfejsu - nieistotne dla idei zadania
        """
        self.frame_choice = StringVar(self.parent)
        self.frame_choice.set(tuple(self.frames.keys())[0])
        self.frame_choice.trace("w", self.createBike)
        self.frame_options = OptionMenu(self.parent,self.frame_choice,
                                        *self.frames.keys())
        Label(self.parent,text="Rama:").pack()
        self.frame_options.pack(fill=BOTH, expand=1)

        self.fork_choice = StringVar(self.parent)
        self.fork_choice.set(tuple(self.forks.keys())[0])
        self.fork_choice.trace("w", self.createBike)
        self.fork_options = OptionMenu(self.parent,self.fork_choice,
                                        *self.forks.keys())
        Label(self.parent,text="Widelec:").pack()
        self.fork_options.pack(fill=BOTH, expand=1)

        self.wheelset_choice = StringVar(self.parent)
        self.wheelset_choice.set(tuple(self.wheelsets.keys())[0])
        self.wheelset_choice.trace("w", self.createBike)
        self.wheelset_options = OptionMenu(self.parent,self.wheelset_choice,
                                        *self.wheelsets.keys())
        Label(self.parent,text="Koła:").pack()
        self.wheelset_options.pack(fill=BOTH, expand=1)

        self.group_choice = StringVar(self.parent)
        self.group_choice.set(tuple(self.groups.keys())[0])
        self.group_choice.trace("w", self.createBike)
        self.group_options = OptionMenu(self.parent,self.group_choice,
                                        *self.groups.keys())
        Label(self.parent,text="Grupa osprzętu:").pack()
        self.group_options.pack(fill=BOTH, expand=1)

        self.components_choice = StringVar(self.parent)
        self.components_choice.set(tuple(self.components.keys())[0])
        self.components_choice.trace("w", self.createBike)
        self.components_options = OptionMenu(self.parent,self.components_choice,
                                        *self.components.keys())
        Label(self.parent,text="Komponenty:").pack()
        self.components_options.pack(fill=BOTH, expand=1)

    def createBike(self, *args):
        """
        Metoda tworząca obiekt roweru na zasadanie dekorowania
        obiektu klasy 'Frame'
        """
        frame = self.frames[self.frame_choice.get()]
        
        fork = self.forks[self.fork_choice.get()]
        fork.decorated = frame
        
        wheelset = self.wheelsets[self.wheelset_choice.get()]
        wheelset.decorated = fork
        
        group = self.groups[self.group_choice.get()]
        group.decorated = wheelset
        
        components = self.components[self.components_choice.get()]
        components.decorated = group
        self._bike = components

        # przypisanie wartości odpowiednim elementom GUI       
        self._bike_price.set("cena: " + str(self._bike.price) + "zł")
        self._bike_weight.set("waga: " + str(self._bike.weight) + " gr")
        self._bike_travel.set("skok: " + str(self._bike.travel) + " mm")

        # uaktualnienie okna
        self.price_label.update_idletasks()
        self.weight_label.update_idletasks()
        # zmiana tytułu okna
        self.parent.wm_title(self._bike.name)
示例#43
0
文件: main.py 项目: kr1/roqba
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((host, port))
        self.grid()
        self.columnconfigure(0, minsize=100)
        self.columnconfigure(1, minsize=200)
        self.columnconfigure(2, minsize=200)
        self.columnconfigure(3, minsize=150)
        self.columnconfigure(4, minsize=150)
        self.columnconfigure(5, minsize=150)
        self.columnconfigure(6, minsize=150)
        self.create_widgets()
        self.settables = self.assemble_settables()
        self.gui_logger = logging.getLogger('gui')
        self.request_update()

    def create_widgets(self):
        self.create_monitor()
        self.create_check_buttons()
        self.create_ranges()
        self.create_scales()
        self.create_radio_buttons()
        self.create_voices()
        self.quitButton = Button(self, text='Quit', command=self.quit)
        self.quitButton.grid(columnspan=7, sticky=E + W)

    def assemble_settables(self):
        settables = self.winfo_children()
        for w in settables:
            settables += w.winfo_children()
        return [w for w in settables if w.__class__.__name__ in ['Scale', 'Checkbutton']]

    def create_radio_buttons(self):
        # Scale related
        entries = ['DIATONIC', 'HARMONIC', 'MELODIC', 'PENTATONIC', 'PENTA_MINOR',
                   'GREEK_CHROMATIC', 'GREEK_ENHARMONIC']
        self.scale = StringVar()
        self.scale.set('DIATONIC')
        self.rb_frame = Frame(self)
        for e in entries:
            rb = Radiobutton(self.rb_frame, value=e, text=e, anchor=W,
                             command=self.send_scale, variable=self.scale)
            rb.grid(row=len(self.rb_frame.winfo_children()), sticky=W)
        self.rb_frame.grid(column=1, row=len(self.grid_slaves(column=1)), rowspan=3)

    def create_monitor(self):
        self.monitor_frame = LabelFrame(self, text="Monitor and Transport")
        this_cycle = Scale(self.monitor_frame, label='cycle_pos', orient=HORIZONTAL,
                           from_=1, to=16, resolution=1)
        this_cycle.disable, this_cycle.enable = (None, None)
        this_cycle.ref = 'cycle_pos'
        this_cycle.grid(column=0, row=0, sticky=E + W)
        self.updateButton = Button(self.monitor_frame,
                                   text='Reload all Settings',
                                   command=self.request_update)
        self.updateButton.grid(row=1, sticky=E + W)
        self.ForceCaesuraButton = Button(self.monitor_frame,
                                         text='Force Caesura',
                                         command=self.force_caesura)
        self.ForceCaesuraButton.grid(row=2, sticky=E + W)
        self.saveBehaviourButton = Button(self.monitor_frame,
                                          text='Save current behaviour',
                                          command=self.request_saving_behaviour)
        self.saveBehaviourButton.grid(row=3, sticky=E + W)
        self.saveBehaviourNameEntry = Entry(self.monitor_frame)
        self.saveBehaviourNameEntry.grid(row=4, sticky=E + W)
        self.saveBehaviourNameEntry.bind('<KeyRelease>', self.request_saving_behaviour)
        self.selected_behaviour = StringVar()
        self.selected_behaviour.trace('w', self.new_behaviour_chosen)
        self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                              self.selected_behaviour, None,)
        self.savedBehavioursMenu.grid(row=5, sticky=E + W)
        self.monitor_frame.grid(column=0, row=10, sticky=E + W)

    def request_update(self):
        self.send({'sys': 'update'})

    def request_saving_behaviour(self, event=None):
        """callback for save behaviour button and textentry"""
        if event and event.widget == self.saveBehaviourNameEntry:
            if event.keysym == 'Return':
                name = self.saveBehaviourNameEntry.get()
                self.saveBehaviourNameEntry.delete(0, len(name))
            else:
                return
        else:  # button was pressed
            name = self.saveBehaviourNameEntry.get()
        if name:
            self.send({'sys': ['save_behaviour', name]})

    def force_caesura(self):
        self.send({'force_caesura': True})

    def create_voices(self):
        voice_ids = ['1', '2', '3', '4']
        SCALES = OrderedDict([
                  ('pan_pos', {'min': -1, 'max': 1, 'start': 0.5, 'res': 0.001}),
                  ('volume', {'min': 0, 'max': 1, 'start': 0.666, 'res': 0.001}),
                  ('slide_duration_msecs', {'min': 0, 'max': 2000, 'start': 60, 'res': 1}),
                  ('slide_duration_prop', {'min': 0, 'max': 2, 'start': 0.666, 'res': 0.001}),
                  ('binaural_diff', {'min': 0, 'max': 66, 'start': 0.2, 'res': 0.01})
                ])

        for vid in voice_ids:
            counter = 0
            for sca in SCALES:
                name = 'voice_' + vid + '_' + sca
                setattr(self, 'min_' + name, SCALES[sca]['min'])
                setattr(self, 'max_' + name, SCALES[sca]['max'])
                this_sca = Scale(self, label=sca, orient=HORIZONTAL,
                                 from_=getattr(self, 'min_' + name),
                                 to=getattr(self, 'max_' + name),
                                 resolution=SCALES[sca]['res'])
                this_sca.enable = ('enable' in list(SCALES[sca].keys()) and
                                   SCALES[sca]['enable'] or None)
                this_sca.disable = ('disable' in list(SCALES[sca].keys()) and
                                    SCALES[sca]['disable'] or None)
                this_sca.grid(column=int(2 + int(vid)), row=counter, sticky=E + W)
                this_sca.bind("<ButtonRelease>", self.scale_handler)
                this_sca.ref = name
                counter += 1
        CHECK_BUTTONS = OrderedDict(
                 [('mute', False),
                  ('automate_binaural_diffs', True),
                  ('automate_note_duration_prop', True),
                  ('use_proportional_slide_duration', {'val': True, 'label': 'proportional slide'}),
                  ('automate_pan', True),
                  ('automate_wavetables', True)])
        for vid in voice_ids:
            counter = 0
            cb_frame = LabelFrame(self, text="Voice {0} - Automation".format(vid))
            setattr(self, 'voice_' + vid + '_cb_frame', cb_frame)
            for cb in CHECK_BUTTONS:
                options = CHECK_BUTTONS[cb]
                name = 'voice_' + vid + '_' + cb
                if isinstance(options, dict) and 'label' in list(options.keys()):
                    label = options['label']
                else:
                    label = cb[9:] if cb[:9] == 'automate_' else cb
                setattr(self, name, IntVar(
                    value=type(options) == dict and options['val'] or options))
                self.this_cb = Checkbutton(cb_frame, text=label, variable=getattr(self, name))
                self.this_cb.bind('<Button-1>', self.check_boxes_handler)
                self.this_cb.disable = None
                self.this_cb.grid(sticky=W, column=0, row=counter)
                self.this_cb.ref = name
                counter += 1
            # add trigger wavetable-button
            trigWavetableButton = Button(cb_frame, text='Next Wavetable')
            trigWavetableButton.bind('<Button-1>', self.trigger_waveform_handler)
            trigWavetableButton.ref = 'voice_' + vid + "_trigger_wavetable"
            trigWavetableButton.grid(row=counter)
            cb_frame.grid(column=int(vid) + 2, row=5, sticky=E + W + N, rowspan=8)
        for vid in voice_ids:
            generation_types = ["random", "random_harmonic", "harmonic"]
            partial_pools = ["even", "odd", "all"]
            prefix = 'voice_' + vid + '_'
            types_name = prefix + 'wavetable_generation_type'
            pools_name = prefix + 'partial_pool'
            setattr(self, types_name, StringVar())
            getattr(self, types_name).set("random")
            setattr(self, pools_name, StringVar())
            getattr(self, pools_name).set("all")
            target_frame = getattr(self, 'voice_' + vid + '_cb_frame')
            gen_typ_frame = LabelFrame(target_frame, text="type")
            gen_typ_frame.grid(row=len(target_frame.winfo_children()), sticky=W)
            for gen_t in generation_types:
                gen_t_entry = Radiobutton(gen_typ_frame, value=gen_t, text=gen_t, anchor=W,
                                          variable=getattr(self, types_name))
                gen_t_entry.bind('<ButtonRelease-1>', self.wt_handler)
                gen_t_entry.ref = types_name
                gen_t_entry.grid(row=len(gen_typ_frame.winfo_children()), sticky=W)
            pp_frame = LabelFrame(target_frame, text="harmonics")
            for pp in partial_pools:
                pp_entry = Radiobutton(pp_frame, value=pp, text=pp, anchor=W,
                                       variable=getattr(self, pools_name))
                pp_entry.bind('<ButtonRelease-1>', self.wt_handler)
                pp_entry.ref = pools_name
                pp_entry.grid(row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials = Scale(pp_frame, label='number of harmonics', orient=HORIZONTAL,
                                      from_=1, to=24, resolution=1)
            this_num_partials.ref = prefix + 'num_partials'
            this_num_partials.grid(column=0, row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials.bind("<ButtonRelease>", self.scale_handler)
            pp_frame.grid(row=len(target_frame.winfo_children()), sticky=E + W)

    def wt_handler(self, event):
        print(event.widget.tk)
        ref = event.widget.ref
        self.send({ref: getattr(self, ref).get()})

    def create_check_buttons(self):
        self.cb_frame = LabelFrame(self, text="Global Settings")
        for cb in CHECK_BUTTONS:
            label = cb
            target_parent = self.cb_frame
            if isinstance(CHECK_BUTTONS[cb], dict) and 'sub_frame' in list(CHECK_BUTTONS[cb].keys()):
                target_parent = getattr(self, CHECK_BUTTONS[cb]['sub_frame'])
            setattr(self, cb, IntVar(value=type(CHECK_BUTTONS[cb]) == dict and
                                     CHECK_BUTTONS[cb]['val'] or
                                     CHECK_BUTTONS[cb]))
            self.this_cb = Checkbutton(target_parent, text=label, variable=getattr(self, cb))
            self.this_cb.bind('<Button-1>', self.check_boxes_handler)
            self.this_cb.disable = (type(CHECK_BUTTONS[cb]) == dict and
                                    'disable' in list(CHECK_BUTTONS[cb].keys()))
            self.this_cb.grid(sticky=W, column=0, row=len(target_parent.winfo_children()))
            self.this_cb.ref = cb
        for but in GLOBAL_BUTTONS:
            label = but
            ele = GLOBAL_BUTTONS[but]
            this_but = Button(self.cb_frame, text=but)
            this_but.bind('<ButtonRelease-1>', getattr(self, ele['handler']))
            this_but.ref = but
            this_but.grid(sticky=W, column=0, row=len(self.cb_frame.winfo_children()))
        self.cb_frame.grid(column=0, row=0, rowspan=10, sticky=N)

    def new_behaviour_chosen(self, a, b, c):
        self.send({'sys': ['change_behaviour', self.selected_behaviour.get()]})

    def set_value(self, name, val):
        '''sets a widget to the specified value

        various different widget types need custom setting functionality'''

        direct = ['scale', 'wavetable_generation_type', 'partial_pool']
        if [x for x in direct if match("(voice_\d_|)" + x, name)]:
            self.gui_logger.info("setting: '{0}' to '{1}' in GUI".format(name, val))
            getattr(self, name).set(val)
            return
        if name == 'saved_behaviours' and len(val):
            self.savedBehavioursMenu.destroy()
            self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                                  self.selected_behaviour, *sorted(val))
            self.savedBehavioursMenu.grid(row=5, sticky=E + W)
            return
        for w in self.settables:
            typ = w.__class__.__name__
            if w.ref == name:
                # print "setting '{0}' of type: '{1}' to: {2}".format(name, typ, val)
                if typ == 'Scale':
                    w.set(val)
                elif typ == "Checkbutton":
                    w.select() if val else w.deselect()

    def check_boxes_handler(self, event):
        '''handles checkbox events.

        shows and hides gui elements according to their enable/disable fields'''
        # print event.__dict__
        # print event.widget.__dict__
        ref = event.widget.ref
        val = not getattr(self, ref).get()  # because is read before the var is changed
        self.send({ref: val})
        # print ref, val
        # handle gui elements
        # enable/disable functionality temporarily(?) commented on:
        # Wed Aug 17 09:39:54 CEST 2011
#        if event.widget.disable:
#            for w in self.children.values():
#
#                # this try clause is for debugging, remove when stable
#                try:
#                    w.ref
#                    #print w.ref
#                except:
#                    pass
#                if (w.__class__.__name__ == 'Scale' and
#                    (w.disable or w.enable)):
#                    if w.disable == ref:
#                        if val:
#                            w.grid()
#                        else:
#                            w.grid_remove()
#                    elif w.enable == ref:
#                        if val:
#                            w.grid_remove()
#                        else:
#                            w.grid()
#                    #print w.disable, w.enable

    def create_scales(self):
        counter = 0
        for sca in SCALES:
            label = SCALES[sca]['label'] if 'label' in list(SCALES[sca].keys()) else sca
            setattr(self, 'min_' + sca, SCALES[sca]['min'])
            setattr(self, 'max_' + sca, SCALES[sca]['max'])
            self.this_scale = Scale(self, label=label, orient=HORIZONTAL,
                                    from_=getattr(self, 'min_' + sca),
                                    to=getattr(self, 'max_' + sca),
                                    resolution=SCALES[sca]['res'])
            self.this_scale.set(SCALES[sca]['start'])
            self.this_scale.enable = ('enable' in list(SCALES[sca].keys()) and
                                      SCALES[sca]['enable'] or None)
            self.this_scale.disable = ('disable' in list(SCALES[sca].keys()) and
                                       SCALES[sca]['disable'] or None)
            if 'pos' in list(SCALES[sca].keys()):
                pos = SCALES[sca]['pos']
                col = pos['c']
                row = pos['r']
            else:
                row = counter
                col = 1
                counter += 1
            self.this_scale.grid(column=col, row=row, sticky=E + W)
            self.this_scale.ref = sca
            self.this_scale.bind("<ButtonRelease>", self.scale_handler)

    def scale_handler(self, event):
        self.send({event.widget.ref: event.widget.get()})
        self.gui_logger.info("handling scale: {0}, with new value: {1}".format(
                  event.widget.ref, event.widget.get()))

    def trigger_waveform_handler(self, event):
        self.send({event.widget.ref: True})
        # print event.widget.ref, "- triggering wavetable"

    def send_scale(self):
        do = {'scale': self.scale.get()}
        self.send(do)

    def send(self, msg):
        self.gui_logger.info("sending: {0}".format(msg))
        self.send_sock.sendto(json.dumps(msg), (remote_host, send_port))

    def create_ranges(self):
        counter = 0
        for ran in RANGES:
            setattr(self, 'min_' + ran, RANGES[ran]['min'])
            setattr(self, 'max_' + ran, RANGES[ran]['max'])
            self.this_min_scale = Scale(self, label='min ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_max_scale = Scale(self, label='max ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_min_scale.set(RANGES[ran]['min_start'])
            self.this_max_scale.set(RANGES[ran]['max_start'])
            self.this_min_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_min_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_max_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_max_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_min_scale.grid(column=2, row=counter, sticky=E + W)
            self.this_max_scale.grid(column=2, row=counter + 1, sticky=E + W)
            self.this_min_scale.ref = 'min_' + ran
            self.this_max_scale.ref = 'max_' + ran
            self.this_min_scale.bind("<ButtonRelease>", self.scale_handler)
            self.this_max_scale.bind("<ButtonRelease>", self.scale_handler)
            counter += 2

    def socket_read_handler(self, file, mask):
        data_object = json.loads(file.recv(1024))
        do = list(data_object.items())[0]
        self.set_value(do[0], do[1])
示例#44
0
class Tk_Nosy(object):
    """This class is the tkinter GUI object"""

    # make a collection of python interpreters to choose from
    pythonInterpreterCollection = None # will be PyInterpsOnSys object

    # extra python interpreters can run nosetests concurrently to main window
    #  concurrent_versionL contains tuples = (PI, Popup)
    concurrent_versionL = [] # additional running python interpreters


    def __init__(self, master):
        self.dirname = os.path.abspath( os.curdir )

        self.initComplete = 0
        self.master = master
        self.x, self.y, self.w, self.h = -1,-1,-1,-1

        # bind master to <Configure> in order to handle any resizing, etc.
        # postpone self.master.bind("<Configure>", self.Master_Configure)
        self.master.bind('<Enter>', self.bindConfigure)

        self.menuBar = Menu(master, relief = "raised", bd=2)

        self.menuBar.add("command", label = "Change_Dir", command = self.menu_Directory_Change_Dir)

        disp_Choices = Menu(self.menuBar, tearoff=0)
        self.display_test_details = StringVar()
        self.display_test_details.set('N')
        disp_Choices.add_checkbutton(label='Display Test Details', variable=self.display_test_details, onvalue='Y', offvalue='N')

        self.display_watched_files = StringVar()
        self.display_watched_files.set('N')
        disp_Choices.add_checkbutton(label='Show Watched Files', variable=self.display_watched_files, onvalue='Y', offvalue='N')
        self.menuBar.add("cascade", label="Display", menu=disp_Choices)


        py_choices = Menu(self.menuBar, tearoff=0)
        py_choices.add("command", label = "Change Python Version",
                          command = self.changePythonVersion)
        py_choices.add("command", label = "Find New Python Interpreter",
                          command = self.findNewPythonInterpreter)
        py_choices.add("command", label = "Launch Another Python Interpreter",
                          command = self.launchAnotherPythonInterpreter)
        self.menuBar.add("cascade", label="Python", menu=py_choices)


        #top_Snippet = Menu(self.menuBar, tearoff=0)

        self.menuBar.add("command", label = "Run", command = self.menu_Run)

        self.display_test_details.trace("w", self.rerun_tests)
        self.display_watched_files.trace("w", self.rerun_tests)

        master.config(menu=self.menuBar)

        # make a Status Bar
        self.statusMessage = StringVar()
        self.statusMessage.set(self.dirname)
        self.statusbar = Label(self.master, textvariable=self.statusMessage,
                               bd=1, relief=SUNKEN)
        self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM)

        self.statusbar_bg = self.statusbar.cget('bg') # save bg for restore

        self.arial_12_bold_font = tkinter.font.Font(family="Arial", size=12,
                                                    weight=tkinter.font.BOLD)
        self.arial_12_font      = tkinter.font.Font(family="Arial", size=12)


        self.statusbar.config( font=self.arial_12_bold_font )

        frame = Frame(master)
        frame.pack(anchor=NE, fill=BOTH, side=TOP)

        self.Pass_Fail_Button = Button(frame,text="Pass/Fail Will Be Shown Here",
                                       image="", width="15", background="green",
                                       anchor=W, justify=LEFT, padx=2)
        self.Pass_Fail_Button.pack(anchor=NE, fill=X, side=TOP)
        self.Pass_Fail_Button.bind("<ButtonRelease-1>", self.Pass_Fail_Button_Click)

        self.master.title("tk_nosy")

        self.oscillator = 1 # animates character on title
        self.oscillator_B = 0 # used to return statusbar to statusbar_bg

        self.lbframe = Frame( frame )
        self.lbframe.pack(anchor=SE, side=LEFT, fill=BOTH, expand=1)

        scrollbar = Scrollbar(self.lbframe, orient=VERTICAL)
        self.Text_1 = Text(self.lbframe, width="80", height="24",
                           yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.Text_1.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.Text_1.pack(side=LEFT, fill=BOTH, expand=1)

        self.master.resizable(1,1) # Linux may not respect this

        self.numNosyCalls = 0
        self.need_to_pick_dir = 1

        print('sys.argv =',sys.argv)
        if len(sys.argv)>1:
            #  I don't care what the exception is, if there's a problem, bail
            # pylint: disable=W0702
            print( "Try Dir =",sys.argv[1] )
            try:
                dirname = os.path.abspath( sys.argv[1] )
                self.try_change_to_new_dir( dirname )
            except Exception:
                pass # let Alarm force dir selection
        else:
            try:
                if os.path.isdir(os.path.join( self.dirname, 'tests' )):
                    self.try_change_to_new_dir( self.dirname )
            except Exception:
                pass # let Alarm force dir selection


        print(LICENSE)

        self.defaultPyInterp = None # need to identify default python interpreter
        if Tk_Nosy.pythonInterpreterCollection == None:
            Tk_Nosy.pythonInterpreterCollection = PyInterpsOnSys()
            self.defaultPyInterp = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_py_path( sys.executable )
            #print( Tk_Nosy.pythonInterpreterCollection )

        self.Alarm()


    def try_change_to_new_dir(self, dirname):
        """A legal abspath will switch to dirname."""
        #  I don't care what the exception is, if there's a problem, bail
        # pylint: disable=W0702
        if dirname:
            try:
                dirname = os.path.abspath( dirname )
            except:
                return # let Alarm force dir selection
        else:
            return

        self.dirname = dirname
        print('Selected dirname    =',dirname)
        fileD.clear()
        os.chdir( self.dirname )
        self.reset_statusbar_bg()
        self.need_to_pick_dir = 0

        #with open(NOSY_USER_DATA_FILE, 'w') as text_file:
        #    text_file.write( self.dirname )

        self.numNosyCalls = 0


    def reset_statusbar_bg(self):
        """Return status bar to default state"""
        self.statusbar.config(bg=self.statusbar_bg)
        self.statusMessage.set(self.dirname)

    def set_statusbar_bg(self, c):
        """Set status bar to show new color and message"""
        self.statusbar.config(bg=c)
        self.oscillator_B = 1 # will return to initial color after a few cycles

    def menu_Directory_Change_Dir(self):
        """Menu selection to set directory in which to run nosetests"""
        dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".")
        if dirname:
            self.try_change_to_new_dir( dirname )
        # >>>>>>insert any user code below this comment for section "menu_Directory_Change_Dir"
        # replace, delete, or comment-out the following
        print("called menu_Directory_Change_Dir")


    def menu_Run(self):
        """User initiates a nosetests run, not file change detection."""
        print("called menu_Run")
        self.callNosy()
    def rerun_tests(self,*args):
        self.menu_Run()


    def callNosy(self):


        """Run nosetests and display results"""
        self.numNosyCalls += 1

        runL = [(self.defaultPyInterp, self)]
        for PI,Popup in Tk_Nosy.concurrent_versionL:
            runL.append( (PI, Popup) )

        for PI, tkwindow in runL:
            tkwindow.Text_1.delete(1.0, END)

            # turn indicator button gray while running the tests
            tkwindow.Pass_Fail_Button.config(background="#999999",
                                             text='TESTING...',
                                             font=self.arial_12_bold_font)
        self.master.update()
        self.master.update_idletasks()

        for PI, tkwindow in runL:
            self.run_tkwin_nosetests( PI, tkwindow)

        self.master.winfo_toplevel().wm_geometry("")



    def run_tkwin_nosetests(self, PI, tkwindow):
        """Run nosetests for main python interpreter and any concurrent
             python interpreters.

           Update GUI to show results.
        """

        if PI.nose_version == None:
            # if nose was not installed last time we checked, check again
            PI.nose_version, err_msg = get_nose_version_info( PI.full_path )
            if PI.nose_version == None:
                print( "\a" )  # make beep
                s = 'Can not verify nose for:\nPython ' + PI.name()
                tkwindow.Pass_Fail_Button.config(background='orange',
                                                  text=s,
                                                  font=self.arial_12_bold_font)
                s = 'Please verify nose installed for:\n'+str(PI) +\
                    '\n\n' + err_msg+\
                    '\n\nFor install instructions see:\n'+\
                    'https://nose.readthedocs.org/en/latest/'
                tkwindow.Text_1.insert(END, s )
                ShowError(title='Can not verify nose', message=s)
                return

        # pylint: disable=W0201
        passedAllTests, numPassed, numFailed, numErrors, numSkipped, outputTextL = \
            run_nosetests(self.numNosyCalls, PI, display_test_details=self.display_test_details.get())

        max_len_s = 42
        num_lines = 1
        for s in outputTextL:
            tkwindow.Text_1.insert(END, s)
            sL = s.split('\n')
            for ss in sL:
                max_len_s = max(max_len_s, len(ss))
                num_lines += 1


        if self.numNosyCalls % 2:
            myFont = self.arial_12_bold_font
        else:
            myFont = self.arial_12_font

        if passedAllTests:
            s = 'PASSED'
            if numPassed > 1:
                s = 'PASSED ALL %i TESTS'%numPassed
            elif numPassed == 1:
                s = 'PASSED ONE TEST'


            bg="#00ff00"
            if numSkipped==1:
                s = 'passed with 1 SKIP'
                bg = "#00cc00"
            elif numSkipped > 1:
                s = 'passed with %i SKIPS'%numSkipped
                bg = "#00cc00"
            elif numPassed==0:
                s = 'No Tests Found'
                bg="#ff8000"
            tkwindow.Pass_Fail_Button.config(background=bg, text=s, font=myFont)

            #self.master.geometry('200x50')
        else:
            s = 'FAILED %i, ERRORS %i, SKIP %i, PASSED %i'%(numFailed,
                                                            numErrors, numSkipped, numPassed)
            tkwindow.Pass_Fail_Button.config(background="#ff0000", text=s, font=myFont)
            #self.master.geometry('516x385')


        # Show list of files being watched.
        #self.Text_1.insert(END, '_'*40+'\n')
        tkwindow.Text_1.insert(END, 'WATCHED *.py FILES'.center(40,'_') + '\n' )
        tkwindow.Text_1.insert(END, '%s%s..\n\n'%(self.dirname,os.path.sep) )
        num_lines += 3

        len_dirname = len( self.dirname )

        if self.display_watched_files.get()=='Y':
            keyL = list(fileD.keys())
            keyL.sort()
            lastdir = ''
            for key in keyL:
                dn = os.path.dirname( key )
                if dn != lastdir:
                    tkwindow.Text_1.insert(END, '..'+dn[len_dirname:] + '\n')
                    max_len_s = max(max_len_s, len(dn)+1)
                    lastdir = dn
                    num_lines += 1
                s = '    ' +os.path.basename( key )
                tkwindow.Text_1.insert(END, s + '\n')
                max_len_s = max(max_len_s, len(s)+1)
                num_lines += 1
        else:
            num_lines += 1
            tkwindow.Text_1.insert(END, '     %i files watched.\n'%len(fileD))

        tkwindow.Text_1.config(width=max_len_s)
        tkwindow.Text_1.config(height=min(40, num_lines))


    def bindConfigure(self, event):
        """Part of goofy main window setup in tkinter."""
        #  tkinter requires arguments, but I don't use them
        # pylint: disable=W0613
        if not self.initComplete:
            self.master.bind("<Configure>", self.Master_Configure)
            self.initComplete = 1

    def change_python_exe(self, full_path ):
        """Allow nosetests to be run under any available python version """
        PI = Tk_Nosy.pythonInterpreterCollection.add_interp( full_path )
        if PI:
            self.defaultPyInterp = PI


    def findNewPythonInterpreter(self):
        """Find a new python interpreter, one that is not already in
             the PyInterpsOnSys object (pythonInterpreterCollection).
        """
        if Tk_Nosy.pythonInterpreterCollection == None:
            print( 'pythonInterpreterCollection NOT yet initialized' )
            self.statusMessage.set('Interpreter Collection NOT initialized')
            self.set_statusbar_bg( '#FF9999' )
            return

        print('Open File')
        filetypes = [
            ('python executable','py*'),
            ('Any File','*.*')]
        pathopen = tkFileDialog.askopenfilename(parent=self.master,
                       title='Select Python Executable',
                       filetypes=filetypes,
                       initialdir=self.defaultPyInterp.full_path)

        if pathopen:
            self.change_python_exe( pathopen )
            self.menu_Run()

    def kill_popup_window(self, popup_name):
        """Close a popup window running another verions of python interpreter"""
        for itup, tup in enumerate(Tk_Nosy.concurrent_versionL):
            PI, Popup = tup
            s = '%s %s' % (PI.exe_name, PI.version_str)
            if popup_name == s:
                Tk_Nosy.concurrent_versionL.pop( itup )
                return True # removed popup from list
        return False # no popup found


    def launchAnotherPythonInterpreter(self):
        """Launch a pop-up window that concurrently runs another python version"""

        removeNameL=[self.defaultPyInterp.name()]
        for PI,Popup in Tk_Nosy.concurrent_versionL:
            removeNameL.append( PI.name() )

        piL = Tk_Nosy.pythonInterpreterCollection.get_PI_list( removeNameL=removeNameL )
        if len(piL)==0:
            print( 'All identified python interpreters in use.' )
        else:
            print( [pi.name() for pi in piL] )
            rbL = [PI.name() for PI in piL]
            dialog = Select_Py_Version(self.master, "Launch Another Python Version",
                                       dialogOptions={'rbL':rbL})
            if dialog.result:
                PI = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_name(
                                                    dialog.result['selection'])

                s = '%s %s' % (PI.exe_name, PI.version_str)
                Popup = SatelliteWindow(self, self.master, s)
                Tk_Nosy.concurrent_versionL.append( (PI, Popup) )
                self.menu_Run()

    def changePythonVersion(self):
        """Change to a different python version.
           If the PyInterpsOnSys object (pythonInterpreterCollection) has been
           initialized, select from its list.
           Otherwise find the python interpreter executable
           (ex. python.exe or python)
        """
        if (Tk_Nosy.pythonInterpreterCollection == None) or \
           (Tk_Nosy.pythonInterpreterCollection.num_terps() == 0):
            # If there is no list of available python interpreters, look for python file
            print('Open File')
            filetypes = [
                ('python executable','py*'),
                ('Any File','*.*')]
            pathopen = tkFileDialog.askopenfilename(parent=self.master,
                           title='Select Python Executable',
                           filetypes=filetypes,
                           initialdir=self.defaultPyInterp.full_path)

            if pathopen:
                self.change_python_exe( pathopen )
                self.menu_Run()
        else:
            rbL = [PI.name() for PI in Tk_Nosy.pythonInterpreterCollection.interpL]
            dialog = Select_Py_Version(self.master, "Select Python Version",
                                       dialogOptions={'rbL':rbL})
            if dialog.result:
                PI = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_name(
                                                   dialog.result['selection'] )
                pathopen = PI.full_path

                self.change_python_exe( pathopen )
                self.menu_Run()

    # return a string containing directory name
    def AskDirectory(self, title='Choose Directory', initialdir="."):
        """Run pop-up menu for user to select directory."""
    #    This is not an error
    # pylint: disable=E1101

        if sys.version_info < (3,):
            dirname = tkFileDialog.askdirectory(parent=self.master,
                                             initialdir=initialdir,title=title)
        else:
            dirname = tkFileDialog.askdirectory(parent=self.master,
                                             initialdir=initialdir,title=title)
        return dirname # <-- string


    def Master_Configure(self, event):
        """Part of tkinter main window initialization"""

        if event.widget != self.master:
            if self.w != -1:
                return
        x = int(self.master.winfo_x())
        y = int(self.master.winfo_y())
        w = int(self.master.winfo_width())
        h = int(self.master.winfo_height())
        if (self.x, self.y, self.w, self.h) == (-1,-1,-1,-1):
            self.x, self.y, self.w, self.h = x,y,w,h


        if self.w!=w or self.h!=h:
            #print "Master reconfigured... make resize adjustments"
            self.w=w
            self.h=h

    # pylint: disable=W0613
    def Pass_Fail_Button_Click(self, event):
        """Routine for user clicking Pass/Fail Button"""
        print('Arranging Windows by User Request')
        num_popups = len(Tk_Nosy.concurrent_versionL)
        DX = 50
        DY = 70
        x = 10
        y = 10 + num_popups * DY
        self.master.geometry( '+%i+%i'%(x,y))

        for PI,Popup in Tk_Nosy.concurrent_versionL:
            x += DX
            y -= DY
            Popup.geometry( '+%i+%i'%(x,y))



    # alarm function is called after specified number of milliseconds
    def SetAlarm(self, milliseconds=1000):
        """Reinitialize tkinter alarm mechanism as well as update seconds
           counter in main window title bar.
        """
        self.master.after( milliseconds, self.Alarm )

        self.oscillator += 1
        if self.oscillator > 5:
            self.oscillator = 0

        if self.oscillator_B>0:
            self.oscillator_B += 1
        if self.oscillator_B>5:
            self.oscillator_B = 0
            self.reset_statusbar_bg()

        pad = '|'*self.oscillator

        s = '%s (v%s)'%(self.defaultPyInterp.exe_name, self.defaultPyInterp.version_str)

        self.master.title('%i) %s '%(self.numNosyCalls , s + pad ))

        for PI,Popup in Tk_Nosy.concurrent_versionL:
            s = '%s (v%s)'%(PI.exe_name, PI.version_str)
            Popup.title( '%i) %s '%(self.numNosyCalls , s + pad ) )



    def Alarm(self):
        """Look for changed files every second, then reset alarm"""
        if self.need_to_pick_dir:
            dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".")
            self.try_change_to_new_dir( dirname )

        #first call to numberOfChangedFiles will be > 0 if any .py files are found
        elif numberOfChangedFiles( self.dirname ) > 0: # or self.numNosyCalls==0
            self.callNosy()

        self.SetAlarm()
示例#45
0
labels = [label_first_name, label_last_name, label_email]
entries = [entry_first_name, entry_last_name, entry_email]
buttons = [button_first, button_last, button_prev, button_next, button_last, button_quit]


for i in range(3):
    labels[i].grid(row = i, column = 0, sticky = 'W')
    entries[i].grid(row = i, column = 1, columnspan = 6)

for j in range(6):
    buttons[j].grid(row = 3, column = j, sticky = 'E')

# def change1(*arg):
#     first_name.set(first_name.get())

# def change2(*arg):
#     last_name.set(last_name.get())

# def change3(*arg):
#     email.set(email.get())

def callback(email):
    global position_track
    update_value(position_track)
    print (email.get())

# first_name.trace("w", change1)
# last_name.trace("w", change2)
email.trace("w", lambda *args, email = email: callback(email))

window.mainloop()
示例#46
0
class BIDSContainer(FileInfo):
    """
    The base object which contains BIDSFiles.
    For KIT data this is the folder that contains the .con, .mrk etc files.
    For Elekta data this is the .fif file itself, so the file is a
    BIDSContainer and a BIDSFile simultanously.
    """
    def __init__(self, id_=None, file=None, settings=None, parent=None):
        super(BIDSContainer, self).__init__(id_, file, parent)

        self._settings = settings

    def _create_vars(self):
        FileInfo._create_vars(self)
        self.proj_name = StringVar()
        self.proj_name.trace("w", self.check_projname_change)
        self.session_ID = StringVar(value='1')
        self.session_ID.trace("w", self.validate)
        # This will be a list of BIDSFile's which have their data extracted
        # and passed to mne_bids.
        self.jobs = set()

        # subject info
        self.subject_ID = StringVar()
        self.subject_ID.trace("w", self.validate)
        # self.subject_age format [DD, MM, YYYY]
        self.subject_age = [StringVar(), StringVar(), StringVar()]
        self.subject_gender = OptionsVar(options=['M', 'F', 'U'])
        self.subject_group = OptionsVar(options=['Participant', 'Control'])
        self.subject_group.trace("w", self._update_groups)

        self.contains_required_files = True
        self.requires_save = True

        self.extra_data = dict()
        # List of extra files to be dumped in the same directory as the
        # scants.tsv
        self.extra_files = []

        # MEG data parameters
        self.electrode = None
        self.hsp = None
        self.readme = None

        self.make_specific_data = dict()

        # Whether the object has had any validation done yet.
        # This will be used to optimise the validation process since once the
        # BIDSContainer has had it's initial validation checks done, we will
        # only need to check the job for their validation sate, instead of
        # running validation on them again.
        self.validation_initialised = False

    def load_data(self):
        """ do all the intial data loading and variable assignment """
        pass

    def init_validation(self):
        """ Checks the validity of any associated jobs and self"""
        for job in self.jobs:
            job.validate(validate_container=False)
        self.validate()
        self.validation_initialised = True

    def validate(self, *args):
        self.valid = self.check_valid()
        self._set_bids_button_state()

    def check_valid(self):
        is_valid = super(BIDSContainer, self).check_valid()
        is_valid &= self.proj_name.get() != ''
        is_valid &= self.subject_ID.get() != ''
        for job in self.jobs:
            is_valid &= job.valid
        return is_valid

    def check_projname_change(self, *args):
        """
        A function to be called every time the project ID changes
        to allow the settings to be adjusted accordingly to allow for automatic
        updating of any applicable defaults
        """
        # re-assign the settings to themselves by evoking the setter method
        # of self.settings.
        if self.parent is not None:
            self.settings = self.parent.proj_settings
        # not sure if having this here is doubling up and could cause problems
        self.validate()

    def _apply_settings(self):
        # try find the specific project settings
        if isinstance(self.settings, list):
            for proj_settings in self.settings:
                if (proj_settings.get('ProjectID', None) ==
                        self.proj_name.get()):
                    self._settings = proj_settings
                    break
            else:
                self._settings = dict()
        # otherwise we already have the dictionary of settings correctly
        groups = flatten(self.settings.get('Groups', ['Participant',
                                                      'Control']))
        tasks = flatten(self.settings.get('Tasks', ['None']))
        self.subject_group.options = groups
        for job in self.jobs:
            job.task.options = tasks
            job._update_tasks()
        self._update_groups()

    def _update_groups(self, *args):
        """Update the EntryChoice that contains the group options"""
        if self.associated_tab is not None:
            self.associated_tab.sub_group_entry.value = self.subject_group

    def _set_bids_button_state(self):
        """
        Set the state of the button depending on whether it should be
        active or not
        """
        if self.associated_tab is not None:
            if self.valid:
                self.associated_tab.bids_gen_btn.config({"state": ACTIVE})
            else:
                self.associated_tab.bids_gen_btn.config({"state": DISABLED})

    def prepare(self):
        """Prepare all the data in the object to be ready for bids export"""
        # generate the readme
        if isinstance(self.settings, dict):
            self.readme = generate_readme(self.settings)

    @property
    def settings(self):
        return self._settings

    @settings.setter
    def settings(self, value):
        self._settings = value
        self._apply_settings()

    def __getstate__(self):
        # only returns a dictionary of information that we actually need
        # to store.
        data = super(BIDSContainer, self).__getstate__()
        data['prj'] = self.proj_name.get()
        data['sid'] = self.session_ID.get()
        data['sji'] = self.subject_ID.get()
        data['sja'] = [self.subject_age[0].get(),
                       self.subject_age[1].get(),
                       self.subject_age[2].get()]
        data['sjs'] = self.subject_gender.get()
        data['sjg'] = self.subject_group.get()

        return data

    def __setstate__(self, state):
        super(BIDSContainer, self).__setstate__(state)
        self.proj_name.set(state.get('prj', ''))
        self.session_ID.set(state.get('sid', ''))
        self.subject_ID.set(state.get('sji', ''))
        self.subject_age[0].set(state.get('sja', ['', '', ''])[0])
        self.subject_age[1].set(state.get('sja', ['', '', ''])[1])
        self.subject_age[2].set(state.get('sja', ['', '', ''])[2])
        gender = state.get('sjs', 'M')
        self.subject_gender.options = ['M', 'F', 'U']
        self.subject_gender.set(gender)
        group = state.get('sjg', '')
        self.subject_group.options = [group]
        self.subject_group.set(group)
示例#47
0
    button_quit
]

for i in range(3):
    labels[i].grid(row=i, column=0, sticky='W')
    entries[i].grid(row=i, column=1, columnspan=6)

for j in range(6):
    buttons[j].grid(row=3, column=j, sticky='E')

# def change1(*arg):
#     first_name.set(first_name.get())

# def change2(*arg):
#     last_name.set(last_name.get())

# def change3(*arg):
#     email.set(email.get())


def callback(email):
    global position_track
    update_value(position_track)
    print(email.get())


# first_name.trace("w", change1)
# last_name.trace("w", change2)
email.trace("w", lambda *args, email=email: callback(email))

window.mainloop()
示例#48
0
class c_configFrame(ttk.Frame):
    '''
    classdocs
    '''

    def __init__(self,master,owner,config_data,**params):
        '''
        Constructor
        '''
        try:
            super().__init__(master,**params)
            self.owner = owner
            self.config_data = config_data
            self.validation_result = StringVar()
            self.validation_result.trace('w',self.__on_change_validation_result)
            self.__create_children(config_data)

        except: raise


    def __del__(self):
        '''
        Destructor
        '''
        for child in self.children:
            self.children[child].destroy()

    def __create_children(self,config_data):
        try:
            row=0
            ttk.Label(self,text="Required Settings").grid(column=0,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Text Editor").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.text_edit,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_textedit",text="Select",command=self.__on_btn_select_textedit).grid(column=2,row=row,sticky='w')
            row=row+1
            
            ttk.Label(self,text="File Compare").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.file_compare,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_fielcompare",text="Select",command=self.__on_btn_select_file_compare).grid(column=2,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="PTC Client directory").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.ptc_client_dir,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_ptc_client",text="Select",command=self.__on_btn_select_ptc_client).grid(column=2,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="PTC Gateway(Rif.bat)").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.rif_bat,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_rifbat",text="Select",command=self.__on_btn_select_rifbat).grid(column=2,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Mapping Template").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.template,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_template",text="Select",command=self.__on_btn_select_template).grid(column=2,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Options").grid(column=0,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Max number of paralell processes").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.max_threads,width=2,).grid(column=1,row=row,sticky='w')
            row=row+1
            
            ttk.Label(self,text="Ptc Gateway Mapping GUI").grid(column=0,row=row,sticky='w')
            ttk.Checkbutton(self,variable=self.config_data.gw_mapping_gui,onvalue=True, offvalue=False).grid(column=1,row=row,sticky='w')
            row=row+1

            
            ttk.Label(self,text="Ptc Gateway GUI").grid(column=0,row=row,sticky='w')
            ttk.Checkbutton(self,variable=self.config_data.gw_gui,onvalue=True, offvalue=False).grid(column=1,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Ptc Gateway NoGUI All Yes").grid(column=0,row=row,sticky='w')
            ttk.Checkbutton(self,variable=self.config_data.gw_all_yes,onvalue=True, offvalue=False).grid(column=1,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Project Settings").grid(column=0,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="PTC Project").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.ptc_project,width=100).grid(column=1,row=row,sticky='w')
            row=row+1

            ttk.Label(self,text="Input directory").grid(column=0,row=row,sticky='w')
            ttk.Entry(self,textvariable=self.config_data.input_dir,width=100,state="readonly").grid(column=1,row=row,sticky='w')
            ttk.Button(self,name="btn_select_input_dir",text="Select",command=self.__on_btn_select_input_dir).grid(column=2,row=row,sticky='w')

            row=row+1
            ttk.Label(self).grid(column=0,row=row,sticky='w')
            row=row+1
            ttk.Label(self).grid(column=0,row=row,sticky='w')
            row=row+1
            ttk.Label(self).grid(column=0,row=row,sticky='w')

            row=row+1
            self.textfield=Text(self,height=8,width=75,state='disabled')
            self.textfield.grid(column=1,row=row)
            ttk.Button(self,name="btn_validate",text="Validate",command=self.__on_btn_validate).grid(column=2,row=row)
            
        except: raise
        else: pass

    def __on_btn_select_rifbat(self):       self.config_data.cmd_select_rifbat()
    def __on_btn_select_template(self):     self.config_data.cmd_select_template()
    def __on_btn_select_textedit(self):     self.config_data.cmd_select_textedit()
    def __on_btn_select_file_compare(self): self.config_data.cmd_select_filecompare()
    def __on_btn_select_ptc_client(self):   self.config_data.cmd_select_ptc_client()
    def __on_btn_select_input_dir(self):    self.config_data.cmd_select_input_dir()

    def __on_chk_use_ptc(self):
        pass

    def __on_btn_validate(self):
        (result,text) = self.config_data.cmd_validate_config()
        self.validation_result.set(text) 
        if(result==True):
            self.owner.config_valid()
        pass
    
    def __on_change_validation_result(self,*args):
        try:
            self.textfield.configure(state='normal')
            self.textfield.delete(1.0,END)
            self.textfield.insert(END,self.validation_result.get())
            self.textfield.configure(state='disabled')
        except: raise
示例#49
0
class ULDO01(UIExample):
    def __init__(self, master=None):
        super(ULDO01, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)

        self.board_num = 0
        self.digital_props = DigitalProps(self.board_num)

        # Find the first port that supports output, defaulting to None
        # if one is not found.
        self.port = next(
            (port
             for port in self.digital_props.port_info if port.supports_output),
            None)

        # If the port is configurable, configure it for output
        if self.port != None and self.port.is_port_configurable:
            try:
                ul.d_config_port(self.board_num, self.port.type,
                                 DigitalIODirection.OUT)
            except ULError as e:
                self.show_ul_error(e)

        self.running = False

        self.create_widgets()

    def get_data_value(self):
        try:
            return int(self.data_value_entry.get())
        except ValueError:
            return 0

    def data_value_changed(self, *args):
        try:
            # Get the data value
            data_value = self.get_data_value()
            # Send the value to the device
            ul.d_out(self.board_num, self.port.type, data_value)
        except ULError as e:
            self.stop()
            self.show_ul_error(e)

    def exit(self):
        # Set the port to 0 at exit
        try:
            ul.d_out(self.board_num, self.port.type, 0)
        except ULError as e:
            self.show_ul_error(e)
        self.master.destroy()

    def create_widgets(self):
        '''Create the tkinter UI'''
        if self.port != None:
            main_frame = tk.Frame(self)
            main_frame.pack(fill=tk.X, anchor=tk.NW)

            positive_int_vcmd = self.register(self.validate_positive_int_entry)

            curr_row = 0
            value_label = tk.Label(main_frame)
            value_label["text"] = "Value:"
            value_label.grid(row=curr_row, column=0, sticky=tk.W)

            self.data_value_variable = StringVar()
            self.data_value_entry = tk.Spinbox(
                main_frame,
                from_=0,
                to=255,
                textvariable=self.data_value_variable,
                validate="key",
                validatecommand=(positive_int_vcmd, "%P"))
            self.data_value_entry.grid(row=curr_row, column=1, sticky=tk.W)
            self.data_value_variable.trace("w", self.data_value_changed)

            button_frame = tk.Frame(self)
            button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

            quit_button = tk.Button(button_frame)
            quit_button["text"] = "Quit"
            quit_button["command"] = self.exit
            quit_button.grid(row=0, column=1, padx=3, pady=3)
        else:
            self.create_unsupported_widgets(self.board_num)
示例#50
0
    def refreshWidget(self) :
        #print "refresh"
        self.card_win.pack_forget()
        import unicodedata
        #Card window      
        self.card_win = PanedWindow(self.card_win.master, orient=VERTICAL)
        self.card_win.pack(side=TOP, expand=True, fill=BOTH, pady=2, padx=2)
        
        
        #Create the name zone
        name_zone=PanedWindow(self.card_win, orient=HORIZONTAL)
        name = StringVar() 
        name.set(self.name)
        def modifName(*args) :
            try :
                assert('"' not in name.get())
                name.get().encode('ascii')
            except Exception as e:
                print ("error on name")
                name.set(self.name)
                return
            old = self.name in Card.blocked_creature
            self.name=name.get()
            if old or self.name in Card.blocked_creature :
                self.refreshWidget()
        name.trace("w", modifName)
        name_wid=Entry(name_zone, width=30,textvariable=name)
        name_wid.pack()
        name_zone.add(name_wid)
        #Create the cost ad star stringvar
        #print int(floor(self.getCost()))
        self.cost=StringVar()
        self.stars=StringVar()
        cost_wid=Label(None, textvariable=self.cost, background='red',width=5, anchor=W)
        star_wid=Label(None, textvariable=self.stars, background='blue', anchor=E)
        self.cost.set(str(int(floor(self.getCost()))))
        self.stars.set("*"*self.getStars())
        #Add them in name zone
        name_zone.add(cost_wid)
        name_zone.add(star_wid)
        
        
        #Create an Image Zone
        image_zone=Button(self.card_win,  command=self.choosePhoto)
        if hasattr(self,"photofile") and self.photofile :            
            print ("Image: ",self.photofile)
            try :
                pilImage=Image.open(self.photofile)
                img=PhotoImage(pilImage,master=image_zone)
            except :
               decomp=self.photofile.split('/')
               for i in range(1,6) :
                   try :
                       fname="/".join(decomp[-i:])
                       print ("try to open",fname)
                       pilImage = Image.open(fname)
                       img=PhotoImage(pilImage,master=image_zone)
                       self.photofile=fname
                       break
                   except :
                       self.photofile=None
        if self.photofile :
            w, h = img.width(), img.height()
            print('wh',w,h)
            if h>400 :
                print("reduction")
                img=PhotoImage(pilImage.resize((w//2,h//2), Image.ANTIALIAS),master=image_zone)
            image_zone=Button(self.card_win,image=img,  command=self.choosePhoto)
            image_zone.image=img
            #image_zone.configure(image=image_zone.image,width=50,height=50,compound=RIGHT)
            #image_zone.pack()
            #print "IMAGE CHANGED"
        else :
            from os import path
            fname=self.name.replace(" ","_")
            if path.isfile("Cards/"+fname+".png") :
                image_zone.config(text='image can be taken from\n'+"Cards/"+fname+".png",background='white',anchor=CENTER)
            else :
                image_zone.config(text='clic to choose image',background='white',anchor=CENTER)

        #image_zone.pack()
        
        
        # POWER ZONE
        power_zone=PanedWindow(self.card_win, orient=VERTICAL)
        #fenetre=self.card_win.master
        def removePowerCreator(px) :
            def removePower(*args) :
                #print 'avant',list_pow
                self.bonus.remove(px)
                #print 'apres',list_pow
                #self.card_win.pack_forget()
                self.refreshWidget()
            return removePower
        for p in self.bonus :
            powline =  PanedWindow(self.card_win, orient=HORIZONTAL)
            pow_wid=p.initWidget(powline)
            powline.add(pow_wid)
            removepow=Button(powline, text="X", command=removePowerCreator(p), anchor=E)
            removepow.pack()
            powline.add(removepow)
            power_zone.add(powline) 
        def addPower(*args) :
            if addBonus.get()!= "add bonus":
                name=addBonus.get()
            else:
                name=add_cost_alteration.get()
            print ("added :",name)
            import CardPowers
            self.bonus+=[eval('CardPowers.'+name+'()')]
            self.bonus[-1].parent=self.bonus
            self.bonus[-1].card=self
            #self.card_win.pack_forget()
            self.refreshWidget()
        #Add bonus Option menu
        addBonus = StringVar(power_zone)
        addBonus.set("add bonus") # default value
        if not self.pv:  
            addBonus_wid = Spell.getSpellMenu(power_zone, addBonus)
        else: addBonus_wid = getBonusMenu(power_zone, addBonus) 
        addBonus.trace('w', addPower)
        if self.pv>0 or len(self.bonus)==0 or all([b.is_cost_alterator for b in self.bonus]):
            addBonus_wid.pack()
            #Add this to power zone
            power_zone.add(addBonus_wid)
        
        #Create save zone
        save_zone = PanedWindow(self.card_win, orient=HORIZONTAL)
        if self.monster_type != "all" and not(self.name in Card.blocked_creature) :
            save_wid = Button(save_zone, text="Save", command=self.postAndSave)
        elif self.monster_type != "all" : 
            save_wid = Button(save_zone, text="creature in campaign", command=None)
        else:
            save_wid = Button(save_zone, text="nead type", command=None)
        save_wid.pack()
        #Create the open button
        save_zone.pack()        
        if Card.monster_list.keys():
            self.opening = StringVar(save_zone)
            self.opening.set("Open")
            choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature]
            choice.sort()
            #print all_monsters.keys()
            open_wid = OptionMenu(save_zone, self.opening,*choice)
            self.opening.trace('w', self.Open)
            open_wid.pack()
            save_zone.add(open_wid)
        
        if Card.monster_list.keys():
            self.delete = StringVar(save_zone)
            self.delete.set("Delete")
            choice = [na for na in Card.monster_list.keys() if na not in Card.blocked_creature]
            choice.sort()
            delete_wid = OptionMenu(save_zone, self.delete,*choice)
            self.delete.trace('w', self.clicDelete)
            delete_wid.pack()
            save_zone.add(delete_wid)
        
        #Create the type button
        self.category = StringVar(save_zone)
        self.category.set(self.monster_type)
        choice = [file2name(t,"_monsters.sav") for t in glob.glob("CardFiles/*_monsters.sav")]
        if "recup" in choice:
            choice.remove("recup")
        #print all_monsters.keys()
        category_wid = OptionMenu(save_zone, self.category,*choice)
        self.category.trace('w', self.setFile)
        
        
        
        category_wid.pack()
        
        #Add it to save zone
        save_zone.add(save_wid)
        save_zone.add(category_wid)
        
        #Create a new Strength zone for att and pv
        strength_zone=PanedWindow(self.card_win, orient=HORIZONTAL)
        att=StringVar()
        att.set(str(self.att))
        pv=StringVar() ; pv.set(str(self.pv))
        def modifiedAttPv(*args) :
            print ("modifiedAttPv")
            self.pv=int(pv.get())
            if self.pv<1 and self.is_spell==False :
                if len(self.bonus)==0 :
                    self.is_spell=True
                    self.refreshWidget()
                else :
                    self.pv=1
                    self.refreshWidget()
            if self.pv>0 and self.is_spell==True :
                if len(self.bonus)==0 :
                    self.is_spell=False
                    self.refreshWidget()
                else :
                    self.pv=0
                    self.refreshWidget()            
            self.att=int(att.get())
            self.getCost()
        att_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=att,command=modifiedAttPv)
        att_wid.pack()
        strength_zone.add(att_wid)
        strength_zone.add(Label(strength_zone, text='       ', background='white', 
             anchor=CENTER))
        pv_wid = Spinbox(strength_zone, from_=0, to=1000,textvariable=pv,command=modifiedAttPv)
        pv_wid.pack()
        strength_zone.add(pv_wid)
        
        #Put it all in window
        self.card_win.add(name_zone)
        self.card_win.add(image_zone)
        self.card_win.add(power_zone)  
        self.card_win.add(strength_zone)
        self.card_win.add(save_zone)
        
        
        self.card_win.pack()                      
示例#51
0
    def __init__(self) :
        Game.__init__(self)
        import socket
        import tkinter
        self.local = self.host=socket.gethostbyname(socket.gethostname()) # Get local machine ip
        from tkinter import Tk,PanedWindow,StringVar,Entry,Button,VERTICAL,HORIZONTAL,Label
        fenetre=Tk()
        fenetre.title('Socket parameters') 
        self.netgame_win = PanedWindow(fenetre, orient=VERTICAL)
        host_zone=PanedWindow(self.netgame_win, orient=HORIZONTAL)
        host=StringVar()
        host.set(self.local)
        def modifHost(*args) :
            self.host=host.get()
            if self.local==self.host :
                start_button.config(text="Create")
            else :
                start_button.config(text="Join")
        host.trace("w", modifHost)
        host_wid=Entry(host_zone, width=30,textvariable=host)
        host_wid.pack()
        host_label=Label(fenetre, text="Host (you are "+self.local+") :")
        host_zone.add(host_label)
        host_zone.add(host_wid)
        self.netgame_win.add(host_zone)
        port_zone=PanedWindow(self.netgame_win, orient=HORIZONTAL)
        port=StringVar()
        self.port=52333
        port.set(str(self.port))
        # adress_wid=Label(None, textvariable=self.cost, background='red',width=5, anchor=W)
        def modifPort(*args) :
            #print "modify port to",port.get()
            try :
                self.port=int(port.get())
            except :
                port.set("")
        port.trace("w", modifPort)
        port_wid=Entry(fenetre, width=30,textvariable=port)
        #port_wid.grid(column=0, row=1)
        host_wid.focus() 
        port_wid.pack()
        port_label=Label(fenetre, text="Port :")
        port_zone.add(port_label)
        port_zone.add(port_wid)
        self.netgame_win.add(port_zone)
        #Create the open button
        def start() :
            fenetre.destroy()
        start_button=Button(self.netgame_win,text="Create",command=start)
        self.netgame_win.add(start_button)
        self.netgame_win.pack()
        #fenetre.focus_set()
        #start_button.focus()        
        fenetre.mainloop()
             # Import socket module
        self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # Reserve a port for your service.
        if self.local==self.host :
            self.soc.bind((self.host, self.port))        # Bind to the port
            print( "socket listening")
            self.soc.listen(5)                 # Now wait for client connection.

            self.soc, addr = self.soc.accept()     # Establish connection with client.
            print( 'Got connection from', addr)
            #self.soc.send('Thank you for connecting')
            #c.close()                # Close the connection
            self.firstplayer=choice([1,2])
            print( "FIRST PLAYER IS",self.firstplayer)
            self.soc.send(str(3-self.firstplayer).encode('utf-8'))
        else :
            self.soc.connect((self.host, self.port))
            print( "connect ok")
            p=self.soc.recv(1024).decode('utf-8')
            try :
                self.firstplayer=int(p)
            except :
                print( "error concerning first player, got ",p)
        self.remains=""
示例#52
0
文件: ULDO01.py 项目: jdechevr/mcculw
class ULDO01(UIExample):
    def __init__(self, master=None):
        super(ULDO01, self).__init__(master)
        master.protocol("WM_DELETE_WINDOW", self.exit)
        # By default, the example detects all available devices and selects the
        # first device listed.
        # If use_device_detection is set to False, the board_num property needs
        # to match the desired board number configured with Instacal.
        use_device_detection = True
        self.board_num = 0

        try:
            if use_device_detection:
                self.configure_first_detected_device()

            self.device_info = DaqDeviceInfo(self.board_num)
            dio_info = self.device_info.get_dio_info()

            # Find the first port that supports output, defaulting to None
            # if one is not found.
            self.port = next(
                (port for port in dio_info.port_info if port.supports_output),
                None)

            if self.port is not None:
                # If the port is configurable, configure it for output
                if self.port.is_port_configurable:
                    try:
                        ul.d_config_port(self.board_num, self.port.type,
                                         DigitalIODirection.OUT)
                    except ULError as e:
                        show_ul_error(e)
                self.create_widgets()
            else:
                self.create_unsupported_widgets()
        except ULError:
            self.create_unsupported_widgets(True)

    def get_data_value(self):
        try:
            return int(self.data_value_entry.get())
        except ValueError:
            return 0

    def data_value_changed(self, *args):
        try:
            # Get the data value
            data_value = self.get_data_value()
            # Send the value to the device
            ul.d_out(self.board_num, self.port.type, data_value)
        except ULError as e:
            show_ul_error(e)

    def exit(self):
        # Set the port to 0 at exit
        try:
            ul.d_out(self.board_num, self.port.type, 0)
        except ULError as e:
            show_ul_error(e)
        self.master.destroy()

    def create_widgets(self):
        '''Create the tkinter UI'''
        self.device_label = tk.Label(self)
        self.device_label.pack(fill=tk.NONE, anchor=tk.NW)
        self.device_label["text"] = ('Board Number ' + str(self.board_num) +
                                     ": " + self.device_info.product_name +
                                     " (" + self.device_info.unique_id + ")")

        main_frame = tk.Frame(self)
        main_frame.pack(fill=tk.X, anchor=tk.NW)

        positive_int_vcmd = self.register(validate_positive_int_entry)

        curr_row = 0
        value_label = tk.Label(main_frame)
        value_label["text"] = "Value:"
        value_label.grid(row=curr_row, column=0, sticky=tk.W)

        self.data_value_variable = StringVar()
        self.data_value_entry = tk.Spinbox(
            main_frame,
            from_=0,
            to=255,
            textvariable=self.data_value_variable,
            validate="key",
            validatecommand=(positive_int_vcmd, "%P"))
        self.data_value_entry.grid(row=curr_row, column=1, sticky=tk.W)
        self.data_value_variable.trace("w", self.data_value_changed)

        button_frame = tk.Frame(self)
        button_frame.pack(fill=tk.X, side=tk.RIGHT, anchor=tk.SE)

        quit_button = tk.Button(button_frame)
        quit_button["text"] = "Quit"
        quit_button["command"] = self.exit
        quit_button.grid(row=0, column=1, padx=3, pady=3)
示例#53
0
# Initialize the radioButFingers array
radioButFingers = [Radiobutton(), Radiobutton(), Radiobutton(), Radiobutton()]

# Set the radio buttons
for text, mode in FINGERS_MODE_LIST:
    radioButFingers[radi_butt_index] = Radiobutton(
        root, text=text, variable=finger_control_variable, value=mode)
    radioButFingers[radi_butt_index].place(x=slider_group_x_offset + 240,
                                           y=slider_group_y_offset + 15 +
                                           radio_butt_offset * radi_butt_index)
    radi_butt_index += 1

radioButFingers[2].select()  #Select initialy the lock position

# Call the finger_control_mode function when the radio buttons change state
finger_control_variable.trace("w", finger_control_mode)

# ------------- Homing ---------------

homingButton = Button(root, text="Homing")
homingButton.bind("<Button-1>", Homing)
homingButton.grid(row=3, column=4, sticky=W)

# ------------ DropList ---------------

choices = ['all', '1', '2', '3']
popupList = OptionMenu(root, list_choiceHoming, *choices)
# Label(root, text = "Choose the axe").grid( row = 2, column = 4, sticky = W)
popupList.grid(row=3, column=4, sticky=E)
list_choiceHoming.set('all')
示例#54
0
class MainUI:
    
    __PLATFORM = ['IOS', 'ANDROID']
    __rootList = []
    
    def __init__(self):
        self.__rootList = []
        
    def initUI(self):
        self.frame = tkinter.Tk()
        self.frame.geometry('600x600')  # 是x 不是*
        self.frame.resizable(width=True, height=True)  # 宽不可变, 高可变,默认为True
        self.frame.minsize(700, 600)
        self.frame.title('工具集')
        
        '''工作目录'''
        panel1 = ttk.Labelframe(self.frame, text='工作目录')
        
        # 打包路径label
        packRootLabel = ttk.Label(panel1, text='打包路径:')
        packRootLabel.grid(row=0, column=0, padx=3, pady=3)
        
        # root下拉菜单
        self.packRootPathVar = StringVar()
        self.packRootPathVar.trace('w', self.__packRootPathChangeCallBack)
        self.packRootPath = ttk.Combobox(panel1, textvariable=self.packRootPathVar)
        self.packRootPath.grid(row=0, column=1, padx=3, pady=3, stick='we')
        
        # root路径选择按钮
        packRootSelBtn = ttk.Button(panel1, text='选择', command=self.selectRootDir)
        packRootSelBtn.grid(row=0, column=2, padx=3, pady=3)
        panel1.columnconfigure(1, weight=1)
        panel1.pack(fill='x', side=TOP, padx=5, pady=5, ipadx=10, ipady=5)
        
        '''打包设置'''
        panel2 = ttk.LabelFrame(self.frame, text='打包设置')
        childRow1 = ttk.Frame(panel2)
        
        # 资源目录label
        srcPathLabel = ttk.Label(childRow1, text='资源目录:')
        srcPathLabel.grid(row=0, column=0, padx=3, pady=3)
        
        # 资源目录路径
        self.srcPathVar = StringVar()
        self.srcPathVar.trace('w', callback=self.__platformChangeCallBack)
        srcPath = ttk.Entry(childRow1, textvariable=self.srcPathVar)
        srcPath.grid(row=0, column=1, padx=3, pady=3, stick='we')
        
        # 资源目录路径选择按钮
        srcPathBtn = ttk.Button(childRow1, text='选择', command=self.selectSrcDir)
        srcPathBtn.grid(row=0, column=2, padx=3, pady=3)
        childRow1.columnconfigure(1, weight=1)
        childRow1.pack(fill='x', side=TOP)
        childRow2 = ttk.Frame(panel2)
        
        # 平台类型
        self.platformComboVar = StringVar()
        platformCombo = ttk.Combobox(childRow2, values=self.__PLATFORM, state='readonly', width=10, textvariable=self.platformComboVar)
        platformCombo.current(0)
        platformCombo.grid(row=0, column=1, padx=3, pady=3)
        
        # 是否全新打包
        self.isNew = IntVar()
        isNewCheck = ttk.Checkbutton(childRow2, text='全新打包', variable=self.isNew)
        isNewCheck.grid(row=0, column=3, padx=3, pady=3)
        
        # 是否整包
        self.isFull = IntVar()
        isFullCheck = ttk.Checkbutton(childRow2, text='整包', variable=self.isFull)
        isFullCheck.grid(row=0, column=4, padx=3, pady=3)
        
        childRow2.columnconfigure(5, weight=1)
        childRow2.pack(fill='x', side=TOP)
        
        panel2.pack(fill='x', side=TOP, padx=5, pady=5, ipadx=10, ipady=5)
        
        # 开始按钮
        startBtn = ttk.Button(self.frame, text='开始打包', command=self.startPack)
        startBtn.pack()
        
        '''输出步骤'''
        panel3 = ttk.LabelFrame(self.frame, text='总览')
        headTextBar = ttk.Scrollbar(panel3, orient=VERTICAL)
        headTextBar.pack(side=RIGHT, fill='y')
        self.headConsole = Text(panel3, state='disabled', yscrollcommand=headTextBar.set, width=40, foreground='white', background='black')
        self.headConsole.pack(expand=1, fill=BOTH)
        panel3.pack(fill='y', side=LEFT, padx=5, pady=5, ipadx=10, ipady=5)
        
        '''输出详细信息'''
        panel4 = ttk.LabelFrame(self.frame, text='详细信息')
        bottomTextBar = ttk.Scrollbar(panel4, orient=VERTICAL)
        bottomTextBar.pack(side=RIGHT, fill='y')
        self.bottomConsole = Text(panel4, state='disabled', yscrollcommand=bottomTextBar.set, foreground='white', background='black')
        self.bottomConsole.pack(expand=1, fill=BOTH)
        panel4.pack(expand=1, fill=BOTH, side=LEFT, padx=5, pady=5, ipadx=10, ipady=5)
        
        self.frame.after(50, func=self.updateLog)
        
    def initUIValues(self):
        RootInfoMgr.load()
        self.__rootList = RootInfoMgr.rootPathList
        self.updateRootList()
        
    def show(self):
        self.frame.mainloop()
        
    def updateLog(self):
        self.headConsole.configure(state='normal')
        while not Log.infoQueue.empty() :
            text = Log.infoQueue.get(True, 1)
            self.headConsole.insert('end', text)
        self.headConsole.configure(state='disabled')
        
        self.bottomConsole.configure(state='normal')
        while not Log.detailQueue.empty() :
            text = Log.detailQueue.get(True, 1)
            self.bottomConsole.insert('end', text)
        self.bottomConsole.configure(state='disabled')
        
        self.frame.after(50, func=self.updateLog)
    
    def selectRootDir(self):
        rootdir = askdirectory()
        if len(rootdir) > 0 and os.path.exists(rootdir) :
            self.packRootPathVar.set(rootdir)
            
    def selectSrcDir(self):
        srcdir = askdirectory()
        if len(srcdir) > 0 and os.path.exists(srcdir) :
            self.srcPathVar.set(srcdir)
    
    def updateRootList(self):
        self.packRootPath['values'] = self.__rootList
        if len(self.__rootList) > 0:
            self.packRootPath.current(0)
            
    def startPack(self):
        self.headConsole.configure(state='normal')
        self.headConsole.delete(0.0, 'end')
        self.headConsole.configure(state='disabled')
        self.bottomConsole.configure(state='normal')
        self.bottomConsole.delete(0.0, 'end')
        self.bottomConsole.configure(state='disabled')
        if not os.path.exists(self.packRootPathVar.get()) :
            Log.printInfoln('打包目录错了,骚年,你确定有这文件夹?? ' + self.packRootPathVar.get())
            return
        if not os.path.exists(self.srcPathVar.get()) :
            Log.printInfoln('资源文件目录错了!' + self.srcPathVar.get())
            return
        RootInfoMgr.updateRoot(self.packRootPathVar.get())
        RootInfoMgr.writeRootInfo(self.packRootPathVar.get(), os.path.normpath(self.srcPathVar.get()), self.platformComboVar.get())
        self.updateRootList()
        ProcessMgr.start(self.srcPathVar.get(), self.getPlatformType(), self.isNew.get() > 0, self.isFull.get() > 0)
        
    def getPlatformType(self):
        if self.__PLATFORM[0] == self.platformComboVar :
            return PLATFORM_IOS
        else :
            return PLATFORM_ANDROID
        
    def __packRootPathChangeCallBack(self, *args):
        if os.path.exists(self.packRootPathVar.get()) :
            rootInfo = RootInfoMgr.loadRootInfo(self.packRootPathVar.get())
            if rootInfo != None :
                self.srcPathVar.set(os.path.normpath(rootInfo.srcPath))
                self.platformComboVar.set(rootInfo.platform)
        
    def __platformChangeCallBack(self, *args):
        if os.path.exists(self.srcPathVar.get()) :
            try:
                self.headConsole.configure(state='normal')
                self.headConsole.delete(0.0, 'end')
                self.headConsole.configure(state='disabled')
                self.bottomConsole.configure(state='normal')
                self.bottomConsole.delete(0.0, 'end')
                self.bottomConsole.configure(state='disabled')
                ProcessMgr.createContext(self.packRootPathVar.get())
            except :
                t, v, tb = sys.exc_info()
                print(t, v)
                traceback.print_tb(tb)
示例#55
0
class ConfigurationPanel(tk.Frame):
    def __init__(self, parent, controller):
        self.conf = Config.get_instance()
        tk.Frame.__init__(self, parent)
        self.xadd = 200
        self.label = tk.Label(self, text="Configuration", font=LARGE_FONT)
        self.label.pack(pady=10, padx=10)
        self.pop = 0
        self.cutil = ConfigUtil.get_instance()

        self.btnBack = ttk.Button(
            self,
            text="<< back",
            command=lambda: controller.show_frame(DefaultPanel))
        self.btnBack.place(x=20, y=80)

        self.lblVirusType = tk.Label(self, text="Select Virus")
        self.lblVirusType.place(x=400 + self.xadd, y=150)

        #---------------- combobox to select virus -----------------------

        self.combovar = StringVar()
        self.combovar.trace('w', self.on_change)
        list_disease = self.cutil.get_all_sections()
        self.comboBoxVirus = ttk.Combobox(self,
                                          textvar=self.combovar,
                                          state='readonly',
                                          values=list_disease[1:])
        self.comboBoxVirus.place(x=500 + self.xadd, y=150)
        self.comboBoxVirus.current(0)
        self.set_virus_properties()

        #combobox on change
    def set_virus_properties(self):
        self.conf = Config.get_instance()
        self.lblPopulation = tk.Label(self, text="Population")
        self.lblPopulation.place(x=200 + self.xadd, y=250)

        self.txtPopulation = tk.Text(self, height=1, width=25)
        self.txtPopulation.insert("end", str(self.conf.get_population()))
        self.txtPopulation.place(x=300 + self.xadd, y=250)

        self.lblInitialInfectedPer = tk.Label(
            self, text="Initial Infected Percentage")
        self.lblInitialInfectedPer.place(x=105 + self.xadd, y=300)

        self.txtInitialInfectedPer = tk.Text(self, height=1, width=25)
        self.txtInitialInfectedPer.insert(
            "end", str(self.conf.get_initial_infected_percentage()))
        self.txtInitialInfectedPer.place(x=300 + self.xadd, y=300)

        self.lblRFactor = tk.Label(self, text="R factor")
        self.lblRFactor.place(x=215 + self.xadd, y=350)

        self.sdrRFactor = tk.Scale(self,
                                   from_=0,
                                   to=10,
                                   orient=tk.HORIZONTAL,
                                   length=130,
                                   showvalue=0,
                                   resolution=1,
                                   command=self.set_valueRFactor)
        self.sdrRFactor.set(self.conf.get_r_factor())
        self.sdrRFactor.place(x=300 + self.xadd, y=350)

        self.lblRFactorVal = tk.Label(self,
                                      text=self.sdrRFactor.get(),
                                      height=1,
                                      width=3)
        self.lblRFactorVal.place(x=450 + self.xadd, y=350)

        self.lblKFactor = tk.Label(self, text="K factor")
        self.lblKFactor.place(x=215 + self.xadd, y=400)

        self.sdrKFactor = tk.Scale(self,
                                   from_=0,
                                   to=1,
                                   orient=tk.HORIZONTAL,
                                   length=130,
                                   showvalue=0,
                                   resolution=0.01,
                                   command=self.set_valueKFactor)
        self.sdrKFactor.set(self.conf.get_k_factor())
        self.sdrKFactor.place(x=300 + self.xadd, y=400)

        self.lblKFactorVal = tk.Label(self,
                                      text=self.sdrKFactor.get(),
                                      height=1,
                                      width=3)
        self.lblKFactorVal.place(x=450 + self.xadd, y=400)

        self.lblDaysContagious = tk.Label(self, text="Days Contagious")
        self.lblDaysContagious.place(x=160 + self.xadd, y=450)

        self.txtDaysContagious = tk.Text(self, height=1, width=25)
        self.txtDaysContagious.insert("end",
                                      str(self.conf.get_days_contageous()))
        self.txtDaysContagious.place(x=300 + self.xadd, y=450)

        #------------------------- mask -------------------------

        self.lblMaskIntroducedTimeline = tk.Label(self, text="Mask Timeline")
        self.lblMaskIntroducedTimeline.place(x=180 + self.xadd, y=500)

        self.txtMaskIntroducedTimeline = tk.Text(self, height=1, width=25)
        self.txtMaskIntroducedTimeline.insert(
            "end", str(self.conf.get_mask_introduced_timeline()))
        self.txtMaskIntroducedTimeline.place(x=300 + self.xadd, y=500)

        self.lblMaskUsuageEffectiveness = tk.Label(
            self, text="Mask Usuage Effectiveness")
        self.lblMaskUsuageEffectiveness.place(x=95 + self.xadd, y=550)

        self.sdrMaskUsuageEffectiveness = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueMaskUsuageEffectiveness)
        self.sdrMaskUsuageEffectiveness.set(
            self.conf.get_mask_usage_effectiveness())
        self.sdrMaskUsuageEffectiveness.place(x=300 + self.xadd, y=550)

        self.lblMaskUsuageEffectivenessVal = tk.Label(
            self, text=self.sdrRFactor.get(), height=1, width=4)
        self.lblMaskUsuageEffectivenessVal.place(x=450 + self.xadd, y=550)

        self.lblMaskUsuagePercentage = tk.Label(self,
                                                text="Mask Usage Percentage")
        self.lblMaskUsuagePercentage.place(x=115 + self.xadd, y=600)

        self.sdrMaskUsuagePercentage = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueMaskUsuagePercentage)
        self.sdrMaskUsuagePercentage.set(self.conf.get_mask_usage_percentage())
        self.sdrMaskUsuagePercentage.place(x=300 + self.xadd, y=600)

        self.lblMaskUsuagePercentageVal = tk.Label(self,
                                                   text=self.sdrRFactor.get(),
                                                   height=1,
                                                   width=4)
        self.lblMaskUsuagePercentageVal.place(x=450 + self.xadd, y=600)

        #------------------------- quarantine -------------------------
        self.lblQuarantineIntroducedTimeline = tk.Label(
            self, text="Quarantine Timeline")
        self.lblQuarantineIntroducedTimeline.place(x=100 + 500 + self.xadd,
                                                   y=250)

        self.txtQuarantineIntroducedTimeline = tk.Text(self,
                                                       height=1,
                                                       width=25)
        self.txtQuarantineIntroducedTimeline.insert(
            "end", str(self.conf.get_quarantine_introduced_timeline()))
        self.txtQuarantineIntroducedTimeline.place(x=250 + 500 + self.xadd,
                                                   y=250)

        self.lblQuarantineEffectiveness = tk.Label(
            self, text="Quarantine Effectiveness")
        self.lblQuarantineEffectiveness.place(x=70 + 500 + self.xadd, y=300)

        self.sdrQuarantineUsuageEffectiveness = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueQuarantineUsuageEffectiveness)
        self.sdrQuarantineUsuageEffectiveness.set(
            self.conf.get_qurantine_effectiveness())
        self.sdrQuarantineUsuageEffectiveness.place(x=250 + 500 + self.xadd,
                                                    y=300)

        self.lblQuarantineUsuageEffectivenessVal = tk.Label(
            self, text=self.sdrRFactor.get(), height=1, width=4)
        self.lblQuarantineUsuageEffectivenessVal.place(x=400 + 500 + self.xadd,
                                                       y=300)

        self.lblQuarantinePercentage = tk.Label(self,
                                                text="Quarantining Percentage")
        self.lblQuarantinePercentage.place(x=70 + 500 + self.xadd, y=350)

        self.sdrQuarantinePercentage = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueQuarantinePercentage)
        self.sdrQuarantinePercentage.set(
            self.conf.get_qurantine_usage_percentage())
        self.sdrQuarantinePercentage.place(x=250 + 500 + self.xadd, y=350)

        self.lblQuarantinePercentageVal = tk.Label(self,
                                                   text=self.sdrRFactor.get(),
                                                   height=1,
                                                   width=4)
        self.lblQuarantinePercentageVal.place(x=400 + 500 + self.xadd, y=350)

        #------------------------- vaccine -------------------------
        self.lblVaccineIntroducedTimeline = tk.Label(self,
                                                     text="Vaccine Timeline")
        self.lblVaccineIntroducedTimeline.place(x=115 + 500 + self.xadd, y=400)

        self.txtVaccineIntroducedTimeline = tk.Text(self, height=1, width=25)
        self.txtVaccineIntroducedTimeline.insert(
            "end", str(self.conf.get_vaccine_introduced_timeline()))
        self.txtVaccineIntroducedTimeline.place(x=250 + 500 + self.xadd, y=400)

        self.lblVaccineEffectiveness = tk.Label(self,
                                                text="Vaccine Effectiveness")
        self.lblVaccineEffectiveness.place(x=85 + 500 + self.xadd, y=450)

        self.sdrVaccineEffectiveness = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueVaccineEffectiveness)
        self.sdrVaccineEffectiveness.set(self.conf.get_vaccine_effectiveness())
        self.sdrVaccineEffectiveness.place(x=250 + 500 + self.xadd, y=450)

        self.lblVaccineEffectivenessVal = tk.Label(self,
                                                   text=self.sdrRFactor.get(),
                                                   height=1,
                                                   width=4)
        self.lblVaccineEffectivenessVal.place(x=400 + 500 + self.xadd, y=450)

        self.lblVaccinePercentage = tk.Label(self, text="Vaccine Percentage")
        self.lblVaccinePercentage.place(x=100 + 500 + self.xadd, y=500)

        self.sdrVaccinePercentage = tk.Scale(
            self,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=130,
            showvalue=0,
            resolution=0.1,
            command=self.set_valueVaccinePercentage)
        self.sdrVaccinePercentage.set(self.conf.get_vaccine_usage_percentage())
        self.sdrVaccinePercentage.place(x=250 + 500 + self.xadd, y=500)

        self.lblVaccinePercentageVal = tk.Label(self,
                                                text=self.sdrRFactor.get(),
                                                height=1,
                                                width=4)
        self.lblVaccinePercentageVal.place(x=400 + 500 + self.xadd, y=500)

        self.btnSet = ttk.Button(self,
                                 text="Set",
                                 command=self.setButtonOnClick)
        self.btnSet.place(x=470 + self.xadd, y=650)

    def on_change(self, index, value, op):
        self.conf.set_property_name(self.comboBoxVirus.get())
        self.conf.load_from_file(self.comboBoxVirus.get())
        self.set_virus_properties()

    def set_valueRFactor(self, v):
        self.lblRFactorVal.config(text=v)

    def set_valueKFactor(self, v):
        self.lblKFactorVal.config(text=v)

    def set_valueMaskUsuageEffectiveness(self, v):
        self.lblMaskUsuageEffectivenessVal.config(text=v + '%')

    def set_valueMaskUsuagePercentage(self, v):
        self.lblMaskUsuagePercentageVal.config(text=v + '%')

    def set_valueQuarantineUsuageEffectiveness(self, v):
        self.lblQuarantineUsuageEffectivenessVal.config(text=v + '%')

    def set_valueQuarantinePercentage(self, v):
        self.lblQuarantinePercentageVal.config(text=v + '%')

    def set_valueVaccineEffectiveness(self, v):
        self.lblVaccineEffectivenessVal.config(text=v + '%')

    def set_valueVaccinePercentage(self, v):
        self.lblVaccinePercentageVal.config(text=v + '%')
        #print(self.txtVaccineIntroducedTimeline.get(1.0,"end-1c"))


#---------------------- changing config values -----------------

    def setButtonOnClick(self):
        conf = Config.get_instance()
        errorMessage = ""
        flag = 0

        try:
            population = int(self.txtPopulation.get(1.0, "end-1c"))
            conf.set_population(population)

        except:
            flag = 1
            errorMessage += "Population\n"

        try:
            daysContagious = int(self.txtDaysContagious.get(1.0, "end-1c"))
            conf.set_days_contageous(daysContagious)
        except:
            flag = 1
            errorMessage += "No of days contagious\n"

        try:
            initialInfectedPer = int(
                self.txtInitialInfectedPer.get(1.0, "end-1c"))
            conf.set_initial_infected_percentage(initialInfectedPer)
            print(conf.get_initial_infected_percentage())
        except:
            flag = 1
            errorMessage += "Initial infected percentage\n"

        try:
            maskIntroducedTimeline = int(
                self.txtMaskIntroducedTimeline.get(1.0, "end-1c"))
            conf.set_mask_introduced_timeline(maskIntroducedTimeline)
        except:
            flag = 1
            errorMessage += "Mask introduced timeline\n"

        try:
            quarantineIntroducedTimeline = int(
                self.txtQuarantineIntroducedTimeline.get(1.0, "end-1c"))
            conf.set_quarantine_introduced_timeline(
                quarantineIntroducedTimeline)
        except:
            flag = 1
            errorMessage += "Quarantine introduced timeline\n"

        try:
            vaccineIntroducedTimeline = int(
                self.txtVaccineIntroducedTimeline.get(1.0, "end-1c"))
            conf.set_vaccine_effectiveness(vaccineIntroducedTimeline)
        except:
            flag = 1
            errorMessage += "Vaccine Introduced Timeline\n"
        if flag == 1:
            tk.messagebox.showinfo("Error",
                                   errorMessage + " should be numbers")