def _update_entries(self, event=None): if self._first_step_check() == "skip": return wvalues = self._widget_values sum_ = float(sum(wvalues)) if sum_ == 0: self._revert() return # Normalize wvalues = [_ / sum_ for _ in wvalues] # Fit green ratio into limits green_min, green_max = self.limits[2], self.limits[3] wvalues[2] = self.round(fit_into(wvalues[2], green_min, green_max)) if wvalues[1] == 0: ratio = self.limits[1] else: ratio = fit_into(wvalues[0] / wvalues[1], self.limits[0], self.limits[1]) # Normalize the rest rest = 1 - wvalues[2] if ratio == float("inf"): wvalues[0] = rest wvalues[1] = 0 else: wvalues[1] = self.round(rest / (1.0 + ratio)) wvalues[0] = rest - wvalues[1] self.set_value(wvalues)
def __init__(self, parent, info, value): """ Parameters: parent (tk.Frame): The Tkinter parent of this widget. info (dict): Contains specifications for the model parameter. value: Initial value for the entry box. """ tk.Entry.__init__(self, parent, width=6) # Set the maximally allowed input length for before and after decimal if info["range"][1] != float("inf"): self.maxlen = [len(str(int(info["range"][1]))), info["roundto"]] else: self.maxlen = [float("inf"), info["roundto"]] def is_okay(value): """Validate whether entered value is permissible.""" if value in ["", "."]: # Allow empty string and single decimal point return True try: # Make sure the value can be converted to a valid float float(value) except ValueError: return False # Restrict the length of input before and after decimal splitted = value.split(".") if any( len(splitted[i]) > self.maxlen[i] for i in range(len(splitted))): return False return True # Register validation function vcmd = (self.register(is_okay), '%P') self.config(validate="all", validatecommand=vcmd) # If no range restriction is specified, at least must be possitive if "range" in info: self.fit_n_round = lambda x: round(fit_into(x, *info["range"]), info["roundto"]) else: self.fit_n_round = lambda x: round(fit_into(x, 0., float("inf")), info["roundto"]) # Check and update value following these actions self.bind('<Return>', self._check_value) self.bind('<FocusOut>', self._check_value) # Initiate value self.value = 0. self.set_value(value)
def update_value(self, event=None): temp = self.entry.get() try: temp=float(temp) except: self.set_value(self.value) return self.set_value(fit_into(temp, self.lowerbound, self.upperbound))
def __init__(self, parent, text, info, value, small_size=False): """ Parameters: parent (tk.Frame): The Tkinter parent of this widget. text (str): Name of the parameter to be displayed. info (dict): Contains specifications for the main parameter. value: Initial value for the main parameter. """ if small_size: length = 100 width = 9 font = EDIT_COLOR_FONT else: length = 150 width = 20 font = None tk.Frame.__init__(self, parent) # Set the maximally allowed input length for before and after decimal if info["range"][1] != float("inf"): self.maxlen = [len(str(int(info["range"][1]))), info["roundto"]] else: self.maxlen = [float("inf"), info["roundto"]] # Make label widget label = tk.Label(self, text=text, width=width) label.grid(row=0, column=0) if font is not None: label.config(font=font) # Set rounding, resolution of scale widget, lower and upper bounds self.round = lambda x: round(x, info["roundto"]) resolution = info["resolution"] from_, to = info["range"] self.fit_into = lambda x: fit_into(x, from_, to) # Register validation function vcmd = (self.register(self._is_okay), '%P') # Make entry widget self.entry = tk.Entry(self, width=6, validate="all", validatecommand=vcmd) self.entry.grid(row=0, column=1) # Make scale (slider) widget self.scale = tk.Scale(self, from_=from_, to=to, resolution=resolution, orient=tk.HORIZONTAL, sliderlength=15, width=15, length=length, command=self._update_entry, showvalue=0) self.scale.grid(row=0, column=2, padx=5) # Check and update value following these actions self.entry.bind('<Return>', self._update_scale) self.entry.bind('<FocusOut>', self._update_scale) # Group widgets and set layout self.widgets = [label, self.entry] for each in self.widgets: each.config(fg=EDIT_BODY_COLOR, font=EDIT_BODY_FONT) # Initiate value self.set_value(value)