예제 #1
0
    class test_gui(tk.Tk):
        def __init__(self, args, picker_type):
            tk.Tk.__init__(self)
            self.picker_type = picker_type
            self.title("test")
            self.geometry(f"{WIDTH}x{HEIGHT}")
            f = Frame(self)
            f.pack(expand=1, fill="both")
            self.l = Label(f, anchor="center")
            self.l.pack(side="top", expand=1, fill="both")
            if args.file:
                text = "Pick a file!"
            elif args.dir:
                text = "Pick a folder!"
            else:  #Not used
                text = "Pick something!"

            Button(
                f,
                text=text,
                command=lambda: threader.add_thread(self.get_input
                                                    )  #Lambda function to 
            ).pack(expand=0, side="bottom")

        def get_input(self):
            dialog = self.picker_type(self)  #Make the dialog window
            selection = dialog.get_input()  #
            self.l.configure(text=selection)
예제 #2
0
        def save(event=None):
            name = name_entry.get().strip()
            if not mailbox:
                # new mailbox
                i = self.b_add.grid_info()['row']
                self.b_add.grid_configure(row=i + 1)
                c = Checkbutton(self.frame)
                c.state(('selected',))
                c.grid(row=i, column=0, pady=4, padx=(4, 0))
                l = Label(self.frame, text=name)
                l.grid(row=i, column=1, padx=4, pady=4)
                b_edit = Button(self.frame, image=self.im_edit, width=1,
                                command=lambda m=name: self.mailbox_info(m))
                b_edit.grid(row=i, column=2, padx=4, pady=4)
                b_del = Button(self.frame, image=self.im_del, width=1,
                               command=lambda m=name: self.del_mailbox(m))
                b_del.grid(row=i, column=3, padx=4, pady=4)
                self.mailboxes[name] = [c, l, b_edit, b_del]
            elif name != mailbox:
                # change name of mailbox
                os.remove(os.path.join(LOCAL_PATH, mailbox))
                c, l, b_edit, b_del = self.mailboxes[mailbox]
                del(self.mailboxes[mailbox])
                l.configure(text=name)
                b_edit.configure(command=lambda m=name: self.mailbox_info(m))
                b_del.configure(command=lambda m=name: self.del_mailbox(m))
                self.mailboxes[name] = [c, l, b_edit, b_del]

            encrypt(name, self.pwd, server_entry.get().strip(),
                    login_entry.get().strip(), password_entry.get().strip(),
                    folder_entry.get().strip())
            top.destroy()
예제 #3
0
 class PredictionWidget(Frame):
     """Shows a prediction to the user."""
     def __init__(self, master):
         """Make boxes, register callbacks etc."""
         Frame.__init__(self, master)
         self.active_category = StringVar()
         self.bind("<Configure>", self.onResize)
         self.date = None
         self.predictor = Predictor()
         self.category_buttons = self.createCategoryButtons()
         self.text = Label(self, justify=CENTER, font="Arial 14")
     def createCategoryButtons(self):
         """Create the buttons used to choose category. Return them."""
         result = []
         icons = self.readIcons()
         categories = self.predictor.categories()
         for i in categories:
             if i in icons:
                 icon = icons[i]
             else:
                 icon = icons["= default ="]
             category_button = Radiobutton(self, image=icon,
                  variable=self.active_category, value=i, indicatoron=False,
                  width=icon_size, height=icon_size, command=self.update)
             category_button.image_data = icon
             result.append(category_button)
         self.active_category.set(categories[0])
         return result
     def readIcons(self):
         """Read the gui icons from disk. Return them."""
         result = {}
         categories = open(nextToThisFile("icons.txt")).read().split("\n\n")
         for i in categories:
             category_name, file_data = i.split("\n", maxsplit=1)
             image = PhotoImage(data=file_data)
             result[category_name] = image
         return result
     def onResize(self, event):
         """Rearrange the children when the geometry of self changes."""
         if event.widget == self:
             center = (event.width / 2, event.height / 2)
             radius = min(center) - icon_size / 2
             self.text.place(anchor=CENTER, x=center[0], y=center[1])
             for i, j in enumerate(self.category_buttons):
                 turn = 2 * math.pi
                 angle = turn * (1 / 4 - i / len(self.category_buttons))
                 j.place(anchor=CENTER,
                         x=center[0] + math.cos(angle) * radius,
                         y=center[1] - math.sin(angle) * radius)
     def update(self, date=None):
         """Change contents based on circumstances. Set date if given."""
         if date:
             self.date = date
         if self.date:
             predictions = self.predictor.predict(self.date)
             prediction = predictions[self.active_category.get()]
             prediction = textwrap.fill(prediction, width=20)
         else:
             prediction = ""
         self.text.configure(text=prediction)
예제 #4
0
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, name="frame")
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("Animation")
        self.pack(fill=BOTH, expand=True)
        self.i = 0
        self.img_names = ("one.png", "two.png", "three.png", "four.png",
                          "five.png", "six.png", "seven.png", "eight.png",
                          "nine.png")
        img = Image.open(self.img_names[self.i])
        num = ImageTk.PhotoImage(img)
        self.label = Label(self, image=num)
        self.label.pack(pady=30)
        # reference must be stored
        self.label.image = num
        self.after(DELAY, self.doCycle)

    def doCycle(self):
        self.i += 1
        if (self.i >= 9):
            return
        img = ImageTk.PhotoImage(Image.open(self.img_names[self.i]))
        self.label.configure(image=img)
        self.label.image = img
        self.after(DELAY, self.doCycle)
예제 #5
0
    def initItems(self):
        """Initialize all widgets here"""
        # An entry to enter feet value.
        self.feet_entry = Entry(self, width=7)
        self.feet_entry.grid(column=2, row=1, sticky=(W, E))
        # A label to display translated meters.
        self.meters_lbl = Label(self, textvariable=self.meters_value)
        self.meters_value.set(0)
        self.meters_lbl.grid(column=2, row=2, sticky=(W, E))
        # Different labels for text only.
        Label(self, text='feet').grid(column=3, row=1, sticky=W)
        Label(self, text='is equivalent to').grid(column=1, row=2, sticky=E)
        Label(self, text='meters').grid(column=3, row=2, sticky=W)
        # Button to calculate things.
        calc_btn = Button(self,
                          text='Calculate',
                          command=lambda: calculate(self))
        calc_btn.grid(column=3, row=3, sticky=W)

        # This widget is just for fun.
        # Also it shows how to get an event callback when Entry widget is modified
        def callback(str):
            print(str.get())

        entry_str = StringVar()
        entry_str.trace('w',
                        lambda name, index, mode, str=entry_str: callback(str))
        self.entry_widg = Entry(self, width=10, textvariable=entry_str)
        self.entry_widg.grid(column=1, row=4, sticky=(W, E))

        # A really simple way to change label text:
        test_lbl = Label(self)
        test_lbl.grid(column=3, row=4, sticky=E)
        test_lbl['text'] = 'hello!'

        # Handling label's events
        ev_lbl = Label(self, text='Do something with me...', width=30)
        ev_lbl.grid(column=1, row=5, columnspan=2, rowspan=2)
        ev_lbl.bind('<Enter>',
                    lambda e: ev_lbl.configure(text='Moved mouse inside'))
        ev_lbl.bind('<Leave>',
                    lambda e: ev_lbl.configure(text='Moved mouse outside'))
        ev_lbl.bind(
            '<1>',
            lambda e: ev_lbl.configure(text='Clicked left mouse button!'))
        ev_lbl.bind(
            '<Double-1>', lambda e: ev_lbl.configure(
                text='Double clicked left mouse button!'))

        # Configure pads for all grid cells
        for child in self.winfo_children():
            child.grid_configure(padx=5, pady=5)
        # As default, entry is focused
        self.feet_entry.focus()
예제 #6
0
class MainUI(Frame):
    def __init__(self, fresco_xyz: FrescoXYZ, z_camera: ZCamera,
                 fresco_camera: FrescoCamera):
        super().__init__()

        self.fresco_xyz = fresco_xyz
        self.z_camera = z_camera
        self.fresco_camera = fresco_camera
        self.image_label = None

        self.init_ui()

    def init_ui(self):
        self.master.title("Fresco Labs")

        self.pack(fill=BOTH, expand=1)

        steps_manual_controller = StepsManualController(
            self, fresco_xyz=self.fresco_xyz)
        steps_manual_controller.place(x=0, y=0)

        macro_steps_controller = MacroStepsManualController(
            self, fresco_xyz=self.fresco_xyz)
        macro_steps_controller.place(x=0, y=200)

        initialization_controller = Initialization(self,
                                                   fresco_xyz=self.fresco_xyz)
        initialization_controller.place(x=0, y=360)

        auto_focus_controller = AutoFocus(self,
                                          fresco_xyz=self.fresco_xyz,
                                          z_camera=self.z_camera)
        auto_focus_controller.place(x=0, y=540)

        functions_controller = Functions(self,
                                         fresco_xyz=self.fresco_xyz,
                                         z_camera=self.z_camera)
        functions_controller.place(x=0, y=640)

        image_array = self.fresco_camera.get_current_image()
        camera_image = ImageTk.PhotoImage(image=Image.fromarray(image_array))
        self.image_label = Label(self, image=camera_image)
        self.image_label.image = camera_image
        self.image_label.place(x=300, y=50)
        self.after(2000, self.update_image)

    def update_image(self):
        image_array = self.fresco_camera.get_current_image()
        camera_image = ImageTk.PhotoImage(image=Image.fromarray(image_array))
        self.image_label.configure(image=camera_image)
        self.image_label.image = camera_image
        self.after(10, self.update_image)
예제 #7
0
파일: Module.py 프로젝트: matty-l/Lilac
	def average_normals( self ):
		""" Applies Gouraud normalization to the module		
		"""
		# Set up updater
		top = Toplevel()
		pb = Progressbar(top,orient ="horizontal",length = 200, mode ="determinate")
		pb['maximum'] = len(self.__elements__)
		pb['value'] = 10
		pb.grid(row=0,column=0)
		tx = Label(top)
		tx.grid(row=1,column=0)
		top.update_idletasks()
		top.lift()
		t0 = time.time()
				
		# run the loop, if we're visible and phong shading
		if not self.invisible == 'gouroud':
			try:
				buf = np.array([0,0,0,1])
				for i,polygon in enumerate(self.__elements__):
					if not ispoly(polygon): continue
					polygon._onorms = np.array([polygon.normals.astype(float)+buf for i in range(len(polygon.coordinates))])
					
					# Update the user as to what's going on
					if i % 50 == 0 and i > 0:
						pb['value'] = i
						tmp = i/len(self.__elements__)
						estimation =  int(tmp*(time.time()-t0) * (1-tmp)/tmp)
						tx.configure(text=str(int(100*i/len(self.__elements__)))+"%"+' Estimated time: '+str(estimation)+'s' )
						top.update_idletasks()
						
					for c,coordinate in enumerate(polygon.coordinates):
						for j,opolygon in enumerate(self.__elements__):
							if i == j or not ispoly(opolygon): continue
							for k,ocoordinate in enumerate(opolygon.coordinates):
								if all(coordinate == ocoordinate): # same vertex, finally
									polygon._onorms[c] += (opolygon.normals+buf)
					polygon._onorms /= polygon._onorms[:,3,None]
					
				for polygon in self.__elements__:
					if ispoly(polygon): 
						polygon.normals = polygon._onorms
						del polygon._onorms
			except IndexError as ie: pass
		
		top.destroy()
		
		if self.invisible == 'gouroud':
			self.invisible = False
		return self # for chaining
예제 #8
0
class Tooltip(Toplevel):
    def __init__(self, parent, **kwargs):
        Toplevel.__init__(self, parent)
        if 'title' in kwargs:
            self.title(kwargs['title'])
        self.transient(parent)
        self.attributes('-type', 'tooltip')
        self.attributes('-alpha', kwargs.get('alpha', 0.8))
        self.overrideredirect(True)
        self.configure(padx=kwargs.get('padx', 4))
        self.configure(pady=kwargs.get('pady', 4))

        self.style = Style(self)
        bg = kwargs.get('background', 'black')
        self.configure(background=bg)
        self.style.configure('tooltip.TLabel',
                             foreground=kwargs.get('foreground', 'gray90'),
                             background=bg,
                             font='TkDefaultFont 9 bold')

        self.im = kwargs.get('image', None)
        self.label = Label(self,
                           text=kwargs.get('text', ''),
                           image=self.im,
                           style='tooltip.TLabel',
                           compound=kwargs.get('compound', 'left'))
        self.label.pack()

    def configure(self, **kwargs):
        if 'text' in kwargs:
            self.label.configure(text=kwargs.pop('text'))
        if 'image' in kwargs:
            self.label.configure(image=kwargs.pop('image'))
        if 'background' in kwargs:
            self.style.configure('tooltip.TLabel',
                                 background=kwargs['background'])
        if 'foreground' in kwargs:
            fg = kwargs.pop('foreground')
            self.style.configure('tooltip.TLabel', foreground=fg)
        if 'alpha' in kwargs:
            self.attributes('-alpha', kwargs.pop('alpha'))
        Toplevel.configure(self, **kwargs)
예제 #9
0
    def initUI(self):
        self.master.title("Fawkes")
        self.master.configure(bg='white')
        self.pack(fill=BOTH, expand=1)

        # fawkes image
        canvas = Canvas(self, width=110, height=150)
        orig = Image.open("fawkes_mask.jpg")
        resized = orig.resize((110,150), Image.ANTIALIAS)
        img = ImageTk.PhotoImage(resized)
        canvas.create_image(0,0, image=img, anchor=NW)
        canvas.image = img
        canvas.pack()
        

        # open button
        btn_Open = Button(self,
                          text='Choose image(s) to cloak',
                          width=25,
                          command=self.select_path)
        btn_Open.pack()

        # run button
        btn_Run = Button(self,
                         text='Cloak images',
                         width=25,
                         command=lambda: thread_it(self.my_fawkes.run_protection, self.img_paths))
        btn_Run.pack()

        # # save button
        # btn_Save = Button(self,
        #                   text='Save cloaked image(s)',
        #                   width=25,
        #                   command=self.save_images)
        # btn_Save.pack()
        
        # Progress info
        Label_Show = Label(self,
                           textvariable=self.var,
                           font=('Arial', 13), width=50)
        Label_Show.configure(anchor="center")
        Label_Show.pack()
예제 #10
0
    def display_evts(self):
        def wrap(event):
            l = event.widget
            if l.master.winfo_ismapped():
                l.configure(wraplength=l.winfo_width())

        week = self.master.get_next_week_events()
        date_today = datetime.now().date()
        today = date_today.strftime('%A')
        children = list(self.display.children.values())
        for ch in children:
            ch.destroy()

        for day, evts in week.items():
            if day == today:
                text = _('Today')
            else:
                text = day.capitalize()
            Label(self.display, text=text,
                  style='day.Events.TLabel').grid(sticky='w',
                                                  pady=(4, 0),
                                                  padx=4)
            for ev, desc in evts:
                if desc.strip():
                    tf = ToggledFrame(self.display,
                                      text=ev.strip(),
                                      style='Events.TFrame')
                    l = Label(tf.interior,
                              text=desc.strip(),
                              style='Events.TLabel')
                    l.pack(padx=4, fill='both', expand=True)
                    l.configure(wraplength=l.winfo_width())
                    l.bind('<Configure>', wrap)
                    tf.grid(sticky='we', pady=2, padx=(8, 4))
                else:
                    l = Label(self.display,
                              text=ev.strip(),
                              style='Events.TLabel')
                    l.bind('<Configure>', wrap)
                    l.grid(sticky='ew', pady=2, padx=(21, 10))
예제 #11
0
파일: main.py 프로젝트: DutytoDevelop/Pyxe
        def about_popup():
            top = Toplevel()
            top.title("About Me")
            top.geometry = "500x400"
            top.resizable(False, False)
            top.iconbitmap(pyxe_favicon)

            about_labelframe = LabelFrame(top,
                                          labelanchor="nw",
                                          text="Developer Profile:",
                                          width=600,
                                          height=200,
                                          font=('', 10))
            about_labelframe.pack(fill="both", expand=True, padx=3, pady=3)

            profile_photo = Image.open(
                resource_path(
                    r"pyxe_resources\data\DutytoDevelop_Profile_Pic.png"))
            resized = profile_photo.resize((150, 150))
            profile_photo_resize = ImageTk.PhotoImage(resized)

            canvas = Canvas(about_labelframe, height=150, width=150)
            canvas.create_image(75, 75, image=profile_photo_resize)
            canvas.image = profile_photo_resize
            canvas.grid(row=1, column=1, padx=3, pady=(3, 0), sticky="nsew")

            about_label = Label(
                about_labelframe,
                text="Name: Nicholas H.\nGitHub: DutytoDevelop",
                font=('', 10, 'bold'))
            about_label.configure(anchor="center", justify='center')
            about_label.grid(row=2,
                             column=1,
                             padx=3,
                             pady=(0, 3),
                             sticky="nsew")
            return
예제 #12
0
class StatusBar(Frame):
    def __init__(self, master, progressMax=100, **kwargs):
        Frame.__init__(self, master, **kwargs)

        self.label = Label(self, text="Ready...")
        self.label.pack(anchor=Tkc.W)

        self.progressVar = IntVar()
        self.progress = Progressbar(self,
                                    mode='determinate',
                                    maximum=abs(progressMax),
                                    length="150",
                                    variable=self.progressVar)

    def showText(self, message):
        self.label.configure(text=message)
        self.progress.stop()
        self.progress.pack_forget()
        self.label.pack(anchor=Tkc.W)

    def showProgress(self):
        self.progress.configure(mode='determinate')
        self.label.pack_forget()
        self.progress.pack(anchor=Tkc.W)
        self.update_idletasks()

    def setProgress(self, value):
        self.progressVar.set(value)
        self.update_idletasks()

    def setProgressMax(self, value):
        self.progress.configure(maximum=abs(value))

    def showActivity(self):
        self.progress.configure(mode='indeterminate')
        self.progress.start()
        self.showProgress()
예제 #13
0
class ShanksApp():
    """Tkinter GUI application with interactive calcualtion of dicrepete logarithm."""

    is_start = True

    i = 0
    a = 0
    b = 0
    p = 0

    x1 = 0
    x2 = 0

    output_ind = 0
    max_ind = -1

    line0 = 'm ='
    line1 = 'Step number i      '
    line2 = '----------------------------------'
    line3 = 'Big step = a^(i*m)  '
    line4 = 'Small step = b*a^i '

    def create_table(self) -> str:
        """Create string with output layout (algorithm steps)."""

        return self.line0 + '\n' + self.line1 + '\n' + self.line2 + '\n' + self.line3 + '\n' + self.line4

    def create_output(self) -> None:
        """Initialization of textual output after correctly specified a, b, p.

        Mainly string operations. Assign values to class instance attributes."""

        self.x1, self.x2, giant_list, baby_list = self.run_shanks_algo(
            self.a, self.b, self.p)

        m = ceil(sqrt(self.p))
        self.max_ind = m + len(baby_list)
        self.output_list = []

        self.line0 = f"PROBLEM: {self.a}^x = {self.b} mod {self.p}, find x.\nSOLUTION: Number of big steps is {m}."
        self.line1 = "Step number i               "
        for i in range(m):
            self.line1 += f"| {i}  "
        self.line2 = '-----------------------' + '-' * 4 * m
        self.line3 = f'Big step = {self.a}^(i*{m})         '
        self.line3 = self.line3[:27]
        self.line4 = f'Small step = {self.b}*{self.a}^(-i)    '
        self.line4 = self.line4[:27]

        self.output_list.append(self.create_table())

        for i in range(m):
            temp = f"| {giant_list[i % len(giant_list)]}  "
            self.line3 += temp[:5]
            self.output_list.append(self.create_table())

        for i in range(len(baby_list)):
            temp = f"| {baby_list[i]}  "
            self.line4 += temp[:5]
            self.output_list.append(self.create_table())

        self.line0 = f"PROBLEM: {self.a}^x = {self.b} mod {self.p}, find x.\nSOLUTION: Number of big steps is {m}."
        self.line1 = "Step number i               "
        for i in range(m):
            self.line1 += f"| {i}  "
        self.line2 = '-----------------------' + '-' * 4 * m
        self.line3 = f'Big step = {self.a}^(i*{m})         '
        self.line3 = self.line3[:27]
        self.line4 = f'Small step = {self.b}*{self.a}^(-i)  '
        self.line4 = self.line4[:25]

    def exp(self, a: int, b: int, p: int) -> int:
        """Recursive exponentiation a^b modulo p."""

        if b == 0:
            return 1
        res = self.exp(a, int(b / 2), p)
        res = (res * res) % p
        if b % 2 == 1:
            res = (res * a) % p
        return res

    def is_prime(self, n: int) -> bool:
        """Checks if n is prime."""
        return n > 1 and all(n % i for i in islice(count(2), int(sqrt(n) - 1)))

    def is_generator(self, a: int, p: int) -> bool:
        """Checks if A generate whole cyclic multiplication group of order P."""

        gen_set = set()
        curr = 1
        gen_set.add(curr)
        for i in range(p - 2):
            curr = (curr * a) % p
            if curr in gen_set:
                return False
            gen_set.add(curr)
        return True

    def validate_input(self) -> None:
        """Validate input values for a, b, p and prompt corresponding errors if some constraints are not satisfiied.

        1. Converts a, b, p to integers, prompt error if not successful
        2. Checks a, b, p to be positive
        3. Checks p to be prime and not exceed p_limit.
        4. Checks if a generates full cyclic group of order p under multiplication
        """

        p_limit = 10000000

        try:
            self.p = int(self.entry_p.get())
            self.a = int(self.entry_a.get())
            self.b = int(self.entry_b.get())
        except Exception:
            self.lbl0.config(text=f"Error! Input should be numeric!",
                             foreground="red")
            return

        if self.is_prime(self.p) and self.p < p_limit and 0 < self.a and self.a < self.p and 0 < self.b and \
                        self.b < self.p:
            self.create_output()
            if self.is_generator(self.a, self.p):
                self.lbl0.config(foreground="black")
                self.update_grid_start_algo()
            else:
                self.lbl0.config(
                    text=f"Error! a={self.a} should generate the whole group!",
                    foreground="red")
        else:
            bool_list = [
                self.is_prime(self.p), self.p < p_limit, 0 < self.a,
                self.a < self.p, 0 < self.b, self.b < self.p
            ]
            str_list = [
                'p should be prime', f'p < {p_limit}', '0 < a', 'a < p',
                '0 < b', 'b < p'
            ]
            err = 'Error! Following constraints should be satisfied: '
            flag = -1  # controls state of error text variable
            for bool_val, err_str in zip(bool_list, str_list):
                if not bool_val:
                    # several possibilities of updating err
                    if flag in [0, 2]:
                        err += '; '

                    err += err_str

                    if flag in [-1, 1]:
                        flag += 1

                    if flag == 0 and len(err) > 66:
                        err += '\n'
                        flag = 1

            self.lbl0.configure(text=err, foreground="red")

    def run_shanks_algo(self, a: int, b: int,
                        p: int) -> Tuple[int, int, List, List]:
        """Main method for running shanks algorithm.

        Args:
            a: logarithm base
            b: result of power operation on a
            p: order of cyclic group

        Returns:
            self.x1: calculated value of giant step
            self.x2: calculated value of beby step
            giant_list: list with values of giant steps
            baby_list: list with values of baby steps
        """

        m = int(ceil(sqrt(p)))
        giant_dict = {}
        step = self.exp(a, m, p)

        baby_list = []
        giant_list = [1]

        # giant steps calculation
        last_val = 1
        for i in range(m):
            last_val = (last_val * step) % p
            giant_list.append(last_val)
            if last_val not in giant_dict:
                giant_dict[last_val] = i + 1

        # baby steps calculation, terminates when we match value in giant_dict
        last_val = b
        for i in range(m):
            baby_list.append(last_val)
            if last_val in giant_dict:
                self.x1 = giant_dict[last_val]
                self.x2 = i
                break
            last_val = (last_val * a) % p

        return self.x1, self.x2, giant_list, baby_list

    def update_grid_start(self) -> None:
        """Called on start or when Restart button was pressed.

        Destroys old layout elements and create new in the latter case."""

        if not self.is_start:
            self.frame0.destroy()
            self.frame1.destroy()
            self.frame2.destroy()
            self.frame3.destroy()

            try:
                self.frame4.destroy()
                self.frame5.destroy()
                self.frame6.destroy()
            except:
                pass

        self.is_start = False
        self.frame.pack(fill=BOTH, expand=True)

        self.frame0 = Frame(self.frame)
        self.frame0.pack(fill=X)

        self.lbl0 = Label(self.frame0,
                          text="Solving for x: a^x = b mod p. Enter a, b, p:",
                          width=60)
        self.lbl0.pack(side=LEFT, padx=20, pady=5)

        self.frame1 = Frame(self.frame)
        self.frame1.pack(fill=X)

        self.lbl1 = Label(self.frame1, text="Logarithm base a", width=18)
        self.lbl1.pack(side=LEFT, padx=20, pady=5)

        self.entry_a = Entry(self.frame1)
        self.entry_a.pack(fill=X, padx=5, expand=True)

        self.frame2 = Frame(self.frame)
        self.frame2.pack(fill=X)

        self.lbl2 = Label(self.frame2, text="Logarithm argument b", width=18)
        self.lbl2.pack(side=LEFT, padx=20, pady=5)

        self.entry_b = Entry(self.frame2)
        self.entry_b.pack(fill=X, padx=5, expand=False)

        self.frame3 = Frame(self.frame)
        self.frame3.pack(fill=X)

        self.lbl3 = Label(self.frame3, text="Prime number p", width=18)
        self.lbl3.pack(side=LEFT, padx=20, pady=5)

        self.entry_p = Entry(self.frame3)
        self.entry_p.pack(fill=X, padx=5, expand=True)

        self.frame4 = Frame(self.frame)
        self.frame4.pack(fill=X)

        self.input_button = Button(self.frame4,
                                   text="Set",
                                   command=lambda: self.validate_input())
        self.input_button.pack(side=LEFT, padx=20, pady=0)

        self.input_button = Button(self.frame4,
                                   text="Restart",
                                   command=lambda: self.update_grid_start())
        self.input_button.pack(side=LEFT, padx=0, pady=0)

        self.input_button = Button(self.frame4,
                                   text="Exit",
                                   command=lambda: self.update_grid_exit())
        self.input_button.pack(side=LEFT, padx=0, pady=0)

    def update_grid_start_algo(self) -> None:
        """Called when "Set button" clicked while all parameters of algorithm specified correctly a, b, p.

        Clears old layout elements, set textual output and new buttons. """

        self.output_ind = 0

        self.lbl0.configure(text=self.create_table())
        self.frame1.destroy()
        self.frame2.destroy()
        self.frame3.destroy()
        self.frame4.destroy()

        self.frame3 = Frame(self.frame)
        self.frame3.pack(fill=X)

        self.input_button = Button(
            self.frame3,
            text="<< Previous step",
            command=lambda: self.update_grid_previous_step())
        self.input_button.pack(side=LEFT, padx=20, pady=0)

        self.input_button = Button(
            self.frame3,
            text="Next step >>",
            command=lambda: self.update_grid_next_step())
        self.input_button.pack(side=LEFT, padx=0, pady=0)

        self.frame4 = Frame(self.frame)
        self.frame4.pack(fill=X)

        self.input_button = Button(self.frame4,
                                   text="Restart",
                                   command=lambda: self.update_grid_start())
        self.input_button.pack(side=LEFT, padx=20, pady=0)

        self.input_button = Button(self.frame4,
                                   text="Exit",
                                   command=lambda: self.update_grid_exit())
        self.input_button.pack(side=LEFT, padx=60, pady=0)

    def update_grid_next_step(self) -> None:
        """Called when "Next Step" button pressed during the algorithm run."""

        if self.output_ind == self.max_ind:
            upd_txt = f"Congratulations, we are done! m = {ceil(sqrt(self.p))}, answer: "
            upd_txt += f"x = {ceil(sqrt(self.p))} * {self.x1} - {self.x2} = {ceil(sqrt(self.p)) * self.x1 - self.x2}\n"
            self.lbl0.configure(text=upd_txt + self.output_list[self.max_ind])
        else:
            self.output_ind += 1
            self.lbl0.configure(text=self.output_list[self.output_ind])

    def update_grid_previous_step(self) -> None:
        """Called when "Previous Step" button is pressed. Updates state of layout and layout itself."""

        if self.output_ind != 0:
            self.output_ind -= 1
            self.lbl0.configure(text=self.output_list[self.output_ind])

    def update_grid_exit(self) -> None:
        """Called if "Exit" button is pressed. Closes tkinter's window. """

        self.window.destroy()

    def run_app(self) -> None:
        """Entry point to tkinter app."""

        self.window = Tk()
        self.window.title("Baby-step giant-step algorithm")
        self.window.geometry("500x180")

        self.frame = Frame()
        self.update_grid_start()
        self.frame.mainloop()
예제 #14
0
class TtkScale(Scale):
    def __init__(self,
                 parent,
                 length=0,
                 from_=0,
                 to=255,
                 orient='vertical',
                 variable=0,
                 digits=None,
                 tickinterval=None,
                 command=None,
                 style=None,
                 showvalue=True,
                 resolution=1):

        self.from_ = from_
        self.to = to
        self.variable = variable
        self.length = length
        self.command = command
        self.parent = parent

        super().__init__(parent,
                         length=length,
                         from_=from_,
                         to=to,
                         orient=orient,
                         variable=variable,
                         command=command,
                         style=style)

        self.digits = digits
        self.tickinterval = tickinterval
        self.showvalue = showvalue
        self.resolution = resolution

        # set sliderlength
        st = Style(self)
        self.bw_val = bw_val = st.lookup('Vertical.Scale.trough',
                                         'borderwidth')
        self.sliderlength = sliderlength = 32

        if showvalue:
            self.configure(command=self.display_value)

        def_font = font.nametofont('TkDefaultFont')
        # if from_ more than to swap values
        if from_ < to:
            pass
        else:
            from_, to = to, from_

        data = np.arange(from_,
                         (to + 1 if tickinterval >= 1 else to + tickinterval),
                         tickinterval)
        self.data = data = np.round(data, 1)
        range_vals = tuple(data)
        len_rvs = len(range_vals)
        lspace = def_font.metrics('linespace')
        len_rvs = len(range_vals)
        data_size = len_rvs * lspace

        space_size = len_rvs * 3
        sizes = data_size + space_size
        min_len = (sizes if sizes % 50 == 0 else sizes + 50 - sizes % 50)
        self.len_val = len_val = min_len if length < min_len else length
        self.configure(length=len_val)

        self.rel_min = rel_min = (sliderlength / 2 + bw_val) / len_val
        self.rel_max = rel_max = 1 - (sliderlength / 2 - bw_val) / len_val
        if range_vals[-1] == to:
            pass
        else:
            max_rv = range_vals[-1]
            self.mult_y = mult_y = ((max_rv - from_) * rel_max / (to - from_))

        self.bind("<Button-1>", self.resolve)

        self.build(from_, to, rel_min, rel_max, range_vals, len_rvs)

    def build(self, from_, to, rel_min, rel_max, range_vals, len_rvs):

        for i, rv in enumerate(range_vals):
            item = Label(self.parent, text=rv)
            item.place(
                in_=self,
                bordermode='outside',
                rely=(rel_min + i / (len_rvs - 1) *
                      ((rel_max if range_vals[-1] == to else self.mult_y) -
                       rel_min)),
                relx=1,
                anchor='w')

        if self.showvalue:
            self.disp_lab = Label(self.parent, text=self.get())
            rel_y = self.convert_to_rely(float(
                self.get()))  #, textvariable = self.act_val)
            self.disp_lab.place(in_=self,
                                bordermode='outside',
                                rely=rel_y,
                                relx=0,
                                anchor='e')

    def convert_to_rely(self, curr_val):
        return ((curr_val - self.from_) * (self.rel_max - self.rel_min) /
                (self.to - self.from_) + self.rel_min)

    def convert_to_acty(self, curr_val):
        y_max = self.rel_max * self.len_val
        y_min = self.rel_min * self.len_val
        return ((curr_val - self.from_) * (y_max - y_min) /
                (self.to - self.from_) + y_min)

    def display_value(self, value):
        # position (in pixel) of the center of the slider
        rel_y = self.convert_to_rely(float(value))
        self.disp_lab.config(text=value)  # text=""
        self.disp_lab.place_configure(rely=rel_y)
        digits = self.digits
        self.disp_lab.configure(text=f'{float(value):.{dig_val}f}')
        # if your python is not 3.6 or above use the following 2 lines
        #   instead of the line above
        #my_precision = '{:.{}f}'.format
        #self.disp_lab.configure(text=my_precision(float(value), digits))

    def resolve(self, evt):
        resolution = self.resolution
        if resolution < 1 or self.tickinterval < 1:
            pass
        else:
            value = self.get()
            curr_y = self.convert_to_acty(value)
            if evt.y < curr_y - self.sliderlength / 2:
                self.set(value - resolution + 1)
            elif evt.y > curr_y + self.sliderlength / 2:
                self.set(value + resolution - 1)
예제 #15
0
파일: tooltip.py 프로젝트: j4321/Scheduler
class Tooltip(Toplevel):
    """ Tooltip class """
    def __init__(self, parent, **kwargs):
        """
            Create a tooltip with given parent.

            KEYWORD OPTIONS

                title, alpha, padx, pady, font, background, foreground, image, text

        """
        Toplevel.__init__(self, parent)
        if 'title' in kwargs:
            self.title(kwargs['title'])
        self.transient(parent)
        self.attributes('-type', 'tooltip')
        self.attributes('-alpha', kwargs.get('alpha', 0.75))
        self.overrideredirect(True)
        self.configure(padx=kwargs.get('padx', 4))
        self.configure(pady=kwargs.get('pady', 4))

        self.font = Font(self, kwargs.get('font', ''))

        self.style = Style(self)
        if 'background' in kwargs:
            bg = kwargs['background']
            self.configure(background=bg)
            self.style.configure('tooltip.TLabel', background=bg)
        if 'foreground' in kwargs:
            self.style.configure('tooltip.TLabel',
                                 foreground=kwargs['foreground'])

        self.im = kwargs.get('image', None)
        self.label = Label(self,
                           text=kwargs.get('text', ''),
                           image=self.im,
                           style='tooltip.TLabel',
                           font=self.font,
                           wraplength='6c',
                           compound=kwargs.get('compound', 'left'))
        self.label.pack()

    def configure(self, **kwargs):
        if 'text' in kwargs:
            self.label.configure(text=kwargs.pop('text'))
        if 'image' in kwargs:
            self.label.configure(image=kwargs.pop('image'))
        if 'background' in kwargs:
            self.style.configure('tooltip.TLabel',
                                 background=kwargs['background'])
        if 'foreground' in kwargs:
            fg = kwargs.pop('foreground')
            self.style.configure('tooltip.TLabel', foreground=fg)
        if 'alpha' in kwargs:
            self.attributes('-alpha', kwargs.pop('alpha'))
        if 'font' in kwargs:
            font = Font(self, kwargs.pop('font'))
            self.font.configure(**font.actual())
        Toplevel.configure(self, **kwargs)

    def config(self, **kw):
        self.configurere(**kw)

    def cget(self, key):
        if key in ['text', 'image']:
            return self.label.cget(key)
        elif key == 'font':
            return self.font
        elif key == 'alpha':
            return self.attributes('-alpha')
        elif key in ['foreground', 'background']:
            return self.style.lookup('tooltip.TLabel', key)
        else:
            return Toplevel.cget(self, key)
예제 #16
0
class ExpenseTab:

    # Use for option selection for currency
    currency_code_list = [
        'AUD', 'CAD', 'CHF', 'CNY', 'DKK', 'EUR', 'GBP', 'INR', 'JPY', 'LBP',
        'NOK', 'NZD', 'MAD', 'USD', 'SEK', 'TND'
    ]

    convert_to_EUR = [
        0.62, 0.65, 0.93, 0.13, 0.13, 1, 1.11, 0.011, 0.008, 0.00056, 0.094,
        0.58, 0.092, 0.85, 0.098, 0.31
    ]

    def __init__(self, tab_control, expense_controller, user_controller,
                 username):
        """Initializes the expense tab and creates all elements of the visual interface"""
        # Input for the expense interface
        self.expense_controller = expense_controller
        self.user_controller = user_controller
        self.username = username

        self.category_list = self.user_controller.get_categories(self.username)

        self.chosen_currency = StringVar()
        self.chosen_category = StringVar()
        self.description = StringVar()
        self.price = StringVar()
        self.price_in_euro = StringVar()
        self.date = StringVar()

        self.currency_EUR_dict = {
            self.currency_code_list[i]: self.convert_to_EUR[i]
            for i in range(len(self.currency_code_list))
        }

        try:
            # try to load latest currency conversion codes through an API
            response = requests.get('https://api.ratesapi.io/api/latest')
            for c in self.currency_code_list:
                try:
                    # try to load conversion rate for specific currency
                    self.currency_EUR_dict[c] = 1 / response.json()['rates'][c]
                except KeyError:
                    # if not available (e.g. LBP) the hard-coded conversion rate is used
                    pass
        except requests.exceptions.RequestException as e:
            # if no internet connection is available or the server is down, hard-coded conversion rates are used
            print(e)

        self.id_expenseItem = 0
        total = self.expense_controller.total_expenses(self.username)
        self.sum_expenses = StringVar(value=f"Sum of all expenses: {total}€")
        self.budget_message = StringVar()

        self.expense_tab = ttk.Frame(tab_control)
        tab_control.add(self.expense_tab, text='Expenses')

        Label(self.expense_tab, text="New expense:",
              font='Helvetica 16 bold').grid(row=0,
                                             column=0,
                                             padx=15,
                                             pady=15,
                                             sticky='w')

        # DESCRIPTION
        Label(self.expense_tab, text="Description:").grid(row=1,
                                                          column=0,
                                                          padx=(15, 0),
                                                          pady=2,
                                                          sticky='w')
        Entry(self.expense_tab,
              textvariable=self.description).grid(row=1,
                                                  column=1,
                                                  pady=2,
                                                  sticky="ew")

        # CATEGORY
        Label(self.expense_tab, text="Category:").grid(row=1, column=2, pady=2)
        self.category_select = OptionMenu(self.expense_tab,
                                          self.chosen_category,
                                          self.category_list[0],
                                          *self.category_list)
        self.category_select.grid(row=1,
                                  column=3,
                                  padx=(0, 15),
                                  pady=2,
                                  sticky="ew")

        # PRICE
        Label(self.expense_tab, text="Price:").grid(row=2,
                                                    column=0,
                                                    padx=(15, 0),
                                                    pady=2,
                                                    sticky='w')
        Entry(self.expense_tab, textvariable=self.price).grid(row=2,
                                                              column=1,
                                                              pady=2,
                                                              sticky="ew")

        # CURRENCY OPTION
        Label(self.expense_tab, text="Currency:").grid(row=2, column=2, pady=2)
        OptionMenu(self.expense_tab, self.chosen_currency, self.currency_code_list[5], *self.currency_code_list)\
            .grid(row=2, column=3, padx=(0, 15), pady=2, sticky="ew")

        # DATE
        Label(self.expense_tab, text="Date:").grid(row=3,
                                                   column=0,
                                                   padx=(15, 0),
                                                   pady=2,
                                                   sticky='w')
        DateEntry(self.expense_tab,
                  background='darkblue',
                  foreground='white',
                  borderwidth=2,
                  textvariable=self.date,
                  date_pattern='dd/MM/yyyy').grid(row=3,
                                                  column=1,
                                                  pady=2,
                                                  sticky="ew")

        # INSERT BUTTON
        Button(self.expense_tab,
               text="Insert",
               command=self.insert_expense_data).grid(row=4,
                                                      column=1,
                                                      pady=2,
                                                      sticky="ew")

        Label(self.expense_tab,
              text="Your expenses:",
              font='Helvetica 16 bold').grid(row=5,
                                             column=0,
                                             padx=15,
                                             pady=15,
                                             sticky='w')

        # TOTAL EXPENSE
        Label(self.expense_tab,
              textvariable=self.sum_expenses).grid(row=6,
                                                   column=0,
                                                   padx=(15, 0),
                                                   sticky='w')

        # BUDGET DIFFERENCE
        self.budgetLabel = Label(self.expense_tab,
                                 textvariable=self.budget_message)
        self.budgetLabel.grid(row=7,
                              column=0,
                              columnspan=2,
                              padx=(15, 0),
                              sticky='w')
        # set budget difference value
        budget_message = self.calculate_budget_level()
        self.budget_message.set(budget_message)

        # TREEVIEW WITH SCROLLBAR
        y_scroll = Scrollbar(self.expense_tab, orient='vertical')
        y_scroll.grid(row=8,
                      column=5,
                      padx=(0, 15),
                      pady=(40, 15),
                      sticky='nsw')
        self.treeExpense = ttk.Treeview(self.expense_tab,
                                        columns=('Date', 'Category',
                                                 'Description', 'Price',
                                                 'Currency', 'Price in EUR'),
                                        yscrollcommand=y_scroll.set,
                                        height=20)
        y_scroll['command'] = self.treeExpense.yview
        self.treeExpense.grid(row=8,
                              column=0,
                              columnspan=5,
                              padx=(15, 0),
                              pady=15)

        # Set the treeview columns
        self.treeExpense.heading('#0', text='Item Id')
        self.treeExpense.column("#0", minwidth=0, width=0)

        self.treeExpense.heading('#1', text='Date')
        self.treeExpense.column("#1", minwidth=0, width=120)

        self.treeExpense.heading('#2', text='Category')
        self.treeExpense.column("#2", minwidth=0, width=280)

        self.treeExpense.heading('#3', text='Description')
        self.treeExpense.column("#3", minwidth=0, width=280)

        self.treeExpense.heading('#4', text='Price')
        self.treeExpense.column("#4", minwidth=0, width=100)

        self.treeExpense.heading('#5', text='Currency')
        self.treeExpense.column("#5", minwidth=0, width=100)

        self.treeExpense.heading('#6', text='Price in EUR')
        self.treeExpense.column("#6", minwidth=0, width=100)

        # Restore display in table from the expense database
        self.update_treeview_from_existing_database()

        # DELETE BUTTON
        # Configure delete button style to be red
        style = Style()
        style.configure('W.TButton', foreground='red')
        Button(self.expense_tab,
               text="Delete",
               style='W.TButton',
               command=self.delete_expense_data).grid(row=9,
                                                      column=4,
                                                      padx=15,
                                                      sticky="e")

        # SORT THE PRICE: CALL FUNCTION
        col1 = "Price"
        col2 = "Price in EUR"
        col3 = "Date"
        self.treeExpense.heading(
            col1,
            text=col1,
            command=lambda: self.treeview_sort_price(col1, False))
        self.treeExpense.heading(
            col2,
            text=col2,
            command=lambda: self.treeview_sort_price(col2, False))

        # SORT THE DATE: CALL FUNCTION
        self.treeExpense.heading(
            col3,
            text=col3,
            command=lambda s=col3: self.treeview_sort_date(col3, False))

    def update_treeview_from_existing_database(self):
        """If the database of expenses already exist for this username, display it back into the treeview"""

        database = self.expense_controller.get_expenses_for_user(self.username)

        for id_item in database:
            self.treeExpense.insert(
                '',
                0,
                id_item,
                values=(database[id_item]["date"],
                        database[id_item]["category"],
                        database[id_item]["description"],
                        database[id_item]["price"],
                        database[id_item]["currency"],
                        database[id_item]["price_in_euro"]))
            self.id_expenseItem = id_item

    def insert_expense_data(self):
        """
        Add a new expense item both to the treeview and to the database. Then update the sum of all expenses and the
        budget difference.
        This function is called when clicking the 'Insert' button
        """
        currency = self.chosen_currency.get()
        category = self.chosen_category.get()
        description = self.description.get()
        price = self.price.get()
        expense_date = self.date.get()

        # replace comma with point in order to make it possible to cast to float
        price = price.replace(',', '.')
        # Check if it is numeric
        if not is_float_number(price):
            messagebox.showerror("INPUT ERROR",
                                 "The price must be a (floating) number")
        else:
            self.id_expenseItem = self.id_expenseItem + 1
            price = float(price)
            price_in_euro = self.expense_controller.convert_in_euro(
                price, currency, self.currency_EUR_dict)

            # display into the Expense gui table
            # https://www.askpython.com/python-modules/tkinter/tkinter-treeview-widget
            self.treeExpense.insert('',
                                    0,
                                    self.id_expenseItem,
                                    values=(expense_date, category,
                                            description, price, currency,
                                            price_in_euro))

            # update the expense database through expense controller
            self.expense_controller.create_expense(self.username,
                                                   self.id_expenseItem,
                                                   expense_date, category,
                                                   description, price,
                                                   currency, price_in_euro)
        total = self.expense_controller.total_expenses(self.username)
        self.sum_expenses.set(f"Sum of all expenses: {total}€")
        budget_message = self.calculate_budget_level()
        self.budget_message.set(budget_message)

    def delete_expense_data(self):
        """
        Remove the selected item from the treeview and the database, then update the sum of all expenses and the
        budget difference.
        This function is called when clicking the 'Delete' button
        """
        try:
            id_expense_selected = int(self.treeExpense.focus())
            self.treeExpense.delete(id_expense_selected)
            # remove the selected expense id in the database as well
            self.expense_controller.delete_expense(self.username,
                                                   id_expense_selected)
        except ValueError:
            messagebox.showerror("Delete Error",
                                 "Select an item to be deleted")
        total = self.expense_controller.total_expenses(self.username)
        self.sum_expenses.set(f"Sum of all expenses: {total}€")
        budget_message = self.calculate_budget_level()
        self.budget_message.set(budget_message)

    def refresh_categories(self, category_list):
        """Refresh the category drop-down menu. This is called after configuring categories in the preferences"""
        self.category_list = category_list
        self.category_select = OptionMenu(self.expense_tab,
                                          self.chosen_category,
                                          self.category_list[0],
                                          *self.category_list)
        self.category_select.grid(row=1, column=3, pady=5, sticky="ew")

    def treeview_sort_price(self, col, reverse: bool):
        """Sort the table by price when clicking on the price column"""
        data_list = [(float(self.treeExpense.set(k, col)), k)
                     for k in self.treeExpense.get_children("")]
        data_list.sort(reverse=reverse)

        # rearrange items in sorted positions
        for index, (val, k) in enumerate(data_list):
            self.treeExpense.move(k, "", index)

        # reverse sort next time
        self.treeExpense.heading(
            column=col,
            text=col,
            command=lambda _col=col: self.treeview_sort_price(
                _col, not reverse),
        )

    def treeview_sort_date(self, date_col, reverse):
        """Sort the table by date when clicking on the date column"""
        l = [(self.treeExpense.set(k, date_col), k)
             for k in self.treeExpense.get_children('')]

        sortedArray = sorted(
            l,
            key=lambda x_lab: datetime.strptime(x_lab[0], '%d/%m/%Y'),
            reverse=not reverse)

        for index, (val, k) in enumerate(sortedArray):
            self.treeExpense.move(k, '', index)

        self.treeExpense.heading(
            column=date_col,
            text=date_col,
            command=lambda _date_col=date_col: self.treeview_sort_date(
                _date_col, not reverse),
        )

    def calculate_budget_level(self):
        """
        Calculates whether the custom budget (in preferences) is already exceeded or not and generate a message to
        display.
        """
        budget = self.user_controller.get_budget(self.username)
        if budget[0]:
            today = date.today()
            if budget[1] == 'per day':
                start_date = today
            elif budget[1] == 'per week':
                start_date = today - timedelta(days=today.weekday())
            elif budget[1] == 'per month':
                start_date = today.replace(day=1)
            elif budget[1] == 'per year':
                start_date = today.replace(month=1).replace(day=1)
            expenses = self.expense_controller.get_expenses_for_user(
                self.username)
            delete = []
            for k, v in expenses.items():
                if datetime.date(datetime.strptime(v['date'],
                                                   '%d/%m/%Y')) < start_date:
                    delete.append(k)
            # we cannot delete items from dictionary while iterating the dict, therefore we store indices to delete in
            # list and delete the corresponding elements later
            for k in delete:
                del expenses[k]
            total = sum([e['price_in_euro'] for e in expenses.values()])
            difference = round((float(budget[0]) - total), 2)
            if difference > 0:
                message = f'You have {difference}€ left from your budget which is {budget[0]}€ {budget[1]}.'
                self.budgetLabel.configure(foreground='green')
            elif difference == 0:
                message = f'Attention! You have nothing left from your budget which is {budget[0]}€ {budget[1]}.'
                self.budgetLabel.configure(foreground='orange')
            else:
                message = f'Attention! You exceeded your budget ({budget[0]}€ {budget[1]}) by {-1*difference}€!'
                self.budgetLabel.configure(foreground='red')
            return message

        return "You haven't set a budget yet. You can do so in the preferences."
예제 #17
0
class viewStock(Frame):
    '''The Frame that is kind of a logged in view and contains buttons
        to move to sell, buy or log out. At the same time it
        it also shows what stocks one has along with their profit and more'''
    def __init__(self, parent, main, **kw):
        Frame.__init__(self, parent, **kw)
        self.view_f_text = Text(width=30)
        self.main = main
        self.view_scroll = Scrollbar(orient = VERTICAL, command=self.view_f_text.yview)
        self.view_f_text.config(yscrollcommand = self.view_scroll.set)
        self.label_head = Label(text='Stocks available', font = MED_FONT)
        self.back_b = Button(text='Login and Buy', command = self.back )
        self.buy_b = Button(text='BUY', command = self.buy)
        self.sell_b = Button(text='SELL', command = self.sell)
    def buy(self):
        '''the call back if we click on buy and takes us to the buy window'''
        self.main.frames[RETAIL_PAGE].page = 'b'
        self.main.show_frame(RETAIL_PAGE, VIEW_STOCK)
    def sell(self):
        '''the call back if we click on sell and it takes us to the sell window'''
        self.main.frames[RETAIL_PAGE].page = 's'
        self.main.show_frame(RETAIL_PAGE, VIEW_STOCK)
    def back(self):
        '''this is kind of the '''
        self.main.show_frame(LOGIN_PAGE, VIEW_STOCK)
        self.main.login = False
        self.main.admin = False
    def showItems(self, main):
        if main.login:
            self.back_b.config(text='Log Out')
            self.label_head.config(text='Logged in as %s'%self.main.present_user)
            self.buy_b.grid(column=0, row=2, columnspan=2)
            self.sell_b.grid(column=0, row=3, columnspan=2)
        else:
            self.back_b.config(text='Login and Buy')
            self.label_head.configure(text='View Stock')

        self.label_head.grid(column=0, row=0, columnspan=2)
        self.view_f_text.grid(column=0, row=1, sticky='nsew')
        self.view_scroll.grid(column=2, row=1)
        self.back_b.grid(column=0, row=4, columnspan=2)
        self.view_stock()
    def hideItems(self, main):
        self.label_head.grid_forget()
        self.view_f_text.grid_forget()
        self.view_scroll.grid_forget()
        self.back_b.grid_forget()

        if main.login:
            self.buy_b.grid_forget()
            self.sell_b.grid_forget()
    def view_stock(self):
        self.view_f_text.config(state='normal')
        self.view_f_text.delete('1.0', 'end')

        if self.main.login and not self.main.admin:
            l2 = self.main.accounts[self.main.present_user]
            txt_1 = 'Balance: ' + l2['balance'] + '\n' + 'Profit: ' + l2['profit'] + '\n'*2 + '*'*20 + '\n'
            self.view_f_text.insert('end',txt_1)
        key = self.main.shares_dict.keys()

        if not self.main.login:
            for name in key:
                li = self.main.shares_dict[name]
                txt_b1 = 'Name: '
                self.view_f_text.insert('end',txt_b1)
                self.view_f_text.insert('end',name+'\n')
                txt_b2 = 'Cost Price: '
                self.view_f_text.insert('end',txt_b2)
                self.view_f_text.insert('end',li['cost']+'\n')
                available_num = int(li['tot_amount']) - int(li['tot_sold'])
                txt_b3 = 'Available amount: '
                self.view_f_text.insert('end',txt_b3)
                self.view_f_text.insert('end',str(available_num)+'\n')
                txt_b4 = '*'*20
                self.view_f_text.insert('end','\n'+txt_b4+'\n\n')
        self.view_scroll.grid(column=1, row=0, rowspan=2, sticky='nswe')

        if self.main.login:
            for name in key:
                li = self.main.shares_dict[name]
                txt_b1 = 'Name: '
                self.view_f_text.insert('end',txt_b1)
                self.view_f_text.insert('end',name+'\n')
                txt_b2 = 'Cost Price: '
                self.view_f_text.insert('end',txt_b2)
                self.view_f_text.insert('end',li['cost']+'\n')
                available_num = int(li['tot_amount']) - int(li['tot_sold'])
                txt_b3 = 'Available amount: '
                self.view_f_text.insert('end',txt_b3)
                self.view_f_text.insert('end',str(available_num)+'\n')
                lis =  self.main.p_user_dict
                for i in lis:
                    if i['name'] == name:
                        lis = i
                        break
                txt1 = 'Stocks owned: '+lis['tot_owned']+'\n' if not lis['tot_owned'] == '0' else ''
                self.view_f_text.insert('end', txt1)
                txt2 = 'Money spent: '+ lis['money_spent']+'\n' if not lis['tot_owned'] == '0' else ''
                self.view_f_text.insert('end', txt2)
                txt_b4 = '*'*20
                self.view_f_text.insert('end','\n'+txt_b4+'\n\n')
            self.view_f_text.config(state='disabled')
        else:
            self.view_f_text.config(state='disabled')
예제 #18
0
def label_inc():
    global i
    i = i + 1
    label.configure(text='Counting UP: {}'.format(i))
    root.update_idletasks()


def label_dec():
    global i
    i = i - 1
    label.configure(text='Counting Down: {}'.format(i))
    root.update_idletasks()


def close_window():
    root.destroy()


if __name__ == '__main__':
    i = 0
    root = Tk()
    root.geometry("250x80")
    root.title("Up & Down Counter")
    label = Label(root)
    label.place(x=5, y=10)
    label.configure(text='Count: 0')
    Button(root, text=' Count up ', command=label_inc).place(x=5, y=40)
    Button(root, text='Count down', command=label_dec).place(x=85, y=40)
    Button(root, text='Exit', command=close_window).place(x=170, y=40)
    mainloop()
예제 #19
0
파일: sudoku.py 프로젝트: j4321/Sudoku-Tk
class Sudoku(Tk):
    def __init__(self, file=None):
        Tk.__init__(self, className="Sudoku-Tk")
        self.title("Sudoku-Tk")
        self.resizable(0, 0)
        self.protocol("WM_DELETE_WINDOW", self.quitter)
        cst.set_icon(self)
        self.columnconfigure(3, weight=1)

        # --- style
        bg = '#dddddd'
        activebg = '#efefef'
        pressedbg = '#c1c1c1'
        lightcolor = '#ededed'
        darkcolor = '#cfcdc8'
        bordercolor = '#888888'
        focusbordercolor = '#5E5E5E'
        disabledfg = '#999999'
        disabledbg = bg

        button_style_config = {'bordercolor': bordercolor,
                               'background': bg,
                               'lightcolor': lightcolor,
                               'darkcolor': darkcolor}

        button_style_map = {'background': [('active', activebg),
                                           ('disabled', disabledbg),
                                           ('pressed', pressedbg)],
                            'lightcolor': [('pressed', darkcolor)],
                            'darkcolor': [('pressed', lightcolor)],
                            'bordercolor': [('focus', focusbordercolor)],
                            'foreground': [('disabled', disabledfg)]}

        style = Style(self)
        style.theme_use(cst.STYLE)
        style.configure('TFrame', background=bg)
        style.configure('TLabel', background=bg)
        style.configure('TScrollbar', gripcount=0, troughcolor=pressedbg,
                        **button_style_config)
        style.map('TScrollbar', **button_style_map)
        style.configure('TButton', **button_style_config)
        style.map('TButton', **button_style_map)
        style.configure('TCheckutton', **button_style_config)
        style.map('TCheckutton', **button_style_map)
        self.option_add('*Toplevel.background', bg)
        self.option_add('*Menu.background', bg)
        self.option_add('*Menu.activeBackground', activebg)
        self.option_add('*Menu.activeForeground', "black")
        self.configure(bg=bg)

        style.configure("bg.TFrame", background="grey")
        style.configure("case.TFrame", background="white")
        style.configure("case.TLabel", background="white", foreground="black")
        style.configure("case_init.TFrame", background="lightgrey")
        style.configure("case_init.TLabel", background="lightgrey", foreground="black")
        style.configure("erreur.TFrame", background="white")
        style.configure("erreur.TLabel", background="white", foreground="red")
        style.configure("solution.TFrame", background="white")
        style.configure("solution.TLabel", background="white", foreground="blue")
        style.configure("pause.TLabel", foreground="grey", background='white')

        # --- images
        self.im_erreur = open_image(cst.ERREUR)
        self.im_pause = open_image(cst.PAUSE)
        self.im_restart = open_image(cst.RESTART)
        self.im_play = open_image(cst.PLAY)
        self.im_info = open_image(cst.INFO)
        self.im_undo = open_image(cst.UNDO)
        self.im_redo = open_image(cst.REDO)
        self.im_question = open_image(cst.QUESTION)

        # --- timer
        self.chrono = [0, 0]
        self.tps = Label(self, text=" %02i:%02i" % tuple(self.chrono),
                         font="Arial 16")
        self.debut = False  # la partie a-t-elle commencée ?
        self.chrono_on = False  # le chrono est-il en marche ?

        # --- buttons
        self.b_pause = Button(self, state="disabled", image=self.im_pause,
                              command=self.play_pause)
        self.b_restart = Button(self, state="disabled", image=self.im_restart,
                                command=self.recommence)
        self.b_undo = Button(self, image=self.im_undo, command=self.undo)
        self.b_redo = Button(self, image=self.im_redo, command=self.redo)

        # --- tooltips
        self.tooltip_wrapper = TooltipWrapper(self)
        self.tooltip_wrapper.add_tooltip(self.b_pause, _("Pause game"))
        self.tooltip_wrapper.add_tooltip(self.b_restart, _("Restart game"))
        self.tooltip_wrapper.add_tooltip(self.b_undo, _("Undo"))
        self.tooltip_wrapper.add_tooltip(self.b_redo, _("Redo"))

        # --- numbers
        frame_nb = Frame(self, style='bg.TFrame', width=36)
        self.progression = []
        for i in range(1, 10):
            self.progression.append(Progression(frame_nb, i))
            self.progression[-1].pack(padx=1, pady=1)

        # --- level indication
        frame = Frame(self)
        frame.grid(row=0, columnspan=5, padx=(30, 10), pady=10)
        Label(frame, text=_("Level") + ' - ', font="Arial 16").pack(side='left')
        self.label_level = Label(frame, font="Arial 16", text=_("Unknown"))
        self.label_level.pack(side='left')
        self.level = "unknown"  # puzzle level

        # --- frame contenant la grille de sudoku
        self.frame_puzzle = Frame(self, style="bg.TFrame")
        self.frame_pause = Frame(self, style="case.TFrame")
        self.frame_pause.grid_propagate(False)
        self.frame_pause.columnconfigure(0, weight=1)
        self.frame_pause.rowconfigure(0, weight=1)
        Label(self.frame_pause, text='PAUSE', style='pause.TLabel',
              font='Arial 30 bold').grid()

        # --- placement
        frame_nb.grid(row=1, column=6, sticky='en', pady=0, padx=(0, 30))
        self.frame_puzzle.grid(row=1, columnspan=5, padx=(30, 15))
        self.tps.grid(row=2, column=0, sticky="e", padx=(30, 10), pady=30)
        self.b_pause.grid(row=2, column=1, sticky="w", padx=2, pady=30)
        self.b_restart.grid(row=2, column=2, sticky="w", padx=2, pady=30)
        self.b_undo.grid(row=2, column=3, sticky="e", pady=30, padx=2)
        self.b_redo.grid(row=2, column=4, sticky="w", pady=30, padx=(2, 10))

        # --- menu
        menu = Menu(self, tearoff=0)

        menu_nouveau = Menu(menu, tearoff=0)

        menu_levels = Menu(menu_nouveau, tearoff=0)
        menu_levels.add_command(label=_("Easy"), command=self.new_easy)
        menu_levels.add_command(label=_("Medium"), command=self.new_medium)
        menu_levels.add_command(label=_("Difficult"), command=self.new_difficult)

        menu_nouveau.add_cascade(label=_("Level"), menu=menu_levels)
        menu_nouveau.add_command(label=_("Generate a puzzle"),
                                 command=self.genere_grille,
                                 accelerator="Ctrl+G")
        menu_nouveau.add_command(label=_("Empty grid"),
                                 command=self.grille_vide,
                                 accelerator="Ctrl+N")

        menu_ouvrir = Menu(menu, tearoff=0)
        menu_ouvrir.add_command(label=_("Game"), command=self.import_partie,
                                accelerator="Ctrl+O")
        menu_ouvrir.add_command(label=_("Puzzle"), command=self.import_grille,
                                accelerator="Ctrl+Shift+O")

        menu_game = Menu(menu, tearoff=0)
        menu_game.add_command(label=_("Restart"), command=self.recommence)
        menu_game.add_command(label=_("Solve"), command=self.resolution)
        menu_game.add_command(label=_("Save"), command=self.sauvegarde,
                              accelerator="Ctrl+S")
        menu_game.add_command(label=_("Export"), command=self.export_impression,
                              accelerator="Ctrl+E")
        menu_game.add_command(label=_("Evaluate level"),
                              command=self.evaluate_level)

        menu_language = Menu(menu, tearoff=0)
        self.langue = StringVar(self)
        self.langue.set(cst.LANGUE[:2])
        menu_language.add_radiobutton(label="Français",
                                      variable=self.langue,
                                      value="fr", command=self.translate)
        menu_language.add_radiobutton(label="English", variable=self.langue,
                                      value="en", command=self.translate)

        menu_help = Menu(menu, tearoff=0)
        menu_help.add_command(label=_("Help"), command=self.aide, accelerator='F1')
        menu_help.add_command(label=_("About"), command=self.about)

        menu.add_cascade(label=_("New"), menu=menu_nouveau)
        menu.add_cascade(label=_("Open"), menu=menu_ouvrir)
        menu.add_cascade(label=_("Game"), menu=menu_game)
        menu.add_cascade(label=_("Language"), menu=menu_language)
        menu.add_command(label=_("Statistics"), command=self.show_stat)
        menu.add_cascade(label=_("Help"), menu=menu_help)

        self.configure(menu=menu)

        # --- clavier popup
        self.clavier = None

        # --- cases
        self.nb_cases_remplies = 0
        self.blocs = np.zeros((9, 9), dtype=object)
        for i in range(9):
            for j in range(9):
                self.blocs[i, j] = Case(self.frame_puzzle, i, j, self.update_nbs, width=50, height=50)
                px, py = 1, 1
                if i % 3 == 2 and i != 8:
                    py = (1, 3)
                if j % 3 == 2 and j != 8:
                    px = (1, 3)
                self.blocs[i, j].grid(row=i, column=j, padx=px, pady=py)
                self.blocs[i, j].grid_propagate(0)

        # --- undo/redo stacks
        self._undo_stack = []
        self._redo_stack = []

        # --- raccourcis clavier et actions de la souris
        self.bind("<Button>", self.edit_case)
        self.bind("<Control-z>", lambda e: self.undo())
        self.bind("<Control-y>", lambda e: self.redo())
        self.bind("<Control-s>", lambda e: self.sauvegarde())
        self.bind("<Control-e>", lambda e: self.export_impression())
        self.bind("<Control-o>", lambda e: self.import_partie())
        self.bind("<Control-Shift-O>", lambda e: self.import_grille())
        self.bind("<Control-n>", lambda e: self.grille_vide())
        self.bind("<Control-g>", lambda e: self.genere_grille())
        self.bind("<FocusOut>", self.focus_out)
        self.bind("<F1>", self.aide)

        # --- open game
        if file:
            try:
                self.load_sudoku(file)
            except FileNotFoundError:
                one_button_box(self, _("Error"),
                               _("The file %(file)r does not exist.") % file,
                               image=self.im_erreur)
            except (KeyError, EOFError, UnpicklingError):
                try:
                    self.load_grille(file)
                except Exception:
                    one_button_box(self, _("Error"),
                                   _("This file is not a valid sudoku file."),
                                   image=self.im_erreur)
        elif exists(cst.PATH_SAVE):
            self.load_sudoku(cst.PATH_SAVE)
            remove(cst.PATH_SAVE)

    @property
    def level(self):
        return self._level

    @level.setter
    def level(self, level):
        self._level = level
        self.label_level.configure(text=_(level.capitalize()))

    def update_nbs(self, nb, delta):
        self.progression[nb - 1].nb += delta

    def reset_nbs(self):
        for p in self.progression:
            p.nb = 0

    def evaluate_level(self):
        grille = Grille()
        for i in range(9):
            for j in range(9):
                val = self.blocs[i, j].get_val()
                if val:
                    grille.ajoute_init(i, j, val)
        self.level = difficulte_grille(grille)

    def show_stat(self):
        """ show best times """
        def reset():
            """ reset best times """
            for level in ["easy", "medium", "difficult"]:
                CONFIG.set("Statistics", level, "")
            top.destroy()

        if self.chrono_on:
            self.play_pause()
        top = Toplevel(self)
        top.transient(self)
        top.columnconfigure(1, weight=1)
        top.resizable(0, 0)

        top.title(_("Statistics"))
        top.grab_set()

        Label(top, text=_("Best times"), font="Sans 12 bold").grid(row=0, columnspan=2,
                                                                   padx=30, pady=10)

        for i, level in enumerate(["easy", "medium", "difficult"]):
            Label(top, text=_(level.capitalize()),
                  font="Sans 10 bold").grid(row=i + 1, column=0, padx=(20, 4),
                                            pady=4, sticky="e")
            tps = CONFIG.get("Statistics", level)
            if tps:
                tps = int(tps)
                m = tps // 60
                s = tps % 60
                Label(top, text=" %i min %i s" % (m, s),
                      font="Sans 10").grid(row=i + 1, column=1,
                                           sticky="w", pady=4,
                                           padx=(4, 20))
        Button(top, text=_("Close"), command=top.destroy).grid(row=4, column=0, padx=(10, 4), pady=10)
        Button(top, text=_("Clear"), command=reset).grid(row=4, column=1, padx=(4, 10), pady=10)

    def new_easy(self):
        nb = np.random.randint(1, 101)
        fichier = join(cst.PUZZLES_LOCATION, "easy", "puzzle_easy_%i.txt" % nb)
        self.import_grille(fichier)
        self.level = "easy"

    def new_medium(self):
        nb = np.random.randint(1, 101)
        fichier = join(cst.PUZZLES_LOCATION, "medium", "puzzle_medium_%i.txt" % nb)
        self.import_grille(fichier)
        self.level = "medium"

    def new_difficult(self):
        nb = np.random.randint(1, 101)
        fichier = join(cst.PUZZLES_LOCATION, "difficult", "puzzle_difficult_%i.txt" % nb)
        self.import_grille(fichier)
        self.level = "difficult"

    def translate(self):
        """ changement de la langue de l'interface """
        one_button_box(self, _("Information"),
                       _("The language setting will take effect after restarting the application"),
                       image=self.im_info)
        CONFIG.set("General", "language", self.langue.get())

    def focus_out(self, event):
        """ met en pause si la fenêtre n'est plus au premier plan """
        try:
            if not self.focus_get() and self.chrono_on:
                self.play_pause()
        except KeyError:
            # erreur déclenchée par la présence d'une tkMessagebox
            if self.chrono_on:
                self.play_pause()

    def stacks_reinit(self):
        """efface l'historique des actions"""
        self._undo_stack.clear()
        self._redo_stack.clear()
        self.b_undo.configure(state="disabled")
        self.b_redo.configure(state="disabled")

    def stacks_modif(self, action):
        """Record action and clear redo stack."""
        self._undo_stack.append(action)
        self.b_undo.configure(state="normal")
        self.b_redo.configure(state="disabled")
        self._redo_stack.clear()

    def about(self):
        if self.chrono_on:
            self.play_pause()
        About(self)

    def aide(self, event=None):
        if self.chrono_on:
            self.play_pause()
        Aide(self)

    def quitter(self):
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you want to interrupt the current puzzle?"),
                                 _("Yes"), _("No"), image=self.im_question)
        if rep == _("Yes"):
            if self.debut:
                self.save(cst.PATH_SAVE)
            self.destroy()

    def undo(self):
        if self._undo_stack and self.chrono_on:
            self.b_redo.configure(state="normal")
            i, j, val_prec, pos_prec, modifs, val, pos = self._undo_stack.pop(-1)
            self._redo_stack.append((i, j, val_prec, pos_prec, modifs, val, pos))
            if not self._undo_stack:
                self.b_undo.configure(state="disabled")

            if self.blocs[i, j].get_val():
                self.modifie_nb_cases_remplies(-1)
                self.update_nbs(self.blocs[i, j].get_val(), -1)
            self.blocs[i, j].efface_case()
            if val_prec:
                self.modifie_nb_cases_remplies(self.blocs[i, j].edit_chiffre(val_prec))
                if not self.test_case(i, j, val):
                    self.update_grille(i, j, val)
            else:
                for nb in pos_prec:
                    v = int(nb)
                    self.modifie_nb_cases_remplies(self.blocs[i, j].edit_possibilite(v))
                    self.test_possibilite(i, j, v)
            for k, l in modifs:
                self.blocs[k, l].edit_possibilite(val)

    def redo(self):
        if self._redo_stack and self.chrono_on:
            self.b_undo.configure(state="normal")
            i, j, val_prec, pos_prec, modifs, val, pos = self._redo_stack.pop(-1)
            self._undo_stack.append((i, j, val_prec, pos_prec, modifs, val, pos))
            if not self._redo_stack:
                self.b_redo.configure(state="disabled")
            val_prec = self.blocs[i, j].get_val()
            if val_prec:
                self.modifie_nb_cases_remplies(-1)
                self.update_nbs(val_prec, -1)
            self.blocs[i, j].efface_case()
            if val:
                self.modifie_nb_cases_remplies(self.blocs[i, j].edit_chiffre(val))
                if not self.test_case(i, j, val_prec):
                    self.update_grille(i, j, val_prec)
            else:
                for nb in pos:
                    v = int(nb)
                    self.modifie_nb_cases_remplies(self.blocs[i, j].edit_possibilite(v))
                    self.test_possibilite(i, j, v)

    def restart(self, m=0, s=0):
        """ réinitialise le chrono et les boutons """
        self.chrono = [m, s]
        self.chrono_on = False
        self.debut = False
        self.tps.configure(text=" %02i:%02i" % tuple(self.chrono))
        self.b_undo.configure(state="disabled")
        self.b_pause.configure(state="disabled", image=self.im_pause)
        self.b_redo.configure(state="disabled")
        self.b_restart.configure(state="disabled")
        self.stacks_reinit()
        self.frame_pause.place_forget()

    def play_pause(self):
        """ Démarre le chrono s'il était arrêté, le met en pause sinon """
        if self.debut:
            if self.chrono_on:
                self.chrono_on = False
                self.b_pause.configure(image=self.im_play)
                self.b_redo.configure(state="disabled")
                self.b_undo.configure(state="disabled")
                self.tooltip_wrapper.set_tooltip_text(self.b_pause, _("Resume game"))
                self.frame_pause.place(in_=self.frame_puzzle, x=0, y=0, anchor='nw',
                                       relwidth=1, relheight=1)
            elif self.nb_cases_remplies != 81:
                self.chrono_on = True
                self.b_pause.configure(image=self.im_pause)
                self.tps.after(1000, self.affiche_chrono)
                if self._undo_stack:
                    self.b_undo.configure(state="normal")
                if self._redo_stack:
                    self.b_redo.configure(state="normal")
                self.tooltip_wrapper.set_tooltip_text(self.b_pause, _("Pause game"))
                self.frame_pause.place_forget()

    def affiche_chrono(self):
        """ Met à jour l'affichage du temps """
        if self.chrono_on:
            self.chrono[1] += 1
            if self.chrono[1] == 60:
                self.chrono[0] += 1
                self.chrono[1] = 0
            self.tps.configure(text=" %02i:%02i" % tuple(self.chrono))
            self.tps.after(1000, self.affiche_chrono)

    def modifie_nb_cases_remplies(self, nb):
        self.nb_cases_remplies += nb

    def edit_case(self, event):
        if event.num in [1, 3]:
            if not self.debut and self.nb_cases_remplies != 81:
                self.debut = True
                self.b_pause.configure(state="normal")
                self.b_restart.configure(state="normal")
                self.play_pause()
            if str(event.widget) != "." and self.chrono_on:
                if self.clavier:
                    self.clavier.quitter()
                ref = self.blocs[0, 0].winfo_parent()
                case = event.widget.grid_info().get("in", None)
                if str(case) == ref:
                    case = event.widget
                try:
                    if case.is_modifiable():
                        if event.num == 1:
                            self.clavier = Clavier(self, case, "val")
                        elif event.num == 3:
                            self.clavier = Clavier(self, case, "possibilite")
                        self.clavier.display("+%i+%i" % (case.winfo_rootx() - 25, case.winfo_rooty() + 50))
                except AttributeError:
                    if self.clavier:
                        self.clavier.quitter()

            elif self.clavier:
                self.clavier.quitter()

    def test_case(self, i, j, val_prec=0):
        """ Teste si la valeur de la case est en contradiction avec celles des
            autres cases de la ligne / colonne / bloc et renvoie True s'il y a une erreur."""
        val = self.blocs[i, j].get_val()
        a, b = i // 3, j // 3
        error = False
        if val:
            if ((self.blocs[i, :] == val).sum() > 1 or (self.blocs[:, j] == val).sum() > 1 or
               (self.blocs[3 * a: 3 * (a + 1), 3 * b: 3 * (b + 1)] == val).sum() > 1):
                # erreur !
                self.blocs[i, j].affiche_erreur()
                error = True
        if val_prec:
            # a number was removed, remove obsolete errors
            line = self.blocs[i, :] == val_prec
            column = self.blocs[:, j] == val_prec
            bloc = self.blocs[3 * a: 3 * (a + 1), 3 * b: 3 * (b + 1)] == val_prec
            if line.sum() == 1:
                self.blocs[i, line.argmax()].no_error()
                self.test_case(i, line.argmax())
            if column.sum() == 1:
                self.blocs[column.argmax(), j].no_error()
                self.test_case(column.argmax(), j)
            if bloc.sum() == 1:
                x, y = divmod(bloc.argmax(), 3)
                self.blocs[3 * a + x, 3 * b + y].no_error()
                self.test_case(3 * a + x, 3 * b + y)
        return error

    def test_possibilite(self, i, j, val):
        """ Teste si la possibilité val de la case est en contradiction avec les valeurs des
            autres cases de la ligne / colonne / bloc """
        a, b = i // 3, j // 3
        if ((self.blocs[i, :] == val).sum() > 0 or (self.blocs[:, j] == val).sum() > 0 or
           (self.blocs[3 * a: 3 * (a + 1), 3 * b: 3 * (b + 1)] == val).sum() > 0):
            # erreur !
            self.blocs[i, j].affiche_erreur_possibilite(val)

    def test_remplie(self):
        """ Test si la grille est remplie """
        if self.nb_cases_remplies == 81:
            grille = Grille()
            for i in range(9):
                for j in range(9):
                    val = self.blocs[i, j].get_val()
                    if val:
                        grille.ajoute_init(i, j, val)
            sol = grille.solve()
            if type(sol) == np.ndarray:
                self.play_pause()
                self.frame_pause.place_forget()
                one_button_box(self, _("Information"),
                               _("You solved the puzzle in %(min)i minutes and %(sec)i secondes.") % {"min": self.chrono[0], "sec": self.chrono[1]},
                               image=self.im_info)
                if self.level != "unknown":
                    best = CONFIG.get("Statistics", self.level)
                    current = self.chrono[0] * 60 + self.chrono[1]
                    if best:
                        best = int(best)
                        if current < best:
                            CONFIG.set("Statistics", self.level, str(current))
                    else:
                        CONFIG.set("Statistics", self.level, str(current))
                self.b_pause.configure(state="disabled")
                self.debut = False

            else:
                i, j = sol[1]
                if self.blocs[i, j].get_val():
                    self.blocs[i, j].affiche_erreur()
                one_button_box(self, _("Information"), _("There is a mistake."),
                               image=self.im_info)

    def update_grille(self, i, j, val_prec=0):
        """ Enlève les possibilités devenues impossibles suite à l'ajout d'une
            valeur dans la case (i, j) """
        val = self.blocs[i, j].get_val()
        modif = []
        a, b = i // 3, j // 3
        if val_prec:
            x, y = divmod(val_prec - 1, 3)
        for k, (line, column, bloc) in enumerate(zip(self.blocs[i, :], self.blocs[:, j], self.blocs[3 * a: 3 * (a + 1), 3 * b: 3 * (b + 1)].flatten())):
            # works because if line is bloc then pos1 is pos3 and both are edited at once
            pos1 = line.get_possibilites()
            pos2 = column.get_possibilites()
            pos3 = bloc.get_possibilites()
            if val in pos1:
                self.blocs[i, k].edit_possibilite(val)
                modif.append((i, k))
            if val in pos2:
                self.blocs[k, j].edit_possibilite(val)
                modif.append((k, j))
            if val in pos3:
                m, n = divmod(k, 3)
                self.blocs[3 * a + m, 3 * b + n].edit_possibilite(val)
                modif.append((3 * a + m, 3 * b + n))
            if val_prec:
                if val_prec in pos1:
                    self.blocs[i, k].pas_erreur(x, y)
                    self.test_possibilite(i, k, val_prec)
                if val_prec in pos2:
                    self.blocs[k, j].pas_erreur(x, y)
                    self.test_possibilite(k, j, val_prec)
                if val_prec in pos3:
                    m, n = divmod(k, 3)
                    m, n = 3 * a + m, 3 * b + n
                    if m != i and n != j:
                        self.blocs[m, n].pas_erreur(x, y)
                        self.test_possibilite(m, n, val_prec)
        return modif

    def set_clavier(self, c):
        self.clavier = c

    def grille_vide(self):
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you want to abandon the current puzzle?"),
                                 _("Yes"), _("No"), self.im_question)
        if rep == _("Yes"):
            self.nb_cases_remplies = 0
            self.restart()
            self.level = "unknown"
            self.reset_nbs()
            for i in range(9):
                for j in range(9):
                    self.blocs[i, j].set_modifiable(True)
                    self.blocs[i, j].efface_case()

    def genere_grille(self):
        """ Génère une nouvelle grille """
        if self.chrono_on:
            self.play_pause()
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you want to abandon the current puzzle?"),
                                 _("Yes"), _("No"), self.im_question)

        if rep == _("Yes"):
            self.configure(cursor="watch")
            self.update()
            rep2 = _("Retry")
            while rep2 == _("Retry"):
                grille = genere_grille()
                diff = difficulte_grille(grille)
                nb = grille.nb_cases_remplies()
                self.configure(cursor="")
                rep2 = two_button_box(self, _("Information"),
                                      _("The generated puzzle contains %(nb)i numbers and its level is %(difficulty)s.") % ({"nb": nb, "difficulty": _(diff.capitalize())}),
                                      _("Play"), _("Retry"), image=self.im_info)
            if rep2 == _("Play"):
                self.level = diff
                self.affiche_grille(grille.get_sudoku())

    def recommence(self):
        if self.chrono_on:
            self.play_pause()
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you really want to start again?"),
                                 _("Yes"), _("No"), self.im_question)
        if rep == _("Yes"):
            self.reset_nbs()
            for i in range(9):
                for j in range(9):
                    if self.blocs[i, j].is_modifiable():
                        if self.blocs[i, j].get_val():
                            self.nb_cases_remplies -= 1
                        self.blocs[i, j].efface_case()
                    else:
                        self.update_nbs(self.blocs[i, j].get_val(), 1)
            self.restart()
        elif self.debut:
            self.play_pause()

    def save(self, path):
        grille = np.zeros((9, 9), dtype=int)
        modif = np.zeros((9, 9), dtype=bool)
        possibilites = []
        for i in range(9):
            possibilites.append([])
            for j in range(9):
                grille[i, j] = self.blocs[i, j].get_val()
                modif[i, j] = self.blocs[i, j].is_modifiable()
                possibilites[i].append(self.blocs[i, j].get_possibilites())
        with open(path, "wb") as fich:
            p = Pickler(fich)
            p.dump(grille)
            p.dump(modif)
            p.dump(possibilites)
            p.dump(self.chrono)
            p.dump(self.level)

    def sauvegarde(self):
        if self.chrono_on:
            self.play_pause()
        fichier = asksaveasfilename(initialdir=cst.INITIALDIR,
                                    defaultextension='.sudoku',
                                    filetypes=[('Sudoku', '*.sudoku')])
        if fichier:
            self.save(fichier)

    def affiche_grille(self, grille):
        """ Affiche la grille """
        self.nb_cases_remplies = 0
        self.restart()
        self.reset_nbs()
        for i in range(9):
            for j in range(9):
                nb = grille[i, j]
                self.blocs[i, j].efface_case()
                if nb:
                    self.blocs[i, j].set_modifiable(False)
                    self.nb_cases_remplies += 1
                    self.blocs[i, j].edit_chiffre(nb)
                else:
                    self.blocs[i, j].set_modifiable(True)

    def load_sudoku(self, file):
        with open(file, "rb") as fich:
            dp = Unpickler(fich)
            grille = dp.load()
            modif = dp.load()
            possibilites = dp.load()
            chrono = dp.load()
            self.level = dp.load()
        self.nb_cases_remplies = 0
        self.reset_nbs()
        self.restart(*chrono)
        for i in range(9):
            for j in range(9):
                self.blocs[i, j].efface_case()
                if grille[i, j]:
                    self.nb_cases_remplies += 1
                    self.blocs[i, j].edit_chiffre(grille[i, j])
                else:
                    for pos in possibilites[i][j]:
                        self.blocs[i, j].edit_possibilite(pos)
                self.blocs[i, j].set_modifiable(modif[i, j])

    def import_partie(self):
        """ importe une partie stockée dans un fichier .sudoku """
        if self.chrono_on:
            self.play_pause()
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you want to abandon the current puzzle?"),
                                 _("Yes"), _("No"), self.im_question)
        if rep == _("Yes"):
            fichier = askopenfilename(initialdir=cst.INITIALDIR,
                                      defaultextension='.sudoku',
                                      filetypes=[('Sudoku', '*.sudoku')])
            if fichier:
                try:
                    self.load_sudoku(fichier)
                except FileNotFoundError:
                    one_button_box(self, _("Error"),
                                   _("The file %(file)r does not exist.") % fichier,
                                   image=self.im_erreur)
                except (KeyError, EOFError, UnpicklingError):
                    one_button_box(self, _("Error"),
                                   _("This file is not a valid sudoku file."),
                                   image=self.im_erreur)
        elif self.debut:
            self.play_pause()

    def resolution_init(self):
        """ Résolution de la grille initiale (sans tenir compte des valeurs rentrées par l'utilisateur. """
        grille = Grille()
        for i in range(9):
            for j in range(9):
                if not self.blocs[i, j].is_modifiable():
                    val = self.blocs[i, j].get_val()
                    grille.ajoute_init(i, j, val)
        self.configure(cursor="watch")
        self.update()
        sol = grille.solve()
        self.configure(cursor="")
        if type(sol) == np.ndarray:
            for i in range(9):
                for j in range(9):
                    val = self.blocs[i, j].get_val()
                    if not val:
                        self.blocs[i, j].edit_chiffre(sol[i, j])
                        self.blocs[i, j].affiche_solution()
                    elif self.blocs[i, j].is_modifiable():
                        if val != sol[i, j]:
                            self.blocs[i, j].edit_chiffre(sol[i, j])
                            self.blocs[i, j].affiche_erreur()
            self.restart()
            self.nb_cases_remplies = 81

        elif sol[1]:
            i, j = sol[1]
            if self.blocs[i, j].get_val():
                self.blocs[i, j].affiche_erreur()
            one_button_box(self, _("Error"), _("The grid is wrong. It cannot be solved."),
                           image=self.im_erreur)
        else:
            one_button_box(self, _("Error"), _("Resolution failed."),
                           image=self.im_erreur)

    def resolution(self):
        if self.chrono_on:
            self.play_pause()
        rep = two_button_box(self, _("Confirmation"),
                             _("Do you really want to get the solution?"),
                             _("Yes"), _("No"), image=self.im_question)
        if rep == _("Yes"):
            self.frame_pause.place_forget()
            grille = Grille()
            for i in range(9):
                for j in range(9):
                    val = self.blocs[i, j].get_val()
                    if val:
                        grille.ajoute_init(i, j, val)
            self.configure(cursor="watch")
            self.update()
            sol = grille.solve()
            self.configure(cursor="")
            if type(sol) == np.ndarray:
                for i in range(9):
                    for j in range(9):
                        val = self.blocs[i, j].get_val()
                        if not val:
                            self.blocs[i, j].edit_chiffre(sol[i, j])
                            self.blocs[i, j].affiche_solution()
                self.restart()
                self.b_restart.configure(state="normal")
                self.nb_cases_remplies = 81
            elif sol[1]:
                i, j = sol[1]
                if self.blocs[i, j].get_val():
                    self.blocs[i, j].affiche_erreur()
                i, j = 0, 0
                while i < 9 and self.blocs[i, j].is_modifiable():
                    j += 1
                    if j == 9:
                        i += 1
                        j = 0
                if i < 9:
                    # il y a au moins une case de type "initial"
                    rep = two_button_box(self, _("Error"),
                                         _("The grid is wrong. It cannot be solved. Do you want the solution of the initial grid?"),
                                         _("Yes"), _("No"), image=self.im_erreur)
                    if rep == _("Yes"):
                        self.resolution_init()
                else:
                    one_button_box(self, _("Error"), _("The grid is wrong. It cannot be solved."),
                                   image=self.im_erreur)
            else:
                one_button_box(self, _("Error"), _("Resolution failed."),
                               image=self.im_erreur)

    def load_grille(self, file):
        gr = np.loadtxt(file, dtype=int)
        if gr.shape == (9, 9):
            self.affiche_grille(gr)
            self.level = "unknown"
        else:
            one_button_box(self, _("Error"), _("This is not a 9x9 sudoku grid."),
                           image=self.im_erreur)

    def import_grille(self, fichier=None):
        """ importe une grille stockée dans un fichier txt sous forme de
            chiffres séparés par des espaces (0 = case vide) """
        if self.chrono_on:
            self.play_pause()
        rep = _("Yes")
        if self.debut:
            rep = two_button_box(self, _("Confirmation"),
                                 _("Do you want to abandon the current puzzle?"),
                                 _("Yes"), _("No"), self.im_question)
        if rep == _("Yes"):
            if not fichier:
                fichier = askopenfilename(initialdir=cst.INITIALDIR,
                                          defaultextension='.txt',
                                          filetypes=[('Text', '*.txt'), ('Tous les fichiers', "*")])
            if fichier:
                try:
                    self.load_grille(fichier)
                except (ValueError, UnicodeDecodeError):
                    one_button_box(self, _("Error"),
                                   _("The file does not have the right format. It should be a .txt file with cell values separated by one space. 0 means empty cell."),
                                   image=self.im_erreur)
                except FileNotFoundError:
                    one_button_box(self, _("Error"),
                                   _("The file %(file)r does not exist.") % fichier,
                                   image=self.im_erreur)
        elif self.debut:
            self.play_pause()

    def export_impression(self):
        """ exporte la grille en image (pour pouvoir l'imprimer) """
        if self.chrono_on:
            self.play_pause()
        fichier = asksaveasfilename(title=_("Export"),
                                    initialdir=cst.INITIALDIR,
                                    defaultextension='.png',
                                    filetypes=[('PNG', '*.png'),
                                               ('JPEG', 'jpg')])
        if fichier:
            grille = np.zeros((9, 9), dtype=int)
            for i in range(9):
                for j in range(9):
                    grille[i, j] = self.blocs[i, j].get_val()
            font = ImageFont.truetype("arial.ttf", 64)
            im = Image.new("RGB", (748, 748), "white")
            draw = ImageDraw.Draw(im)
            i = 0
            l = 1
            while i < 10:
                if i % 3 == 0:
                    w = 4
                else:
                    w = 2
                draw.line((l, 1, l, 748), width=w, fill="black")
                draw.line((1, l, 748, l), width=w, fill="black")
                l += 80 + w
                i += 1

            for i in range(9):
                for j in range(9):
                    if grille[i, j]:
                        draw.text((26 + j * 82 + 2 * (j // 3),
                                   10 + i * 82 + 2 * (i // 3)),
                                  " %i" % grille[i, j], fill="black", font=font)

            del draw
            im.save(fichier)
예제 #20
0
파일: sticky.py 프로젝트: Vistaus/MyNotes
class Sticky(Toplevel):
    """ Sticky note class """
    def __init__(self, master, key, **kwargs):
        """ Create a new sticky note.
            master: main app
            key: key identifying this note in master.note_data
            kwargs: dictionnary of the other arguments
            (title, txt, category, color, tags, geometry, locked, checkboxes,
             images, rolled)
        """
        Toplevel.__init__(self, master)
        # --- window properties
        self.id = key
        self.is_locked = not (kwargs.get("locked", False))
        self.images = []
        self.links = {}
        self.latex = {}
        self.nb_links = 0
        self.title('mynotes%s' % key)
        self.attributes("-type", "splash")
        self.attributes("-alpha", CONFIG.getint("General", "opacity") / 100)
        self.focus_force()
        # window geometry
        self.update_idletasks()
        self.geometry(kwargs.get("geometry", '220x235'))
        self.save_geometry = kwargs.get("geometry", '220x235')
        self.update()
        self.rowconfigure(1, weight=1)
        self.minsize(10, 10)
        self.protocol("WM_DELETE_WINDOW", self.hide)

        # --- style
        self.style = Style(self)
        self.style.configure(self.id + ".TCheckbutton", selectbackground="red")
        self.style.map('TEntry', selectbackground=[('!focus', '#c3c3c3')])
        selectbg = self.style.lookup('TEntry', 'selectbackground', ('focus', ))
        self.style.configure("sel.TCheckbutton", background=selectbg)
        self.style.map("sel.TCheckbutton", background=[("active", selectbg)])

        # --- note elements
        # title
        font_title = "%s %s" % (CONFIG.get("Font", "title_family").replace(
            " ", "\ "), CONFIG.get("Font", "title_size"))
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font_title += " "
            font_title += " ".join(style)

        self.title_var = StringVar(master=self,
                                   value=kwargs.get("title", _("Title")))
        self.title_label = Label(self,
                                 textvariable=self.title_var,
                                 anchor="center",
                                 style=self.id + ".TLabel",
                                 font=font_title)
        self.title_entry = Entry(self,
                                 textvariable=self.title_var,
                                 exportselection=False,
                                 justify="center",
                                 font=font_title)
        # buttons/icons
        self.roll = Label(self, image="img_roll", style=self.id + ".TLabel")
        self.close = Label(self, image="img_close", style=self.id + ".TLabel")
        self.im_lock = PhotoImage(master=self, file=IM_LOCK)
        self.cadenas = Label(self, style=self.id + ".TLabel")
        # corner grip
        self.corner = Sizegrip(self, style=self.id + ".TSizegrip")
        # texte
        font_text = "%s %s" % (CONFIG.get("Font", "text_family").replace(
            " ", "\ "), CONFIG.get("Font", "text_size"))
        self.txt = Text(self,
                        wrap='word',
                        undo=True,
                        selectforeground='white',
                        inactiveselectbackground=selectbg,
                        selectbackground=selectbg,
                        tabs=(10, 'right', 21, 'left'),
                        relief="flat",
                        borderwidth=0,
                        highlightthickness=0,
                        font=font_text)
        # tags
        self.txt.tag_configure("bold", font="%s bold" % font_text)
        self.txt.tag_configure("italic", font="%s italic" % font_text)
        self.txt.tag_configure("bold-italic",
                               font="%s bold italic" % font_text)
        self.txt.tag_configure("underline",
                               underline=True,
                               selectforeground="white")
        self.txt.tag_configure("overstrike",
                               overstrike=True,
                               selectforeground="white")
        self.txt.tag_configure("center", justify="center")
        self.txt.tag_configure("left", justify="left")
        self.txt.tag_configure("right", justify="right")
        self.txt.tag_configure("link",
                               foreground="blue",
                               underline=True,
                               selectforeground="white")
        self.txt.tag_configure("list",
                               lmargin1=0,
                               lmargin2=21,
                               tabs=(10, 'right', 21, 'left'))
        self.txt.tag_configure("todolist",
                               lmargin1=0,
                               lmargin2=21,
                               tabs=(10, 'right', 21, 'left'))
        margin = 2 * Font(self, font=font_text).measure("m")
        self.txt.tag_configure("enum",
                               lmargin1=0,
                               lmargin2=margin + 5,
                               tabs=(margin, 'right', margin + 5, 'left'))

        for coul in TEXT_COLORS.values():
            self.txt.tag_configure(coul,
                                   foreground=coul,
                                   selectforeground="white")
            self.txt.tag_configure(coul + "-underline",
                                   foreground=coul,
                                   selectforeground="white",
                                   underline=True)
            self.txt.tag_configure(coul + "-overstrike",
                                   foreground=coul,
                                   overstrike=True,
                                   selectforeground="white")
        # --- menus
        # --- * menu on title
        self.menu = Menu(self, tearoff=False)
        # note color
        menu_note_color = Menu(self.menu, tearoff=False)
        colors = list(COLORS.keys())
        colors.sort()
        for coul in colors:
            menu_note_color.add_command(
                label=coul, command=lambda key=coul: self.change_color(key))
        # category
        self.category = StringVar(
            self,
            kwargs.get("category", CONFIG.get("General", "default_category")))
        self.menu_categories = Menu(self.menu, tearoff=False)
        categories = CONFIG.options("Categories")
        categories.sort()
        for cat in categories:
            self.menu_categories.add_radiobutton(label=cat.capitalize(),
                                                 value=cat,
                                                 variable=self.category,
                                                 command=self.change_category)
        # position: normal, always above, always below
        self.position = StringVar(
            self, kwargs.get("position", CONFIG.get("General", "position")))
        menu_position = Menu(self.menu, tearoff=False)
        menu_position.add_radiobutton(label=_("Always above"),
                                      value="above",
                                      variable=self.position,
                                      command=self.set_position_above)
        menu_position.add_radiobutton(label=_("Always below"),
                                      value="below",
                                      variable=self.position,
                                      command=self.set_position_below)
        menu_position.add_radiobutton(label=_("Normal"),
                                      value="normal",
                                      variable=self.position,
                                      command=self.set_position_normal)
        # mode: note, list, todo list
        menu_mode = Menu(self.menu, tearoff=False)
        self.mode = StringVar(self, kwargs.get("mode", "note"))
        menu_mode.add_radiobutton(label=_("Note"),
                                  value="note",
                                  variable=self.mode,
                                  command=self.set_mode_note)
        menu_mode.add_radiobutton(label=_("List"),
                                  value="list",
                                  variable=self.mode,
                                  command=self.set_mode_list)
        menu_mode.add_radiobutton(label=_("ToDo List"),
                                  value="todolist",
                                  variable=self.mode,
                                  command=self.set_mode_todolist)
        menu_mode.add_radiobutton(label=_("Enumeration"),
                                  value="enum",
                                  variable=self.mode,
                                  command=self.set_mode_enum)

        self.menu.add_command(label=_("Delete"), command=self.delete)
        self.menu.add_cascade(label=_("Category"), menu=self.menu_categories)
        self.menu.add_cascade(label=_("Color"), menu=menu_note_color)
        self.menu.add_command(label=_("Lock"), command=self.lock)
        self.menu.add_cascade(label=_("Position"), menu=menu_position)
        self.menu.add_cascade(label=_("Mode"), menu=menu_mode)

        # --- * menu on main text
        self.menu_txt = Menu(self.txt, tearoff=False)
        # style
        menu_style = Menu(self.menu_txt, tearoff=False)
        menu_style.add_command(label=_("Bold"),
                               command=lambda: self.toggle_text_style("bold"))
        menu_style.add_command(
            label=_("Italic"),
            command=lambda: self.toggle_text_style("italic"))
        menu_style.add_command(label=_("Underline"),
                               command=self.toggle_underline)
        menu_style.add_command(label=_("Overstrike"),
                               command=self.toggle_overstrike)
        # text alignment
        menu_align = Menu(self.menu_txt, tearoff=False)
        menu_align.add_command(label=_("Left"),
                               command=lambda: self.set_align("left"))
        menu_align.add_command(label=_("Right"),
                               command=lambda: self.set_align("right"))
        menu_align.add_command(label=_("Center"),
                               command=lambda: self.set_align("center"))
        # text color
        menu_colors = Menu(self.menu_txt, tearoff=False)
        colors = list(TEXT_COLORS.keys())
        colors.sort()
        for coul in colors:
            menu_colors.add_command(label=coul,
                                    command=lambda key=coul: self.
                                    change_sel_color(TEXT_COLORS[key]))

        # insert
        menu_insert = Menu(self.menu_txt, tearoff=False)
        menu_insert.add_command(label=_("Symbols"), command=self.add_symbols)
        menu_insert.add_command(label=_("Checkbox"), command=self.add_checkbox)
        menu_insert.add_command(label=_("Image"), command=self.add_image)
        menu_insert.add_command(label=_("Date"), command=self.add_date)
        menu_insert.add_command(label=_("Link"), command=self.add_link)
        if LATEX:
            menu_insert.add_command(label="LaTex", command=self.add_latex)

        self.menu_txt.add_cascade(label=_("Style"), menu=menu_style)
        self.menu_txt.add_cascade(label=_("Alignment"), menu=menu_align)
        self.menu_txt.add_cascade(label=_("Color"), menu=menu_colors)
        self.menu_txt.add_cascade(label=_("Insert"), menu=menu_insert)

        # --- restore note content/appearence
        self.color = kwargs.get("color",
                                CONFIG.get("Categories", self.category.get()))
        self.txt.insert('1.0', kwargs.get("txt", ""))
        self.txt.edit_reset()  # clear undo stack
        # restore inserted objects (images and checkboxes)
        # we need to restore objects with increasing index to avoid placment errors
        indexes = list(kwargs.get("inserted_objects", {}).keys())
        indexes.sort(key=sorting)
        for index in indexes:
            kind, val = kwargs["inserted_objects"][index]
            if kind == "checkbox":
                ch = Checkbutton(self.txt,
                                 takefocus=False,
                                 style=self.id + ".TCheckbutton")
                if val:
                    ch.state(("selected", ))
                self.txt.window_create(index, window=ch)

            elif kind == "image":
                if os.path.exists(val):
                    self.images.append(PhotoImage(master=self.txt, file=val))
                    self.txt.image_create(index,
                                          image=self.images[-1],
                                          name=val)
        # restore tags
        for tag, indices in kwargs.get("tags", {}).items():
            if indices:
                self.txt.tag_add(tag, *indices)

        for link in kwargs.get("links", {}).values():
            self.nb_links += 1
            self.links[self.nb_links] = link
            self.txt.tag_bind("link#%i" % self.nb_links,
                              "<Button-1>",
                              lambda e, l=link: open_url(l))

        for img, latex in kwargs.get("latex", {}).items():
            self.latex[img] = latex
            if LATEX:
                self.txt.tag_bind(img,
                                  '<Double-Button-1>',
                                  lambda e, im=img: self.add_latex(im))
        mode = self.mode.get()
        if mode != "note":
            self.txt.tag_add(mode, "1.0", "end")
        self.txt.focus_set()
        self.lock()
        if kwargs.get("rolled", False):
            self.rollnote()
        if self.position.get() == "above":
            self.set_position_above()
        elif self.position.get() == "below":
            self.set_position_below()

        # --- placement
        # titlebar
        if CONFIG.get("General", "buttons_position") == "right":
            # right = lock icon - title - roll - close
            self.columnconfigure(1, weight=1)
            self.roll.grid(row=0, column=2, sticky="e")
            self.close.grid(row=0, column=3, sticky="e", padx=(0, 2))
            self.cadenas.grid(row=0, column=0, sticky="w")
            self.title_label.grid(row=0, column=1, sticky="ew", pady=(1, 0))
        else:
            # left = close - roll - title - lock icon
            self.columnconfigure(2, weight=1)
            self.roll.grid(row=0, column=1, sticky="w")
            self.close.grid(row=0, column=0, sticky="w", padx=(2, 0))
            self.cadenas.grid(row=0, column=3, sticky="e")
            self.title_label.grid(row=0, column=2, sticky="ew", pady=(1, 0))
        # body
        self.txt.grid(row=1,
                      columnspan=4,
                      column=0,
                      sticky="ewsn",
                      pady=(1, 4),
                      padx=4)
        self.corner.lift(self.txt)
        self.corner.place(relx=1.0, rely=1.0, anchor="se")

        # --- bindings
        self.bind("<FocusOut>", self.save_note)
        self.bind('<Configure>', self.bouge)
        self.bind('<Button-1>', self.change_focus, True)
        self.close.bind("<Button-1>", self.hide)
        self.close.bind("<Enter>", self.enter_close)
        self.close.bind("<Leave>", self.leave_close)
        self.roll.bind("<Button-1>", self.rollnote)
        self.roll.bind("<Enter>", self.enter_roll)
        self.roll.bind("<Leave >", self.leave_roll)
        self.title_label.bind("<Double-Button-1>", self.edit_title)
        self.title_label.bind("<ButtonPress-1>", self.start_move)
        self.title_label.bind("<ButtonRelease-1>", self.stop_move)
        self.title_label.bind("<B1-Motion>", self.move)
        self.title_label.bind('<Button-3>', self.show_menu)
        self.title_entry.bind("<Return>",
                              lambda e: self.title_entry.place_forget())
        self.title_entry.bind("<FocusOut>",
                              lambda e: self.title_entry.place_forget())
        self.title_entry.bind("<Escape>",
                              lambda e: self.title_entry.place_forget())
        self.txt.tag_bind("link", "<Enter>",
                          lambda event: self.txt.configure(cursor="hand1"))
        self.txt.tag_bind("link", "<Leave>",
                          lambda event: self.txt.configure(cursor=""))
        self.txt.bind("<FocusOut>", self.save_note)
        self.txt.bind('<Button-3>', self.show_menu_txt)
        # add binding to the existing class binding so that the selected text
        # is erased on pasting
        self.txt.bind("<Control-v>", self.paste)
        self.corner.bind('<ButtonRelease-1>', self.resize)

        # --- keyboard shortcuts
        self.txt.bind('<Control-b>', lambda e: self.toggle_text_style('bold'))
        self.txt.bind('<Control-i>',
                      lambda e: self.toggle_text_style('italic'))
        self.txt.bind('<Control-u>', lambda e: self.toggle_underline())
        self.txt.bind('<Control-r>', lambda e: self.set_align('right'))
        self.txt.bind('<Control-l>', lambda e: self.set_align('left'))

    def __setattr__(self, name, value):
        object.__setattr__(self, name, value)
        if name == "color":
            self.style.configure(self.id + ".TSizegrip", background=self.color)
            self.style.configure(self.id + ".TLabel", background=self.color)
            self.style.configure("close" + self.id + ".TLabel",
                                 background=self.color)
            self.style.configure("roll" + self.id + ".TLabel",
                                 background=self.color)
            self.style.map(self.id + ".TLabel",
                           background=[("active", self.color)])
            self.style.configure(self.id + ".TCheckbutton",
                                 background=self.color)
            self.style.map(self.id + ".TCheckbutton",
                           background=[("active", self.color),
                                       ("disabled", self.color)])
            self.style.map("close" + self.id + ".TLabel",
                           background=[("active", self.color)])
            self.style.map("roll" + self.id + ".TLabel",
                           background=[("active", self.color)])
            self.configure(bg=self.color)
            self.txt.configure(bg=self.color)

    def paste(self, event):
        """ delete selected text before pasting """
        if self.txt.tag_ranges("sel"):
            self.txt.delete("sel.first", "sel.last")

    def delete(self, confirmation=True):
        """ Delete this note """
        if confirmation:
            rep = askokcancel(_("Confirmation"), _("Delete the note?"))
        else:
            rep = True
        if rep:
            del (self.master.note_data[self.id])
            del (self.master.notes[self.id])
            self.master.save()
            self.destroy()

    def lock(self):
        """ Put note in read-only mode to avoid unwanted text insertion """
        if self.is_locked:
            selectbg = self.style.lookup('TEntry', 'selectbackground',
                                         ('focus', ))
            self.txt.configure(state="normal",
                               selectforeground='white',
                               selectbackground=selectbg,
                               inactiveselectbackground=selectbg)
            self.style.configure("sel.TCheckbutton", background=selectbg)
            self.style.map("sel.TCheckbutton",
                           background=[("active", selectbg)])
            self.is_locked = False
            for checkbox in self.txt.window_names():
                ch = self.txt.children[checkbox.split(".")[-1]]
                ch.configure(state="normal")
            self.cadenas.configure(image="")
            self.menu.entryconfigure(3, label=_("Lock"))
            self.title_label.bind("<Double-Button-1>", self.edit_title)
            self.txt.bind('<Button-3>', self.show_menu_txt)
        else:
            self.txt.configure(state="disabled",
                               selectforeground='black',
                               inactiveselectbackground='#c3c3c3',
                               selectbackground='#c3c3c3')
            self.style.configure("sel.TCheckbutton", background='#c3c3c3')
            self.style.map("sel.TCheckbutton",
                           background=[("active", '#c3c3c3')])
            self.cadenas.configure(image=self.im_lock)
            for checkbox in self.txt.window_names():
                ch = self.txt.children[checkbox.split(".")[-1]]
                ch.configure(state="disabled")
            self.is_locked = True
            self.menu.entryconfigure(3, label=_("Unlock"))
            self.title_label.unbind("<Double-Button-1>")
            self.txt.unbind('<Button-3>')
        self.save_note()

    def save_info(self):
        """ Return the dictionnary containing all the note data """
        data = {}
        data["txt"] = self.txt.get("1.0", "end")[:-1]
        data["tags"] = {}
        for tag in self.txt.tag_names():
            if tag not in ["sel", "todolist", "list", "enum"]:
                data["tags"][tag] = [
                    index.string for index in self.txt.tag_ranges(tag)
                ]
        data["title"] = self.title_var.get()
        data["geometry"] = self.save_geometry
        data["category"] = self.category.get()
        data["color"] = self.color
        data["locked"] = self.is_locked
        data["mode"] = self.mode.get()
        data["inserted_objects"] = {}
        data["rolled"] = not self.txt.winfo_ismapped()
        data["position"] = self.position.get()
        data["links"] = {}
        for i, link in self.links.items():
            if self.txt.tag_ranges("link#%i" % i):
                data["links"][i] = link
        data["latex"] = {}
        for img, latex in self.latex.items():
            if self.txt.tag_ranges(img):
                data["latex"][img] = latex
        for image in self.txt.image_names():
            data["inserted_objects"][self.txt.index(image)] = (
                "image", image.split('#')[0])
        for checkbox in self.txt.window_names():
            ch = self.txt.children[checkbox.split(".")[-1]]
            data["inserted_objects"][self.txt.index(checkbox)] = (
                "checkbox", "selected" in ch.state())
        return data

    def change_color(self, key):
        self.color = COLORS[key]
        self.save_note()

    def change_category(self, category=None):
        if category:
            self.category.set(category)
        self.color = CONFIG.get("Categories", self.category.get())
        self.save_note()

    def set_position_above(self):
        e = ewmh.EWMH()
        for w in e.getClientList():
            if w.get_wm_name() == 'mynotes%s' % self.id:
                e.setWmState(w, 1, '_NET_WM_STATE_ABOVE')
                e.setWmState(w, 0, '_NET_WM_STATE_BELOW')
        e.display.flush()
        self.save_note()

    def set_position_below(self):
        e = ewmh.EWMH()
        for w in e.getClientList():
            if w.get_wm_name() == 'mynotes%s' % self.id:
                e.setWmState(w, 0, '_NET_WM_STATE_ABOVE')
                e.setWmState(w, 1, '_NET_WM_STATE_BELOW')
        e.display.flush()
        self.save_note()

    def set_position_normal(self):
        e = ewmh.EWMH()
        for w in e.getClientList():
            if w.get_wm_name() == 'mynotes%s' % self.id:
                e.setWmState(w, 0, '_NET_WM_STATE_BELOW')
                e.setWmState(w, 0, '_NET_WM_STATE_ABOVE')
        e.display.flush()
        self.save_note()

    def set_mode_note(self):
        self.txt.tag_remove("list", "1.0", "end")
        self.txt.tag_remove("todolist", "1.0", "end")
        self.txt.tag_remove("enum", "1.0", "end")
        self.save_note()

    def set_mode_list(self):
        end = int(self.txt.index("end").split(".")[0])
        lines = self.txt.get("1.0", "end").splitlines()
        for i, l in zip(range(1, end), lines):
            # remove checkboxes
            try:
                ch = self.txt.window_cget("%i.0" % i, "window")
                self.txt.children[ch.split('.')[-1]].destroy()
                self.txt.delete("%i.0" % i)
            except TclError:
                # there is no checkbox
                # remove enumeration
                res = re.match('^\t[0-9]+\.\t', l)
                if res:
                    self.txt.delete("%i.0" % i, "%i.%i" % (i, res.end()))
            if self.txt.get("%i.0" % i, "%i.3" % i) != "\t•\t":
                self.txt.insert("%i.0" % i, "\t•\t")
        self.txt.tag_add("list", "1.0", "end")
        self.txt.tag_remove("todolist", "1.0", "end")
        self.txt.tag_remove("enum", "1.0", "end")
        self.save_note()

    def set_mode_enum(self):
        self.txt.configure(autoseparators=False)
        self.txt.edit_separator()
        end = int(self.txt.index("end").split(".")[0])
        lines = self.txt.get("1.0", "end").splitlines()
        for i, l in zip(range(1, end), lines):
            # remove checkboxes
            try:
                ch = self.txt.window_cget("%i.0" % i, "window")
                self.txt.children[ch.split('.')[-1]].destroy()
                self.txt.delete("%i.0" % i)
            except TclError:
                # there is no checkbox
                # remove bullets
                if self.txt.get("%i.0" % i, "%i.3" % i) == "\t•\t":
                    self.txt.delete("%i.0" % i, "%i.3" % i)
            if not re.match('^\t[0-9]+\.', l):
                self.txt.insert("%i.0" % i, "\t0.\t")
        self.txt.tag_add("enum", "1.0", "end")
        self.txt.tag_remove("todolist", "1.0", "end")
        self.txt.tag_remove("list", "1.0", "end")
        self.update_enum()
        self.txt.configure(autoseparators=True)
        self.txt.edit_separator()
        self.save_note()

    def set_mode_todolist(self):
        end = int(self.txt.index("end").split(".")[0])
        lines = self.txt.get("1.0", "end").splitlines()
        for i, l in zip(range(1, end), lines):
            res = re.match('^\t[0-9]+\.\t', l)
            if res:
                self.txt.delete("%i.0" % i, "%i.%i" % (i, res.end()))
            elif self.txt.get("%i.0" % i, "%i.3" % i) == "\t•\t":
                self.txt.delete("%i.0" % i, "%i.3" % i)
            try:
                ch = self.txt.window_cget("%i.0" % i, "window")
            except TclError:
                ch = Checkbutton(self.txt,
                                 takefocus=False,
                                 style=self.id + ".TCheckbutton")
                self.txt.window_create("%i.0" % i, window=ch)
        self.txt.tag_remove("enum", "1.0", "end")
        self.txt.tag_remove("list", "1.0", "end")
        self.txt.tag_add("todolist", "1.0", "end")
        self.save_note()

    # --- bindings
    def enter_roll(self, event):
        """ mouse is over the roll icon """
        self.roll.configure(image="img_rollactive")

    def leave_roll(self, event):
        """ mouse leaves the roll icon """
        self.roll.configure(image="img_roll")

    def enter_close(self, event):
        """ mouse is over the close icon """
        self.close.configure(image="img_closeactive")

    def leave_close(self, event):
        """ mouse leaves the close icon """
        self.close.configure(image="img_close")

    def change_focus(self, event):
        if not self.is_locked:
            event.widget.focus_force()

    def show_menu(self, event):
        self.menu.tk_popup(event.x_root, event.y_root)

    def show_menu_txt(self, event):
        self.menu_txt.tk_popup(event.x_root, event.y_root)

    def resize(self, event):
        self.save_geometry = self.geometry()

    def bouge(self, event):
        geo = self.geometry().split("+")[1:]
        self.save_geometry = self.save_geometry.split("+")[0] \
                             + "+%s+%s" % tuple(geo)

    def edit_title(self, event):
        self.title_entry.place(x=self.title_label.winfo_x() + 5,
                               y=self.title_label.winfo_y(),
                               anchor="nw",
                               width=self.title_label.winfo_width() - 10)

    def start_move(self, event):
        self.x = event.x
        self.y = event.y
        self.configure(cursor='fleur')

    def stop_move(self, event):
        self.x = None
        self.y = None
        self.configure(cursor='')

    def move(self, event):
        if self.x is not None and self.y is not None:
            deltax = event.x - self.x
            deltay = event.y - self.y
            x = self.winfo_x() + deltax
            y = self.winfo_y() + deltay
            self.geometry("+%s+%s" % (x, y))

    def save_note(self, event=None):
        data = self.save_info()
        data["visible"] = True
        self.master.note_data[self.id] = data
        self.master.save()

    def rollnote(self, event=None):
        if self.txt.winfo_ismapped():
            self.txt.grid_forget()
            self.corner.place_forget()
            self.geometry("%sx22" % self.winfo_width())
        else:
            self.txt.grid(row=1,
                          columnspan=4,
                          column=0,
                          sticky="ewsn",
                          pady=(1, 4),
                          padx=4)
            self.corner.place(relx=1.0, rely=1.0, anchor="se")
            self.geometry(self.save_geometry)
        self.save_note()

    def hide(self, event=None):
        """ Hide note (can be displayed again via app menu) """
        cat = self.category.get()
        self.master.add_note_to_menu(self.id,
                                     self.title_var.get().strip(), cat)
        data = self.save_info()
        data["visible"] = False
        self.master.note_data[self.id] = data
        del (self.master.notes[self.id])
        self.master.save()
        self.destroy()

    # --- Settings update
    def update_title_font(self):
        font = "%s %s" % (CONFIG.get("Font", "title_family").replace(
            " ", "\ "), CONFIG.get("Font", "title_size"))
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font += " "
            font += " ".join(style)
        self.title_label.configure(font=font)

    def update_text_font(self):
        font = "%s %s" % (CONFIG.get("Font", "text_family").replace(
            " ", "\ "), CONFIG.get("Font", "text_size"))
        self.txt.configure(font=font)
        self.txt.tag_configure("bold", font="%s bold" % font)
        self.txt.tag_configure("italic", font="%s italic" % font)
        self.txt.tag_configure("bold-italic", font="%s bold italic" % font)
        margin = 2 * Font(self, font=font).measure("m")
        self.txt.tag_configure("enum",
                               lmargin1=0,
                               lmargin2=margin + 5,
                               tabs=(margin, 'right', margin + 5, 'left'))

    def update_menu_cat(self, categories):
        """ Update the category submenu """
        self.menu_categories.delete(0, "end")
        for cat in categories:
            self.menu_categories.add_radiobutton(label=cat.capitalize(),
                                                 value=cat,
                                                 variable=self.category,
                                                 command=self.change_category)

    def update_titlebar(self):
        if CONFIG.get("General", "buttons_position") == "right":
            # right = lock icon - title - roll - close
            self.columnconfigure(1, weight=1)
            self.columnconfigure(2, weight=0)
            self.roll.grid_configure(row=0, column=2, sticky="e")
            self.close.grid_configure(row=0, column=3, sticky="e", padx=(0, 2))
            self.cadenas.grid_configure(row=0, column=0, sticky="w")
            self.title_label.grid_configure(row=0,
                                            column=1,
                                            sticky="ew",
                                            pady=(1, 0))
        else:
            # left = close - roll - title - lock icon
            self.columnconfigure(2, weight=1)
            self.columnconfigure(1, weight=0)
            self.roll.grid_configure(row=0, column=1, sticky="w")
            self.close.grid_configure(row=0, column=0, sticky="w", padx=(2, 0))
            self.cadenas.grid_configure(row=0, column=3, sticky="e")
            self.title_label.grid_configure(row=0,
                                            column=2,
                                            sticky="ew",
                                            pady=(1, 0))

    # --- Text edition
    def add_link(self):
        def ok(eveny=None):
            lien = link.get()
            txt = text.get()
            if lien:
                if not txt:
                    txt = lien
                self.nb_links += 1
                if self.txt.tag_ranges("sel"):
                    index = self.txt.index("sel.first")
                    self.txt.delete('sel.first', 'sel.last')
                else:
                    index = "current"
                tags = self.txt.tag_names(index) + ("link",
                                                    "link#%i" % self.nb_links)
                self.txt.insert("current", txt, tags)
                if not lien[:4] == "http":
                    lien = "http://" + lien
                self.links[self.nb_links] = lien
                self.txt.tag_bind("link#%i" % self.nb_links, "<Button-1>",
                                  lambda e: open_url(lien))
            top.destroy()

        top = Toplevel(self)
        top.transient(self)
        top.update_idletasks()
        top.geometry("+%i+%i" % top.winfo_pointerxy())
        top.grab_set()
        top.resizable(True, False)
        top.title(_("Link"))
        top.columnconfigure(1, weight=1)
        text = Entry(top)
        link = Entry(top)
        if self.txt.tag_ranges('sel'):
            txt = self.txt.get('sel.first', 'sel.last')
        else:
            txt = ''
        text.insert(0, txt)
        text.icursor("end")
        Label(top, text=_("Text")).grid(row=0,
                                        column=0,
                                        sticky="e",
                                        padx=4,
                                        pady=4)
        Label(top, text=_("Link")).grid(row=1,
                                        column=0,
                                        sticky="e",
                                        padx=4,
                                        pady=4)
        text.grid(row=0, column=1, sticky="ew", padx=4, pady=4)
        link.grid(row=1, column=1, sticky="ew", padx=4, pady=4)
        Button(top, text="Ok", command=ok).grid(row=2,
                                                columnspan=2,
                                                padx=4,
                                                pady=4)

        text.focus_set()
        text.bind("<Return>", ok)
        link.bind("<Return>", ok)

    def add_checkbox(self):
        ch = Checkbutton(self.txt,
                         takefocus=False,
                         style=self.id + ".TCheckbutton")
        self.txt.window_create("current", window=ch)

    def add_date(self):
        self.txt.insert("current", strftime("%x"))

    def add_latex(self, img_name=None):
        def ok(event):
            latex = r'%s' % text.get()
            if latex:
                if img_name is None:
                    l = [
                        int(os.path.splitext(f)[0])
                        for f in os.listdir(PATH_LATEX)
                    ]
                    l.sort()
                    if l:
                        i = l[-1] + 1
                    else:
                        i = 0
                    img = "%i.png" % i
                    self.txt.tag_bind(img, '<Double-Button-1>',
                                      lambda e: self.add_latex(img))
                    self.latex[img] = latex

                else:
                    img = img_name
                im = os.path.join(PATH_LATEX, img)
                try:
                    math_to_image(latex,
                                  im,
                                  fontsize=CONFIG.getint("Font", "text_size") -
                                  2)
                    self.images.append(PhotoImage(file=im, master=self))
                    if self.txt.tag_ranges("sel"):
                        index = self.txt.index("sel.first")
                        self.txt.delete('sel.first', 'sel.last')
                    else:
                        index = self.txt.index("current")
                    self.txt.image_create(index,
                                          image=self.images[-1],
                                          name=im)
                    self.txt.tag_add(img, index)
                    top.destroy()

                except Exception as e:
                    showerror(_("Error"), str(e))

        top = Toplevel(self)
        top.transient(self)
        top.update_idletasks()
        top.geometry("+%i+%i" % top.winfo_pointerxy())
        top.grab_set()
        top.resizable(True, False)
        top.title("LaTex")
        text = Entry(top, justify='center')
        if img_name is not None:
            text.insert(0, self.latex[img_name])
        else:
            if self.txt.tag_ranges('sel'):
                text.insert(0, self.txt.get('sel.first', 'sel.last'))
            else:
                text.insert(0, '$$')
                text.icursor(1)

        text.pack(fill='x', expand=True)
        text.bind('<Return>', ok)
        text.focus_set()

    def add_image(self):
        fichier = askopenfilename(defaultextension=".png",
                                  filetypes=[("PNG", "*.png")],
                                  initialdir="",
                                  initialfile="",
                                  title=_('Select PNG image'))
        if os.path.exists(fichier):
            self.images.append(PhotoImage(master=self.txt, file=fichier))
            self.txt.image_create("current",
                                  image=self.images[-1],
                                  name=fichier)
        elif fichier:
            showerror("Erreur", "L'image %s n'existe pas" % fichier)

    def add_symbols(self):
        symbols = pick_symbol(
            self,
            CONFIG.get("Font", "text_family").replace(" ", "\ "),
            CONFIG.get("General", "symbols"))
        self.txt.insert("current", symbols)

    def toggle_text_style(self, style):
        '''Toggle the style of the selected text'''
        if self.txt.tag_ranges("sel"):
            current_tags = self.txt.tag_names("sel.first")
            if style in current_tags:
                # first char is in style so 'unstyle' the range
                self.txt.tag_remove(style, "sel.first", "sel.last")
            elif style == "bold" and "bold-italic" in current_tags:
                self.txt.tag_remove("bold-italic", "sel.first", "sel.last")
                self.txt.tag_add("italic", "sel.first", "sel.last")
            elif style == "italic" and "bold-italic" in current_tags:
                self.txt.tag_remove("bold-italic", "sel.first", "sel.last")
                self.txt.tag_add("bold", "sel.first", "sel.last")
            elif style == "bold" and "italic" in current_tags:
                self.txt.tag_remove("italic", "sel.first", "sel.last")
                self.txt.tag_add("bold-italic", "sel.first", "sel.last")
            elif style == "italic" and "bold" in current_tags:
                self.txt.tag_remove("bold", "sel.first", "sel.last")
                self.txt.tag_add("bold-italic", "sel.first", "sel.last")
            else:
                # first char is normal, so apply style to the whole selection
                self.txt.tag_add(style, "sel.first", "sel.last")

    def toggle_underline(self):
        if self.txt.tag_ranges("sel"):
            current_tags = self.txt.tag_names("sel.first")
            if "underline" in current_tags:
                # first char is in style so 'unstyle' the range
                self.txt.tag_remove("underline", "sel.first", "sel.last")
                for coul in TEXT_COLORS.values():
                    self.txt.tag_remove(coul + "-underline", "sel.first",
                                        "sel.last")
            else:
                self.txt.tag_add("underline", "sel.first", "sel.last")
                for coul in TEXT_COLORS.values():
                    r = text_ranges(self.txt, coul, "sel.first", "sel.last")
                    if r:
                        for deb, fin in zip(r[::2], r[1::2]):
                            self.txt.tag_add(coul + "-underline", "sel.first",
                                             "sel.last")

    def toggle_overstrike(self):
        if self.txt.tag_ranges("sel"):
            current_tags = self.txt.tag_names("sel.first")
            if "overstrike" in current_tags:
                # first char is in style so 'unstyle' the range
                self.txt.tag_remove("overstrike", "sel.first", "sel.last")
                for coul in TEXT_COLORS.values():
                    self.txt.tag_remove(coul + "-overstrike", "sel.first",
                                        "sel.last")
            else:
                self.txt.tag_add("overstrike", "sel.first", "sel.last")
                for coul in TEXT_COLORS.values():
                    r = text_ranges(self.txt, coul, "sel.first", "sel.last")
                    if r:
                        for deb, fin in zip(r[::2], r[1::2]):
                            self.txt.tag_add(coul + "-overstrike", "sel.first",
                                             "sel.last")

    def change_sel_color(self, color):
        """ change the color of the selection """
        if self.txt.tag_ranges("sel"):
            for coul in TEXT_COLORS.values():
                self.txt.tag_remove(coul, "sel.first", "sel.last")
                self.txt.tag_remove(coul + "-overstrike", "sel.first",
                                    "sel.last")
                self.txt.tag_remove(coul + "-underline", "sel.first",
                                    "sel.last")
            if not color == "black":
                self.txt.tag_add(color, "sel.first", "sel.last")
                underline = text_ranges(self.txt, "underline", "sel.first",
                                        "sel.last")
                overstrike = text_ranges(self.txt, "overstrike", "sel.first",
                                         "sel.last")

                for deb, fin in zip(underline[::2], underline[1::2]):
                    self.txt.tag_add(color + "-underline", deb, fin)
                for deb, fin in zip(overstrike[::2], overstrike[1::2]):
                    self.txt.tag_add(color + "-overstrike", deb, fin)

    def set_align(self, alignment):
        """ Align the text according to alignment (left, right, center) """
        if self.txt.tag_ranges("sel"):
            line = self.txt.index("sel.first").split(".")[0]
            line2 = self.txt.index("sel.last").split(".")[0]
            deb, fin = line + ".0", line2 + ".end"
            if not "\t" in self.txt.get(deb, fin):
                # tabulations don't support right/center alignment
                # remove old alignment tag
                self.txt.tag_remove("left", deb, fin)
                self.txt.tag_remove("right", deb, fin)
                self.txt.tag_remove("center", deb, fin)
                # set new alignment tag
                self.txt.tag_add(alignment, deb, fin)

    def update_enum(self):
        """ update enumeration numbers """
        lines = self.txt.get("1.0", "end").splitlines()
        indexes = []
        for i, l in enumerate(lines):
            res = re.match('^\t[0-9]+\.\t', l)
            res2 = re.match('^\t[0-9]+\.', l)
            if res:
                indexes.append((i, res.end()))
            elif res2:
                indexes.append((i, res2.end()))
        for j, (i, end) in enumerate(indexes):
            self.txt.delete("%i.0" % (i + 1), "%i.%i" % (i + 1, end))
            self.txt.insert("%i.0" % (i + 1), "\t%i.\t" % (j + 1))
        self.txt.tag_add("enum", "1.0", "end")
예제 #21
0
class LoginFrame:
    def __init__(self, url):
        self.url = url

        self.root = Tk()
        self.root.title("验证码")

        while True:
            try:
                image_bytes = urlopen(self.url).read()
                break
            except socket.timeout:
                print('获取验证码超时:%s\r\n重新获取.' % (self.url))
                continue
            except urllib.error.URLError as e:
                if isinstance(e.reason, socket.timeout):
                    print('获取验证码超时:%s\r\n重新获取.' % (self.url))
                    continue
        # internal data file
        data_stream = io.BytesIO(image_bytes)
        # open as a PIL image object
        self.pil_image = Image.open(data_stream)
        # convert PIL image object to Tkinter PhotoImage object
        self.tk_image = ImageTk.PhotoImage(self.pil_image)
        self.label = Label(self.root, image=self.tk_image, background='brown')
        self.label.pack(padx=5, pady=5)
        self.button = Button(self.root, text="刷新验证码", command=self.refreshImg)
        self.button.pack(padx=5, pady=5)

        randCodeLable = Label(self.root, text="验证码:")
        randCodeLable.pack(padx=5, pady=5)
        self.randCode = Entry(self.root)
        self.randCode.pack(padx=5, pady=5)

        self.loginButton = Button(self.root, text="登录", default=tkinter.ACTIVE)
        self.loginButton.pack(padx=5, pady=5)

    def refreshImg(self):
        url = self.url
        while True:
            try:
                image_bytes = urlopen(url).read()
                data_stream = io.BytesIO(image_bytes)
                self.pil_image = Image.open(data_stream)
                self.tk_image = ImageTk.PhotoImage(self.pil_image)
                self.label.configure(image=self.tk_image)
                break
            except socket.timeout:
                print('获取验证码超时:%s\r\n重新获取.' % (self.url))
                continue
            except urllib.error.URLError as e:
                if isinstance(e.reason, socket.timeout):
                    print('获取验证码超时:%s\r\n重新获取.' % (self.url))
                    continue

    # 显示URL地址指定图片
    def show(self):
        w, h = self.pil_image.size

        # 窗体居中
        width = w + 100
        height = h + 160
        ws = self.root.winfo_screenwidth()
        hs = self.root.winfo_screenheight()
        x = int((ws / 2) - (width / 2))
        y = int((hs / 2) - (height / 2))
        self.root.geometry('{}x{}+{}+{}'.format(width, height, x, y))
        # 禁止窗体改变大小
        self.root.resizable(False, False)
        self.root.mainloop()


    def quit(self):
        self.root.destroy()
예제 #22
0
class ErrorSurfaceFrame(LabelFrame):
	
	def __init__(self,parent):
		LabelFrame.__init__(self, parent, borderwidth=0)
		
		entryWidth = 7
		xPad1 = 30
		xPad2 = 5
		
		self.errorXLowerLimitL = Label(self)
		self.errorXLowerLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorXLowerLimitL.grid(row=0,column=0,padx=(10,xPad2),pady=5,sticky="W")
		self.errorXLowerLimitE.grid(row=0,column=1,padx=(xPad2,xPad1),pady=5)
		
		self.errorXUpperLimitL = Label(self)
		self.errorXUpperLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorXUpperLimitL.grid(row=1,column=0,padx=(10,xPad2),pady=5,sticky="W")
		self.errorXUpperLimitE.grid(row=1,column=1,padx=(xPad2,xPad1),pady=5)
		
		self.errorYLowerLimitL = Label(self)
		self.errorYLowerLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorYLowerLimitL.grid(row=0,column=2,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorYLowerLimitE.grid(row=0,column=3,padx=(xPad2,xPad1),pady=5)
		
		self.errorYUpperLimitL = Label(self)
		self.errorYUpperLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorYUpperLimitL.grid(row=1,column=2,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorYUpperLimitE.grid(row=1,column=3,padx=(xPad2,xPad1),pady=5)
		
		self.errorResolutionL = Label(self,text="Resolution: ")
		self.errorResolutionE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorResolutionE.insert(0,ERROR_SURFACE_DEFAULT_RESOLUTION)
		self.errorResolutionL.grid(row=0,column=4,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorResolutionE.grid(row=0,column=5,padx=(xPad2,xPad1),pady=5,sticky="E")
		
		self.errorSurfaceB = Button(self,text=" Calculate error surface ")
		self.errorSurfaceB.grid(row=1,column=4,columnspan=2,padx=(xPad1,xPad1),sticky="EW")
		self.errorSurfaceB.configure(state=tkinter.ACTIVE)
		
	def update(self,xSymbol,ySymbol,xLL,xUL,yLL,yUL):
		
		self.xSymbol = xSymbol
		self.ySymbol = ySymbol
		
		self.errorXLowerLimitL.configure(text="Lower limit ("+self.xSymbol+"): ")
		self.errorXLowerLimitE.insertNew(xLL)
		
		self.errorXUpperLimitL.configure(text="Upper limit ("+self.xSymbol+"): ")
		self.errorXUpperLimitE.insertNew(xUL)
		
		self.errorYLowerLimitL.configure(text="Lower limit ("+self.ySymbol+"): ")
		self.errorYLowerLimitE.insertNew(yLL)
		
		self.errorYUpperLimitL.configure(text="Upper limit ("+self.ySymbol+"): ")
		self.errorYUpperLimitE.insertNew(yUL)
		
	def getSurfaceParameters(self):
		
		xLowerLimit = helper_functions.validateValue(self.errorXLowerLimitE.get(),
									self.xSymbol + " lower limit must be a positive number",
									"float",
									lowerBound=0)
		xUpperLimit = helper_functions.validateValue(self.errorXUpperLimitE.get(),
									self.xSymbol + " upper limit must be greater than the lower limit",
									"float",
									strictLowerBound=xLowerLimit)
		yLowerLimit = helper_functions.validateValue(self.errorYLowerLimitE.get(),
									self.ySymbol + " lower limit must be a positive number",
									"float",
									lowerBound=0)
		yUpperLimit = helper_functions.validateValue(self.errorYUpperLimitE.get(),
									self.ySymbol + " upper limit must be greater than the lower limit",
									"float",
									strictLowerBound=yLowerLimit)
		resolution = helper_functions.validateValue(self.errorResolutionE.get(),
								   "Resolution must be " + str(ERROR_SURFACE_MIN_RESOLUTION) + " \u2264 x \u2264 " + str(ERROR_SURFACE_MAX_RESOLUTION),
								   "int",
								   lowerBound=ERROR_SURFACE_MIN_RESOLUTION,
								   upperBound=ERROR_SURFACE_MAX_RESOLUTION)
		
		return [xLowerLimit,xUpperLimit,yLowerLimit,yUpperLimit,resolution]
		
	def clear(self):
		self.errorXLowerLimitE.insertNew("")
		self.errorXUpperLimitE.insertNew("")
		self.errorYLowerLimitE.insertNew("")
		self.errorYUpperLimitE.insertNew("")
예제 #23
0
class GUI(Frame):
    def __init__(self, jointNumber):
        super().__init__()
        self.jointNumber = jointNumber
        self.initGUI()

    def quit(self):
        self.master.quit()
        self.master.destroy()

    def initGUI(self):
        
        self.master.title('VRGlove')
        self.master.geometry('1280x720')
        self.pack(fill=BOTH, expand=True)

        # Color list: https://xkcd.com/color/rgb/
        self.colorList = ['xkcd:purple', 'xkcd:green', \
        'xkcd:blue', 'xkcd:pink', 'xkcd:brown', 'xkcd:red', \
        'xkcd:light blue', 'xkcd:teal', 'xkcd:orange', 'xkcd:light green', \
        'xkcd:magenta', 'xkcd:yellow', 'xkcd:cyan', 'xkcd:grey', \
        'xkcd:lime green', 'xkcd:light purple', 'xkcd:violet', 'xkcd:dark green', \
        'xkcd:turquoise', 'xkcd:lavender', 'xkcd:dark blue', 'xkcd:tan']

        ##################################################

        # frameCalibrate = Frame(self)
        # frameCalibrate.pack(side=RIGHT, fill=Y)

        # labelPredict = Label(frameCalibrate, text='CALIBRATE', width=32)
        # labelPredict.pack(side=TOP, padx=5, pady=5)
        s = Style()
        s.configure('My.TFrame', background='green')
        ##################################################

        framePredict = Frame(self,style='My.TFrame')
        framePredict.pack(side=RIGHT, fill=Y)

        labelPredict = Label(framePredict, text='SETTING')
        labelPredict.pack(side=TOP, padx=5, pady=5)

        # self.textPredictResult = Label(framePredict, text='N/A', font=("Arial", 50), foreground='red')
        # self.textPredictResult.pack(side=TOP, padx=5, pady=50)

        labelTrainer = Label(framePredict, text='TRAINER',style='My.TFrame')
        labelTrainer.pack(side=TOP, padx=5, pady=100)

        labelTrainingCharacter = Label(framePredict, text='Training character', )
        labelTrainingCharacter.pack(side=TOP, padx=5, pady=5)

        entryTrainingCharacter = Entry(framePredict, width=5, justify=CENTER)
        entryTrainingCharacter.pack(side=TOP, padx=5, pady=5)
        entryTrainingCharacter.insert(END, '2')

        labelSampleCount = Label(framePredict, text='Sample count')
        labelSampleCount.pack(side=TOP, padx=5, pady=5)

        self.textSampleCount = Label(framePredict, text=0)
        self.textSampleCount.pack(side=TOP, padx=5, pady=5)

        def sample():
            global threadCollectData
            global threadPredict
            if not threadCollectData.collectSampleEnable:
                threadPredict.predictEnable=False
                threadCollectData.sampleCount = 0
                threadCollectData.collectSampleEnable = True
                threadCollectData.trainingCharacter = entryTrainingCharacter.get()
                print('\nStarted sampling!')
                print('Sampling character: ' + threadCollectData.trainingCharacter + '\n')
                buttonSample.configure(text='Stop sampling')
            else:
                threadPredict.predictEnable=True
                threadCollectData.collectSampleEnable = False
                print('\nStopped sampling!\n')
                buttonSample.configure(text='Start sampling')

        buttonSample = Button(framePredict, text='Start sampling', command=sample, width=15)
        buttonSample.pack(side=TOP, padx=5, pady=5)

        def trainModel():
            global threadPredict
            threadPredict.predictEnable = False
            global threadCollectData
            if threadQuatProcess.collectSampleEnable:
                sample()
            global threadTrainingModel
            threadTrainingModel.train()
            statusText = 'Training done!\nTime elapsed: ' + str(threadTrainingModel.timeElapsed) + ' ms\n'
            statusText += 'Testing done!\nTraining accuracy: ' + str(threadTrainingModel.trainScore) + '%\n'
            statusText += 'Saving done!\nFilename: ' + threadTrainingModel.modelFile
            labelTrainingStatus.configure(text=statusText)
            threadPredict.predictEnable = True

        buttonTrain = Button(framePredict, text='Train model', command=trainModel, width=15)
        buttonTrain.pack(side=TOP, padx=5, pady=5)

        labelTrainingStatus = Label(framePredict, text='Ready')
        labelTrainingStatus.pack(side=TOP, padx=5, pady=5)

        def PredictCmd():
            global threadPredict                
            if threadPredict.predictEnable and not threadPredict.MultiplePredictEnable:
                start=timer()
                jointAngle=jointAngleRight+jointAngleLeft 
                threadPredict.Count=threadPredict.Count+1
                temp = np.array(jointAngle).reshape(1, -1)
                yPredict = threadPredict.loadedModel.predict(temp)
                img=mpimg.imread(ImageIndex[int(yPredict)])
                imgplot=plt.imshow(img)
                plt.show()
                end=timer()
                predictTime=end-start
                predictTime=round(predictTime,3)
          


                #self.textPredictResult.configure(text=predictTime)
            else:
                messagebox.showwarning("Infor", "Another process is running")
            
                
       

        def MultiplePredictCmd():
            global threadPredict
            if threadPredict.predictEnable:
                if not threadPredict.MultiplePredictEnable:
                    threadPredict.MultiplePredictEnable = True
                    buttonMultiplePredict.configure(text='Stop')
                    threadPredict.start()                                                
                else:
                    threadPredict.MultiplePredictEnable = False
                    buttonMultiplePredict.configure(text='Multiple Predict')
                    #threadPredict = ThreadPredict('finalizedModel.sav')
                    threadPredict = ThreadPredict('twoHandModel.h5')
        
       
        

        

        ##################################################

        frameGraph = Frame(self,style='My.TFrame')
        frameGraph.pack(side=RIGHT, fill=BOTH, expand=True)

        labelGraph = Label(frameGraph, text='JOINT ANGLES')
        labelGraph.pack(side=TOP, padx=5, pady=5)

        buttonPredict = Button(frameGraph, text='Single Predict', command=PredictCmd, width=15)
        buttonPredict.pack(side=BOTTOM, padx=5, pady=5)

        buttonMultiplePredict= Button(frameGraph, text='Multiple Predict', command=MultiplePredictCmd, width=15)
        buttonMultiplePredict.pack(side=BOTTOM, padx=5, pady=5)
        

        self.fig = plt.Figure(dpi = 100)
        ax = self.fig.add_subplot(111)
        ax.set(xlim = (0, 100), ylim = (-100, 100))
        canvas = FigureCanvasTkAgg(self.fig, frameGraph)
        canvas.get_tk_widget().pack(fill=BOTH, padx=5, expand=True)

        self.x = np.arange(0, 101, 1)
        self.y = []
        self.line = []
        for i in range(jointNumber):
            self.y.append([])
            for j in range(101):
                self.y[i].append(0)
            self.line.append(ax.plot(self.x, self.y[i], color=self.colorList[i], lw=1)[0])
        #########################################################
        frameMultiplePredict = Frame(self,style='My.TFrame')
        frameMultiplePredict.pack(side=RIGHT, fill=BOTH)

        LabelMultiplePredict = Label(frameMultiplePredict, text='MULTIPLE PREDICT')
        LabelMultiplePredict.pack(side=TOP, padx=5, pady=5)

        self.predictResult = Text(frameMultiplePredict, width=50,  font=("Arial",15), foreground='black')
        self.predictResult.pack(fill=BOTH, padx=5, expand=True)

        TimeLabel= Label(frameMultiplePredict, text='Time Respone', font=("Arial", 15), foreground='red')
        TimeLabel.pack(side=TOP, padx=5, pady=5)

        def UpCmd():
            global threadPredict
            global timeConstant
            if timeConstant<10:
                timeConstant=timeConstant+0.5
        
            threadPredict.timeConstant=timeConstant
            self.Time.configure(text=timeConstant)

        buttonUp=Button(frameMultiplePredict, command=UpCmd, text ='+', width=2)                    
        buttonUp.pack(side=TOP, padx=5, pady=5)

        self.Time= Label(frameMultiplePredict, text='0.5')
        self.Time.pack(side=TOP, padx=5, pady=5)

        def DownCmd():
            global threadPredict
            global timeConstant
            if timeConstant>0.5:
                timeConstant=timeConstant-0.5
            
            threadPredict.timeConstant=timeConstant
            self.Time.configure(text=timeConstant)
        
        buttonDown=Button(frameMultiplePredict, command=DownCmd, text ='-', width=2)                    
        buttonDown.pack(side=TOP, padx=5, pady=5)


        
        

        # buttonPredict = Button(frameGraph, Text='Predict')
        # buttonPredict.pack(side=TOP ,padx=5, pady=5)

        # serialPort = StringVar(frameGraph)
        # serialPort.set('/dev/rfcomm0')
        # serialPortList = ['/dev/rfcomm0', '/dev/ttyACM0', '/dev/ttyACM1']
        # serialPortOption = OptionMenu(frameGraph, serialPort, serialPortList[0], *serialPortList)
        # serialPortOption.pack(side=LEFT, padx=10, pady=10)

        # def connect():
        #     global threadQuatProcess
        #     threadQuatProcess.receiveQuatEnable = False
        #     threadQuatProcess.changeSerialPort(serialPort.get())
        #     threadQuatProcess.receiveQuatEnable = True
        #     print('\nConnected to ' + threadQuatProcess.serialPort + '!\n')

        # buttonConnect = Button(frameGraph, text='Connect', command=connect)
        # buttonConnect.pack(side=TOP, padx=5, pady=5)

        
    def updateGraph(self, i):
        for i in range(jointNumber):
            global jointAngleRight
            self.y[i].pop(0)
            self.y[i].append(jointAngleRight[i]*180.0/3.1416)
            # self.y[i].append(randint(-90, 90))
            self.line[i].set_ydata(self.y[i])
        return self.line[i],

    def updateParameters(self):
        global threadPredict
        global threadCollectData
        #self.textPredictResult.configure(text=threadPredict.predictResult)
        self.textSampleCount.configure(text=threadCollectData.sampleCount)
        self.master.after(100, self.updateParameters)

    def run(self):
        self.ani = animation.FuncAnimation(self.fig, self.updateGraph, interval=100)
        self.master.after(100, self.updateParameters)
        self.master.mainloop()
예제 #24
0
class Progression(Frame):
    """Class to display the progress in filling the puzzle."""

    def __init__(self, master, number, **kwargs):
        kwargs.setdefault('width', 34)
        kwargs.setdefault('height', 34)
        kwargs.setdefault('style', 'case.TFrame')
        Frame.__init__(self, master, **kwargs)
        self.grid_propagate(False)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        self.number = number
        self._nb = 0

        self.label_number = Label(self, style='case.TLabel', text=str(number),
                                  font='Arial 16')
        self.label_nb = Label(self, style='case.TLabel', text='0', font='Arial 9')
        self.label_number.grid(row=0, column=0, sticky='e', padx=0)
        self.label_nb.grid(row=0, column=1, sticky='n')

    @property
    def nb(self):
        return self._nb

    @nb.setter
    def nb(self, value):
        self._nb = value
        self.label_nb.configure(text=str(self._nb))

        if self._nb < 9:
            self.configure(style='case.TFrame')
            self.label_number.configure(style='case.TLabel')
            self.label_nb.configure(style='case.TLabel')
        elif self._nb == 9:
            self.configure(style='case_init.TFrame')
            self.label_number.configure(style='case_init.TLabel')
            self.label_nb.configure(style='case_init.TLabel')
        else:
            self.configure(style='erreur.TFrame')
            self.label_number.configure(style='erreur.TLabel')
            self.label_nb.configure(style='erreur.TLabel')
예제 #25
0
class Search(Module):
    def __init__(self, app):
        self.app = app
        self.window = None

        self.context_size = 3
        self.results = []
        self.regex = StringVar(self.app)

        # if anything ever changes the contents of any intervals
        # it should call SearchModule.loadIntervals()
        self.intervals = []
        self.loadIntervals()

    def handleClose(self, event=None):
        self.window.destroy()
        self.window = None

    def createWindow(self):
        self.window = Toplevel(self.app)
        self.window.title('Search')
        self.window.protocol("WM_DELETE_WINDOW", self.handleClose)
        self.input = Entry(self.window, textvariable=self.regex)
        self.input.grid(row=0, column=0)
        self.input.bind('<Return>', self.search)
        self.input.bind('<Escape>', lambda ev: self.window.focus())
        self.searchButton = Button(self.window,
                                   text='Search',
                                   command=self.search,
                                   takefocus=0)
        self.searchButton.grid(row=0, column=1)
        self.resultCount = Label(self.window, text='0 results')
        self.resultCount.grid(row=0, column=2)
        cols = ('File', 'Tier', 'Time', 'Text')
        self.scroll = Scrollbar(self.window, orient='vertical')
        self.resultList = Treeview(self.window,
                                   columns=cols,
                                   show="headings",
                                   yscrollcommand=self.scroll.set,
                                   selectmode='browse')
        self.scroll.config(command=self.resultList.yview)
        for col in cols:
            self.resultList.heading(col, text=col)
        self.resultList.grid(row=2, column=0, columnspan=3, sticky='news')
        self.resultList.bind('<Double-1>', self.onClick)
        Grid.rowconfigure(self.window, 2, weight=1)
        Grid.columnconfigure(self.window, 0, weight=1)
        self.scroll.grid(row=2, column=3, sticky='ns')

    def openSearch(self):
        if self.window == None:
            self.createWindow()
        self.window.lift()
        self.input.focus()

    def loadIntervals(self):
        filecount = len(self.app.Data.getTopLevel('files'))
        self.intervals = []
        for f in range(filecount):
            filename = self.app.Data.getFileLevel('name', f)
            tg = self.app.Data.checkFileLevel('.TextGrid',
                                              f,
                                              shoulderror=False)
            if tg:
                grid = self.app.TextGrid.fromFile(tg)
                for tier in grid:
                    if TextGrid.isIntervalTier(tier):
                        for el in tier:
                            if el.mark:
                                self.intervals.append(
                                    (el, tier.name, filename))

    def search(self, event=None):
        if self.regex.get() == '':
            self.results = []
        else:
            pat = re.compile(self.regex.get(),
                             re.IGNORECASE | re.MULTILINE | re.DOTALL)
            self.results = []
            for i in self.intervals:
                s = pat.search(i[0].mark)
                if s:
                    disp = i[0].mark
                    a = max(0, s.start() - self.context_size)
                    b = min(s.end() + self.context_size, len(disp))
                    self.results.append(i +
                                        (('...' if a > 0 else '') + disp[a:b] +
                                         ('...' if b < len(disp) else ''), ))
        self.resultCount.configure(text='%s results' % len(self.results))
        for kid in self.resultList.get_children():
            self.resultList.delete(kid)
        for row, res in enumerate(self.results):
            ls = (res[2], res[1], '%s-%s' % (res[0].minTime, res[0].maxTime),
                  res[3])
            self.resultList.insert('', 'end', iid=str(row), values=ls)

    def onClick(self, event=None):
        self.jumpTo(int(self.resultList.selection()[0]))

    def jumpTo(self, index):
        self.app.filesJumpTo(self.results[index][2])
        self.app.TextGrid.selectedTier.set(self.results[index][1])
        self.app.TextGrid.start = self.results[index][0].minTime
        self.app.TextGrid.end = self.results[index][0].maxTime
        for i, f in enumerate(self.app.TextGrid.frameTier):
            if f.time >= self.results[index][0].minTime:
                self.app.frameSV.set(str(i))
                self.app.framesJumpTo()
                break
        self.app.TextGrid.fillCanvases()

    def reset(self, *args, **kwargs):
        raise NotImplementedError('cannot call SearchModule::reset')

    def update(self, *args, **kwargs):
        raise NotImplementedError('cannot call SearchModule::update')

    def grid(self, *args, **kwargs):
        raise NotImplementedError('cannot call SearchModule::grid')

    def grid_remove(self, *args, **kwargs):
        raise NotImplementedError('cannot call SearchModule::grid_remove')
예제 #26
0
class fiveOhOne:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.configure_gui1()

    def configure_gui1(self):
        self.master.title("501")
        self.master.geometry("800x600")

        # function binding return key to entry box
        self.master.bind('<Return>', lambda e: self.score_Entered())

        #create menu
        def callback():
            print("called the callback!")

        # create a menu
        menu = Menu(root)
        root.config(menu=menu)

        filemenu = Menu(menu)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="New", command=callback)
        filemenu.add_command(label="Open...", command=callback)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=callback)

        helpmenu = Menu(menu)
        menu.add_cascade(label="Help", menu=helpmenu)
        helpmenu.add_command(label="About...", command=callback)

        #create frames
        labFrame1 = LabelFrame(self.master, text="Player1 Stats")
        labFrame2 = LabelFrame(self.master, text="Player2 Stats")
        labFrame3 = LabelFrame(self.master, text="Player1 Scores")
        labFrame4 = LabelFrame(self.master, text="Player2  Scores")
        labFrame5 = LabelFrame(self.master, text="Enter Scores")
        """
        #make frames visible using grid
        labFrame1.grid(row=0, column=0, rowspan=2, sticky='ew')
        labFrame3.grid(row=0, column=1, sticky='ew')
        labFrame4.grid(row=0, column=2, sticky='ew')
        labFrame2.grid(row=0, column=3, rowspan=2, sticky='ew')
        labFrame5.grid(row=1, column=1, columnspan=2, sticky='ew')
        """

        #make frames visible using pack
        labFrame1.pack(side="left", fill="both", expand=True)

        labFrame2.pack(side="right", fill="both", expand=True)
        labFrame5.pack(side="bottom", fill="x", expand=True)
        labFrame3.pack(side="left", fill="both", expand=True)
        labFrame4.pack(side="right", fill="both", expand=True)

        #stringvars
        self.pl1name = StringVar()
        self.pl2name = StringVar()
        self.pl1sets = StringVar()
        self.pl1legs = StringVar()
        self.pl160 = StringVar()
        self.pl180 = StringVar()
        self.pl1100 = StringVar()
        self.pl1140 = StringVar()
        self.pl1180 = StringVar()
        self.pl1avg = StringVar()
        self.pl1chtpc = StringVar()
        self.pl1chtnumbs = StringVar()

        #player to go boolean
        self.player1_togo = True

        #frame 1 widgets
        Label(labFrame1, text="Totals").grid(row=0, column=0, sticky='w')
        Label(labFrame1, text="Sets:").grid(row=1, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1sets).grid(row=1, column=1)
        Label(labFrame1, text="Legs:").grid(row=2, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1legs).grid(row=2, column=1)
        Label(labFrame1, text="60+:").grid(row=3, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl160).grid(row=3, column=1)
        Label(labFrame1, text="80+:").grid(row=4, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl180).grid(row=4, column=1)
        Label(labFrame1, text="100+:").grid(row=5, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1100).grid(row=5, column=1)
        Label(labFrame1, text="140+:").grid(row=6, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1140).grid(row=6, column=1)
        Label(labFrame1, text="180:").grid(row=7, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1180).grid(row=7, column=1)
        Label(labFrame1, text="Averages").grid(row=8, column=0, sticky='w')
        Label(labFrame1, text="Score:").grid(row=9, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1avg).grid(row=9, column=1)
        Label(labFrame1, text="Checkout %:").grid(row=10, column=0, sticky='w')
        Label(labFrame1, textvariable=self.pl1chtpc).grid(row=10, column=1)
        Label(labFrame1, text="Checkout Hit/Thrown:").grid(row=11,
                                                           column=0,
                                                           sticky='w')
        Label(labFrame1, textvariable=self.pl1chtnumbs).grid(row=11, column=1)

        #stringvars
        self.pl2sets = StringVar()
        self.pl2legs = StringVar()
        self.pl260 = StringVar()
        self.pl280 = StringVar()
        self.pl2100 = StringVar()
        self.pl2140 = StringVar()
        self.pl2180 = StringVar()
        self.pl2avg = StringVar()
        self.pl2chtpc = StringVar()
        self.pl2chtnumbs = StringVar()

        #frame 2 widgets
        Label(labFrame2, text="Totals").grid(row=0, column=0, sticky='w')
        Label(labFrame2, text="Sets:").grid(row=1, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2sets).grid(row=1, column=1)
        Label(labFrame2, text="Legs:").grid(row=2, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2legs).grid(row=2, column=1)
        Label(labFrame2, text="60+:").grid(row=3, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl260).grid(row=3, column=1)
        Label(labFrame2, text="80+:").grid(row=4, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl280).grid(row=4, column=1)
        Label(labFrame2, text="100+:").grid(row=5, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2100).grid(row=5, column=1)
        Label(labFrame2, text="140+:").grid(row=6, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2140).grid(row=6, column=1)
        Label(labFrame2, text="180:").grid(row=7, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2180).grid(row=7, column=1)
        Label(labFrame2, text="Averages").grid(row=8, column=0, sticky='w')
        Label(labFrame2, text="Score:").grid(row=9, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2avg).grid(row=9, column=1)
        Label(labFrame2, text="Checkout %:").grid(row=10, column=0, sticky='w')
        Label(labFrame2, textvariable=self.pl2chtpc).grid(row=10, column=1)
        Label(labFrame2, text="Checkout Hit/Thrown:").grid(row=11,
                                                           column=0,
                                                           sticky='w')
        Label(labFrame2, textvariable=self.pl2chtnumbs).grid(row=11, column=1)

        #frame 3 widgets
        self.pl1remaining = StringVar()
        Label(labFrame3, text="Player:").grid(row=0, column=0)
        Label(labFrame3, textvariable=self.pl1name).grid(row=0, column=1)
        Label(labFrame3).grid(row=1)
        Label(labFrame3, text="Remaining").grid(row=2,
                                                column=0,
                                                columnspan=2,
                                                sticky='ew')
        self.remlabel1 = Label(labFrame3, textvariable=self.pl1remaining)
        self.remlabel1.grid(row=3, column=0, columnspan=2)
        self.remlabel1.configure(width=3, background='white', font=(None, 35))

        #self.pl1remaining.set(self.pl1dict['score'])
        #self.pl1name.set(game_state.player1)

        #frame 4 widgets
        self.pl2remaining = StringVar()
        Label(labFrame4, text="Player:").grid(row=0, column=0)
        Label(labFrame4, textvariable=self.pl2name).grid(row=0, column=1)
        Label(labFrame4).grid(row=1)
        Label(labFrame4, text="Remaining").grid(row=2,
                                                column=0,
                                                columnspan=2,
                                                sticky='ew')
        self.remlabel2 = Label(labFrame4, textvariable=self.pl2remaining)
        self.remlabel2.grid(row=3, column=0, columnspan=2)
        self.remlabel2.configure(width=3, background='white', font=(None, 35))
        #self.pl2remaining.set(self.pl2dict['score'])
        #self.pl2name.set(game_state.player2)

        #frame 5 widgets
        self.playertogo = StringVar()
        self.scoreEntered = StringVar()
        Label(labFrame5, text="    ").grid(row=0, column=0)
        #Label(labFrame5).grid(row=0, column=1)
        #Label(labFrame5).grid(row=0, column=2)
        Label(labFrame5, text="To Go:").grid(row=1, column=1)
        playerLabel = Label(labFrame5, textvariable=self.playertogo)
        playerLabel.grid(row=2, column=1)
        playerLabel.configure(font=(None, 20))

        self.number_entry = Entry(labFrame5,
                                  textvariable=self.scoreEntered,
                                  width=5)
        self.number_entry.grid(row=2, column=2)
        self.number_entry.configure(background='white', font=(None, 20))
        self.number_entry.focus()
예제 #27
0
class Confirmation(Toplevel):
    """
    Confirmation window that recapitulate the changes that will be made
    during the synchronisation.
    """
    def __init__(self, master, a_copier, a_supp, a_supp_avant_cp, original,
                 sauvegarde, show_size):
        Toplevel.__init__(self, master)
        self.geometry("%ix%i" %
                      (self.winfo_screenwidth(), self.winfo_screenheight()))
        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.title(_("Confirmation"))

        self.a_copier = a_copier
        self.a_supp = a_supp
        self.a_supp_avant_cp = a_supp_avant_cp

        h = max(len(a_supp), len(a_copier))

        style = Style(self)
        style.configure("text.TFrame", background="white", relief="sunken")

        Label(self,
              text=_("Synchronization from %(original)s to %(backup)s") % {
                  "original": original,
                  "backup": sauvegarde
              }).grid(row=0, columnspan=2, padx=10, pady=10)
        paned = PanedWindow(self, orient='horizontal')
        paned.grid(row=1, columnspan=2, sticky="eswn", padx=(10, 4), pady=4)
        paned.columnconfigure(0, weight=1)
        paned.columnconfigure(1, weight=1)
        paned.rowconfigure(1, weight=1)

        # --- copy
        frame_copie = Frame(paned)
        frame_copie.columnconfigure(0, weight=1)
        frame_copie.rowconfigure(1, weight=1)
        paned.add(frame_copie, weight=1)
        Label(frame_copie, text=_("To copy:")).grid(row=0,
                                                    columnspan=2,
                                                    padx=(10, 4),
                                                    pady=4)
        f_copie = Frame(frame_copie, style="text.TFrame", borderwidth=1)
        f_copie.columnconfigure(0, weight=1)
        f_copie.rowconfigure(0, weight=1)
        f_copie.grid(row=1, column=0, sticky="ewsn")
        txt_copie = Text(f_copie,
                         height=h,
                         wrap="none",
                         highlightthickness=0,
                         relief="flat")
        txt_copie.grid(row=0, column=0, sticky="eswn")
        scrollx_copie = Scrollbar(frame_copie,
                                  orient="horizontal",
                                  command=txt_copie.xview)
        scrolly_copie = Scrollbar(frame_copie,
                                  orient="vertical",
                                  command=txt_copie.yview)
        scrollx_copie.grid(row=2, column=0, sticky="ew")
        scrolly_copie.grid(row=1, column=1, sticky="ns")
        txt_copie.configure(yscrollcommand=scrolly_copie.set,
                            xscrollcommand=scrollx_copie.set)
        txt_copie.insert("1.0", "\n".join(a_copier))
        txt_copie.configure(state="disabled")
        self._size_copy = Label(frame_copie)
        self._size_copy.grid(row=3, column=0)

        # --- deletion
        frame_supp = Frame(paned)
        frame_supp.columnconfigure(0, weight=1)
        frame_supp.rowconfigure(1, weight=1)
        paned.add(frame_supp, weight=1)
        Label(frame_supp, text=_("To remove:")).grid(row=0,
                                                     columnspan=2,
                                                     padx=(4, 10),
                                                     pady=4)
        f_supp = Frame(frame_supp, style="text.TFrame", borderwidth=1)
        f_supp.columnconfigure(0, weight=1)
        f_supp.rowconfigure(0, weight=1)
        f_supp.grid(row=1, column=0, sticky="ewsn")
        txt_supp = Text(f_supp,
                        height=h,
                        wrap="none",
                        highlightthickness=0,
                        relief="flat")
        txt_supp.grid(row=0, column=0, sticky="eswn")
        scrollx_supp = Scrollbar(frame_supp,
                                 orient="horizontal",
                                 command=txt_supp.xview)
        scrolly_supp = Scrollbar(frame_supp,
                                 orient="vertical",
                                 command=txt_supp.yview)
        scrollx_supp.grid(row=2, column=0, sticky="ew")
        scrolly_supp.grid(row=1, column=1, sticky="ns")
        txt_supp.configure(yscrollcommand=scrolly_supp.set,
                           xscrollcommand=scrollx_supp.set)
        txt_supp.insert("1.0", "\n".join(a_supp))
        txt_supp.configure(state="disabled")
        self._size_supp = Label(frame_supp)
        self._size_supp.grid(row=3, column=0)

        Button(self, command=self.ok, text="Ok").grid(row=3,
                                                      column=0,
                                                      sticky="e",
                                                      padx=(10, 4),
                                                      pady=(4, 10))
        Button(self, text=_("Cancel"), command=self.destroy).grid(row=3,
                                                                  column=1,
                                                                  sticky="w",
                                                                  padx=(4, 10),
                                                                  pady=(4, 10))
        self.wait_visibility()
        self.grab_set()
        self.transient(self.master)
        if show_size:
            self.compute_size()

    def compute_size(self):
        """Compute and display total size of files to copy/to delete."""
        def size(path):
            s = 0
            try:
                with scandir(path) as content:
                    for f in content:
                        try:
                            if f.is_file():
                                s += f.stat().st_size
                            else:
                                s += size(f.path)
                        except FileNotFoundError:
                            pass
            except NotADirectoryError:
                s = getsize(path)
            return s

        size_copy = 0
        size_supp = 0

        for path in self.a_copier:
            size_copy += size(path)
        for path in self.a_supp:
            size_supp += size(path)
        self._size_copy.configure(text=_("Copy: %(size)s") %
                                  {'size': convert_size(size_copy)})
        self._size_supp.configure(text=_("Remove: %(size)s") %
                                  {'size': convert_size(size_supp)})

    def ok(self):
        """Close dialog and start sync."""
        self.grab_release()
        self.master.copie_supp(self.a_copier, self.a_supp,
                               self.a_supp_avant_cp)
        self.destroy()
예제 #28
0
class MemberChecker(PanedWindow):
    def __init__(self, parent):
        PanedWindow.__init__(self, parent, background="white")

        self.parent = parent
        self.init_data()
        self.init_log()
        self.init_ui()
        self.update_status()

    def init_data(self):
        self.data_store = api.DataStore()

    def init_log(self):
        self.entrance_log = entrance_log.EntranceLog()

    def init_ui(self):
        self.parent.title("Member Checker")
        self.columnconfigure(3, weight=3)
        self.pack(fill=BOTH, expand=True)

        self.input = StringVar()
        self.input_entry = Entry(self, textvariable=self.input)
        self.input_entry.bind('<Return>', self.submit)
        self.input_entry.grid(row=0, column=0, columnspan=3, sticky=E + W)

        self.result = StringVar()
        self.result_label = Label(self, textvariable=self.result)
        self.result_label.grid(row=3, column=0, columnspan=3, sticky=E + W)

        self.name = StringVar()
        name_label = Label(self, textvariable=self.name)
        name_label.grid(row=2, column=0, columnspan=3, sticky=E + W)

        self.status = StringVar()
        status_label = Label(self, textvariable=self.status)
        status_label.grid(row=4, column=0, columnspan=4, sticky=E + W)

        submit_button = Button(self, text="Submit", command=self.submit)
        submit_button.grid(row=1, column=2)

        enter_without_card_button = Button(self, text="Enter without card", command=self.enter_without_card)
        enter_without_card_button.grid(row=1, column=0)

        enter_member_without_card_button = Button(self, text="Enter member without card",
                                                  command=self.enter_member_without_card)
        enter_member_without_card_button.grid(row=1, column=1)

        self.entrance_log_list = Listbox(self)
        self.entrance_log_list.grid(row=0, column=3, rowspan=4, sticky=E + W + S + N)

        self.input_entry.focus()

    def load_data(self):
        if messagebox.askyesno("Load new API Data",
                               "Are you sure you want to load the new API data? All previous data will be removed. The program might be unresponsive for a few seconds, but don't kill it, please! It has feelings too."):
            self.data_store.load_api_data()

    def enter_by_identification(self, identification):
        member = self.data_store.find_member_by_identification(identification)
        if member is None:
            if messagebox.askyesno("Not a member",
                                   "This university identification is not registered as a member. Do you want to let them in as a non-member?"):
                self.enter_non_member_by_identification(identification)
        else:
            self.enter_member(member)

    def enter_by_barcode(self, barcode):
        member = self.data_store.find_member_by_barcode(barcode)
        if member is None:
            if messagebox.askyesno("Not a member",
                                   "This barcode is not registered as a member. Do you want to let them in as a non-member?"):
                self.enter_non_member_by_barcode(barcode)
        else:
            self.enter_member(member)

    def enter_non_member_by_identification(self, identification):
        self.entrance_log.enter_non_member_by_identification(identification)
        self.enter_non_member()

    def enter_non_member_by_barcode(self, barcode):
        self.entrance_log.enter_non_member_by_barcode(barcode)
        self.enter_non_member()

    def enter_without_card(self):
        self.clear_result()
        self.entrance_log.enter_without_card()
        self.enter_non_member()
        self.input_entry.focus()

    def enter_member(self, member):
        inside_result = self.entrance_log.is_member_inside(member)
        if inside_result[0]:
            if not messagebox.askyesno("Already inside",
                                       "This membership card has already been used to enter at {}. Are you sure you want to register it again? Normally you should let this person enter without card (and bill them accordingly).".format(
                                           inside_result[1])):
                return
        self.entrance_log.enter_member(member)
        self.result.set('Member!')
        self.result_label.configure(background='green')
        self.name.set(member['firstName'] + ' ' + member['lastName'])

        self.update_status()

    def enter_non_member(self):
        self.result.set('Not a member!')
        self.result_label.configure(background='red')
        self.name.set('Not in the database')

        self.update_status()

    def enter_member_without_card(self):
        name = self.input.get()
        if len(name) == 0:
            messagebox.showinfo('Name required', 'Please enter the name of this person!')
            return
        self.entrance_log.enter_member_without_card(name)
        self.result.set('Member without card!')
        self.result_label.configure(background="orange")
        self.name.set('')
        self.input.set('')
        self.update_status()

    def clear_result(self):
        self.result.set('')
        self.result_label.configure(background='white')
        self.name.set('')

    def submit(self, event=None):
        self.clear_result()

        entry = self.input.get()
        if helpers.is_valid_identification(entry):
            self.enter_by_identification(entry)
        elif helpers.is_valid_barcode(entry):
            self.enter_by_barcode(entry)
        else:
            messagebox.showinfo('Invalid entry',
                                'The data entered was not recognized as a valid bar code or a valid university identification. You should click \'enter without card\' to let this person in.')
            return

        self.input.set('')
        self.input_entry.focus()

    def clear_log(self):
        if messagebox.askyesno("Clear log", "Are you sure you want to clear the log of all people who entered?"):
            self.entrance_log.clear_log()
            self.update_status()

    def update_status(self):
        self.status.set("{} members inside. Total: {}".format(self.entrance_log.members_inside_count(),
                                                              self.entrance_log.inside_count()))

        logs = self.entrance_log.get_latest_logs(15)
        self.entrance_log_list.delete(0, 15)
        for l in logs:
            s = l['timestamp'] + ": "
            data = l['data']
            if 'member_id' in data:
                member = self.data_store.find_member(data['member_id'])
                s += member['firstName'] + " " + member['lastName']
            elif 'barcode' in data:
                s += data['barcode']
            elif 'identification' in data:
                s += data['identification']
            elif 'name' in data:
                s += '[no card]' + data['name']
            else:
                s += "-"
            self.entrance_log_list.insert(0, s)
예제 #29
0
class waitWindowProgressBar(Toplevel):
    def __init__(self, parent=None):
        """
        Initialises the calculate wait window. Waits for other processes to finish, then packs everything. 
        messages, setup_dataset and stop are the functions that change the layout of the frame.
        """
        super().__init__(parent)
        self.title("Setting up.......")
        #self.attributes("-topmost", True)
        self.pb_val = IntVar(self)
        self.pb_val.set(0)
        self.pb = Progressbar(self, length=400, variable=self.pb_val)
        self.pb.pack(pady=20, padx=20)
        self.pb.configure(maximum=10)
        self.labeltext = StringVar()
        self.labeltext.set("Waiting for other process.....")
        self.waiting_label = Label(self, textvariable=self.labeltext)
        self.waiting_label.configure(anchor="center")
        self.waiting_label.pack(pady=20, padx=20, fill='both', expand=True)
        self.stopbutton = Button(self,
                                 text="Stop!",
                                 compound="bottom",
                                 command=self.stop)
        self.stopbutton.pack(side="left", fill="x", expand=True)
        self.stopflag = 0
        self.update()

    def stop(self):
        """
        Sets the stopflag to 1, thus stopping the calculation.
        """
        self.stopflag = 1

    def setup_dataset(self, dataset):
        """
        Sets up the calculation wait window for the different stages of calculation.
        """
        self.dataset = dataset
        self.title("Calculating Dataset %s" % os.path.basename(dataset.path))
        self.waiting_label.pack(pady=20, padx=20)
        self.update()

    def errormessage(self, dataset):
        messagebox.showwarning(
            "Invalid parameters",
            "Dataset %s was skipped in the computation because of invalid parameters. Please configure Cut-off frequency and / or Filter type."
            % os.path.basename(dataset.path))

    def return_function(self):
        """
        Returns two functions for further use in the model.
        """
        @ri.rternalize
        def messages(i, r, each):
            """
            Messages function given to the R environment.
            Gives feedback on the state of the Monte-Carlo simulation. 
            """
            self.pb.step()
            count = np.asarray((i, r))
            if (count[0] == -1):
                self.title("Computation for Dataset %s" %
                           os.path.basename(self.dataset.path))
                self.pb.pack(pady=20, padx=20)
                self.pb_val.set(0)
                self.stopbutton["state"] = "normal"
                if self.dataset.metadata[
                        "Method"] == "HILDE-Homogeneous" or self.dataset.metadata[
                            "Method"] == "HILDE-Heterogeneous":
                    self.pb.configure(maximum=int(
                        self.dataset.metadata["Repetitions_Hilde"]))
                else:
                    self.pb.configure(
                        maximum=int(self.dataset.metadata["Repetitions"]))
                self.labeltext.set(
                    "Currently computing quantile for Dataset:\n%s \n Press Stop! button to stop computation for current dataset."
                    % os.path.basename(self.dataset.path))
            if (count[0] == -2):
                self.pb.pack_forget()
                self.labeltext.set(
                    "Calculating fit for Dataset:\n%s\nThis computation cannot be interrupted and may take a few minutes."
                    % os.path.basename(self.dataset.path))
                self.stopbutton["state"] = "disabled"
                self.waiting_label.pack(pady=20, padx=20)
            self.update()
            return self.stopflag

        return messages, self.setup_dataset, self.errormessage
예제 #30
0
class retailPage(Frame):
    ''' the main page that actually branches into 2 seperate frames for buying and selling
        this frame provides the use with the
'''
    def __init__(self, parent, main, **kw):
        Frame.__init__(self, parent, **kw)
        self.main = main
        self.Head = Label(font=MED_FONT)

        self.retail_back_b = Button(text='BACK', command=self.back_fb)
        self.stock_name = StringVar()
        self.stock_name_ = ''
        self.stock_name_c = Combobox(textvariable=self.stock_name)
        self.stock_name_l = Label(text='Stock name: ')
        self.amount = Entry()
        self.amount_l = Label(text='Number of stocks :')

        self.check_avail_b = Button(text='Check')
        self.cost_l = Label(text='Cost: ')
        self.cost = Label()
        self.buy_stock_b = Button(text='BUY Stock')
        self.sellp_l = Label(text='Current Selling Price: ')
        self.profit_l = Label(text='PROFIT/LOSS')
        self.sell_stock_b = Button(text='SELL Stock')
        self.page = None

    def showItems(self, main):
        self.Head.grid(column=0, row=0, columnspan=2)
        self.Head.configure(text='logged in as %s' % main.present_user)
        if self.page == 'b':
            self.buy()
        elif self.page == 's':
            self.sell()

    def hideItems(self, main):
        self.Head.grid_forget()

    def buy(self):
        '''This function creates the buy window
'''
        self.retail_back_b.grid(column=1, row=5)
        self.retail_back_b.config(command=self.back_fb)
        self.stock_name_l.grid(column=0, row=1)
        self.stock_name_c.grid(column=1, row=1)
        self.stock_name_c.config(values=self.main.shares_dict.keys())
        self.amount_l.grid(column=0, row=2)
        self.amount.grid(column=1, row=2)
        self.check_avail_b.config(command=self.check_avail_buy)
        self.check_avail_b.grid(column=0, row=3)
        self.cost_l.grid(column=0, row=4, columnspan=2)
        self.buy_stock_b.config(command=self.buy_stock,
                                text='Buy Stock',
                                state='disabled')
        self.buy_stock_b.grid(column=0, row=5)

    def sell(self):
        '''This function creats the sell window'''
        self.retail_back_b.grid(column=1, row=6)
        self.retail_back_b.config(command=self.back_fs)
        self.check_avail_b.config(command=self.check_avail_sell)
        self.stock_name_l.grid(column=0, row=1)
        self.stock_name_c.grid(column=1, row=1)
        self.stock_name_c.config(values=self.main.shares_dict.keys())
        self.amount_l.grid(column=0, row=2)
        self.amount.grid(column=1, row=2)
        self.check_avail_b.grid(column=0, row=3)
        self.sellp_l.grid(column=0, row=4, columnspan=2)
        self.profit_l.grid(column=0, row=5, columnspan=2)
        self.sell_stock_b.config(command=self.sell_stock,
                                 state='disabled',
                                 text='Check')
        self.sell_stock_b.grid(column=0, row=6)

    def back_fb(self):
        '''Back from buy i.e. removes all the items needed to make buy'''
        self.retail_back_b.grid_forget()
        self.Head.grid(column=0, row=0, columnspan=2)
        self.stock_name_l.grid_forget()
        self.stock_name_c.grid_forget()
        self.amount_l.grid_forget()
        self.amount.grid_forget()
        self.check_avail_b.grid_forget()
        self.cost_l.grid_forget()
        self.buy_stock_b.grid_forget()
        self.buy_stock_b.config(state='disabled')

        self.main.show_frame(VIEW_STOCK, RETAIL_PAGE)
        self.stock_name.set('')
        self.amount.delete(0, END)

    def back_fs(self):
        ''' Back from sell i.e. removes all the items needed to make it sell window'''
        self.Head.grid(column=0, row=0, columnspan=2)
        self.retail_back_b.grid_forget()
        self.check_avail_b.grid_forget()
        self.stock_name_l.grid_forget()
        self.stock_name_c.grid_forget()
        self.amount_l.grid_forget()
        self.amount.grid_forget()
        self.sellp_l.grid_forget()
        self.profit_l.grid_forget()
        self.sell_stock_b.grid_forget()

        self.main.show_frame(VIEW_STOCK, RETAIL_PAGE)
        self.stock_name.set('')
        self.amount.delete(0, END)
        self.check_avail_b.grid_forget()

    def check_avail_buy(self):
        ''' Performs a check whether the number of shares requisted are available or not and then check whether the
            person has the required amounts of fund or not for the transaction to go through'''
        name = self.stock_name.get()
        l2 = self.main.accounts[self.main.present_user]

        if name in self.main.shares_dict.keys():
            li = self.main.shares_dict[name]
        else:
            self.stock_name.delete(0, END)
            showinfo(meassage='Enter a Valid Stock name')

        available_num = int(li['tot_amount']) - int(li['tot_sold'])
        req = int(self.amount.get())
        cost = req * int(li['cost'])

        if req < 0:
            showinfo(message='Enter a Valid amount')
        elif req > available_num:
            showinfo(message='Enter an amount less than ' + str(available_num))
        elif cost > int(l2['balance']):
            showinfo(message='You have only %s in you account' % l2['balance'])
        else:
            self.cost_l.config(text='Cost: \t' + li['cost'] + '*' + str(req) +
                               '=' + str(cost))
            self.buy_stock_b.config(state='normal')

    def check_avail_sell(self):
        ''' Performs a check whether the user has enough stocks to sell'''
        name = self.stock_name.get()
        if name in self.main.shares_dict.keys():
            li = self.main.shares_dict[name]
        else:
            self.stock_name.delete(0, END)
            showinfo(message='Enter a Valid Stock name')
        req = int(self.amount.get())
        if req < 0:
            showinfo(message='Please Enter a Valid amount')
            self.amount.delete(0, END)
        li = self.main.p_user_dict
        ok = False
        for i in li:
            if name == i['name']:
                ok = True
                buff = i

        if req > int(buff['tot_owned']):
            showinfo(message='You dont have that many stocks try less than ' +
                     buff['tot_owned'])
            self.amount.delete(0, END)
        cost = self.main.shares_dict[name]['cost']
        tot_cost = req * int(cost)
        try:
            spent = req * float(buff['money_spent']) / int(buff['tot_owned'])
        except:
            spent = 0
        pol = tot_cost - spent

        if pol >= 0:
            self.profit_l.config()
        elif pol < 0:
            self.profit_l.config()
        if req <= int(buff['tot_owned']):
            self.sellp_l.config(text='Current Selling Price: \t' + cost)
            self.profit_l.config(text="PROFIT-LOSS: \t" + str(pol))
            self.sell_stock_b.config(command=self.sell_stock,
                                     text='Sell Stock')
            showinfo(message=
                     'Everthing is ok, \nClicking Sell will execute the trade')
            self.sell_stock_b.config(state='normal')

    def buy_stock(self):
        '''Finally Executes the transaction and asks the user for conformation one last time'''
        name = self.stock_name.get()
        li = self.main.shares_dict[name]

        for i in range(len(self.main.p_user_dict)):
            if name == self.main.p_user_dict[i]['name']:
                index = i
        req = int(self.amount.get())
        tot_cost = req * int(li['cost'])
        self.main.shares_dict[name]['tot_sold'] = str(
            int(self.main.shares_dict[name]['tot_sold']) + req)
        self.main.p_user_dict[index]['tot_owned'] = str(
            int(self.main.p_user_dict[index]['tot_owned']) + req)
        self.main.p_user_dict[index]['money_spent'] = str(
            int(self.main.p_user_dict[index]['money_spent']) + tot_cost)
        self.main.users_dict[
            self.main.present_user][index] = self.main.p_user_dict[index]
        balance = int(self.main.accounts[self.main.present_user]['balance'])
        self.main.accounts[self.main.present_user]['balance'] = str(balance -
                                                                    tot_cost)
        self.cost_l.config(text='Cost: ')

        showinfo(
            message='You have just bought %s of the stock %s at the price %s' %
            (str(req), name, str(tot_cost)))
        self.stock_name.set('')
        self.main.show_frame(VIEW_STOCK, RETAIL_PAGE)
        self.back_fb()

    def sell_stock(self):
        '''Asks the user for conformation and then completes the transaction
        of selling, at this point the profit field is
        also updated'''
        name = self.stock_name.get()
        req = int(self.amount.get())

        li = self.main.p_user_dict
        for i in range(len(li)):
            if name == li[i]['name']:
                ok = True
                buff = i

        tot_cost = req * int(self.main.shares_dict[name]['cost'])
        try:
            spent = req * float(
                self.main.p_user_dict[buff]['money_spent']) / int(
                    self.main.p_user_dict[buff]['tot_owned'])
        except ZeroDivisionError:
            spent = 0
        self.main.shares_dict[name]['tot_sold'] = str(
            int(self.main.shares_dict[name]['tot_sold']) - req)
        self.main.p_user_dict[buff]['tot_owned'] = str(
            int(self.main.p_user_dict[buff]['tot_owned']) - req)
        pol = tot_cost - spent
        diff = int(self.main.p_user_dict[buff]['money_spent']) - tot_cost
        self.main.p_user_dict[buff]['money_spent'] = str(
            diff) if diff > 0 else '0'
        self.main.users_dict[self.main.present_user] = self.main.p_user_dict
        profit = int(self.main.accounts[self.main.present_user]['profit'])
        self.main.accounts[self.main.present_user]['profit'] = str(
            int(profit + pol))
        balance = int(self.main.accounts[self.main.present_user]['balance'])
        self.main.accounts[self.main.present_user]['balance'] = str(balance +
                                                                    tot_cost)
        self.retail_back_b.grid_forget()
        self.profit_l.config(text='PROFIT/LOSS: ')
        self.sellp_l.config(text='Current selling price: ')
        self.main.show_frame(VIEW_STOCK, RETAIL_PAGE)
        self.back_fs()
예제 #31
0
class Calculator:
    equation_to_display = ""

    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Calculator")

        self.entry_display = Label(self.root, width=50, background="white")
        self.entry_display.grid(row=0, columnspan=5)

        self.result_display = Label(self.root, width=37, background="white")
        self.result_display.grid(row=1, columnspan=3)

        button_tree = Button(self.root, text="Tree")
        button_tree.grid(row=0, column=5)

        button_one = Button(self.root,
                            text="1",
                            command=lambda: self.append_sign("1"))
        button_one.grid(row=2, column=0)

        button_two = Button(self.root,
                            text="2",
                            command=lambda: self.append_sign("2"))
        button_two.grid(row=2, column=1)

        button_three = Button(self.root,
                              text="3",
                              command=lambda: self.append_sign("3"))
        button_three.grid(row=2, column=2)

        button_four = Button(self.root,
                             text="4",
                             command=lambda: self.append_sign("4"))
        button_four.grid(row=3, column=0)

        button_five = Button(self.root,
                             text="5",
                             command=lambda: self.append_sign("5"))
        button_five.grid(row=3, column=1)

        button_six = Button(self.root,
                            text="6",
                            command=lambda: self.append_sign("6"))
        button_six.grid(row=3, column=2)

        button_seven = Button(self.root,
                              text="7",
                              command=lambda: self.append_sign("7"))
        button_seven.grid(row=4, column=0)

        button_eight = Button(self.root,
                              text="8",
                              command=lambda: self.append_sign("8"))
        button_eight.grid(row=4, column=1)

        button_nine = Button(self.root,
                             text="9",
                             command=lambda: self.append_sign("9"))
        button_nine.grid(row=4, column=2)

        button_plus = Button(self.root,
                             text="+",
                             command=lambda: self.append_sign("+"))
        button_plus.grid(row=5, column=0)

        button_minus = Button(self.root,
                              text="-",
                              command=lambda: self.append_sign("-"))
        button_minus.grid(row=5, column=1)

        button_zero = Button(self.root,
                             text="0",
                             command=lambda: self.append_sign("0"))
        button_zero.grid(row=5, column=2)

        button_mul = Button(self.root,
                            text="*",
                            command=lambda: self.append_sign("*"))
        button_mul.grid(row=6, column=0)

        button_div = Button(self.root,
                            text="/",
                            command=lambda: self.append_sign("/"))
        button_div.grid(row=6, column=1)

        button_eq = Button(self.root,
                           text="=",
                           command=lambda: self.solve_equation())
        button_eq.grid(row=6, column=2)

        button_clear = Button(self.root,
                              text="Clear",
                              command=lambda: self.clear_equation())
        button_clear.grid(row=1, column=4)

        button_clear = Button(self.root,
                              text="<<<",
                              command=lambda: self.back_on_equation())
        button_clear.grid(row=1, column=5)

        button_pow = Button(self.root,
                            text="^",
                            command=lambda: self.append_sign("^"))
        button_pow.grid(row=2, column=4)

        button_par_left = Button(self.root,
                                 text="(",
                                 command=lambda: self.append_sign("("))
        button_par_left.grid(row=2, column=5)

        button_pow = Button(self.root,
                            text="!",
                            command=lambda: self.append_sign("!"))
        button_pow.grid(row=3, column=4)

        button_par_right = Button(self.root,
                                  text=")",
                                  command=lambda: self.append_sign(")"))
        button_par_right.grid(row=3, column=5)

        button_sqrt = Button(self.root,
                             text="sqrt",
                             command=lambda: self.append_sign("sqrt"))
        button_sqrt.grid(row=4, column=4)

        button_abs_left = Button(self.root,
                                 text="|",
                                 command=lambda: self.append_sign("|"))
        button_abs_left.grid(row=4, column=5)

        button_mod = Button(self.root,
                            text="mod",
                            command=lambda: self.append_sign("mod"))
        button_mod.grid(row=5, column=4)

        button_abs_right = Button(self.root,
                                  text="|",
                                  command=lambda: self.append_sign("|"))
        button_abs_right.grid(row=5, column=5)

        button_log = Button(self.root,
                            text="log",
                            command=lambda: self.append_sign("log"))
        button_log.grid(row=6, column=4)

        button_dot = Button(self.root,
                            text=".",
                            command=lambda: self.append_sign("."))
        button_dot.grid(row=6, column=5)

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

    def append_sign(self, sign):
        if not sign.isnumeric() and sign != '.':
            sign = sign + " "
            if len(self.equation_to_display) > 0:
                if self.equation_to_display[-1] != " ":
                    sign = " " + sign

        self.equation_to_display += sign
        self.entry_display.configure(text=self.equation_to_display)
        print(self.equation_to_display)

    def clear_equation(self):
        self.equation_to_display = ""
        self.entry_display.configure(text=self.equation_to_display)
        print(self.equation_to_display)

    def solve_equation(self):
        tree = parse_tree.infix_to_tree(self.equation_to_display)
        result = parse_tree.calculate_equation(tree)
        self.result_display.configure(text=str(result))
        print(self.equation_to_display)

    def back_on_equation(self):
        if self.equation_to_display[-1] == " ":
            self.equation_to_display = self.equation_to_display[:-1]
        self.equation_to_display = self.equation_to_display[:-1]
        self.entry_display.configure(text=self.equation_to_display)
예제 #32
0
class Register(Frame):
    def __init__(self, master):
        super().__init__(master=master)
        self.layout_components()
        # Setup Callbacks
        self.show_sign_in: Callable = None
        self.sign_in: Callable = None
        self.search_email: Callable = None
        self.search_username: Callable = None
        self.search_password: Callable = None
        self.register: Callable = None

        self.username_valid: bool = False
        self.email_valid: bool = False
        self.password_valid: bool = False
        self.passcnfm_valid: bool = False
        # Refocus to Email Entry
        self.email_Entry.focus()

    def layout_components(self):
        self.pack(fill=tk.BOTH, expand=False, padx=PADX, pady=PADY)
        error_font = font.Font(family="Ariel", size=8)

        # Variables
        self.username = tk.StringVar()
        self.username.set("")

        self.email = tk.StringVar()
        self.email.set("")

        self.password = tk.StringVar()
        self.password.set("")

        self.passcnfm = tk.StringVar()
        self.passcnfm.set("")

        # Email Row
        email_Frame = Frame(self)
        email_Frame.pack(fill=tk.X)
        email_Label = Label(email_Frame, text="Email:", width=LABEL_WIDTH)
        email_Label.pack(side=tk.LEFT, padx=PADX, pady=PADY)
        self.email_Entry = Entry(email_Frame,
                                 width=ENTRY_WIDTH,
                                 textvariable=self.email)
        self.email_Entry.pack(fill=tk.X, padx=PADX, pady=PADY, expand=True)
        self.email_Entry.bind("<FocusOut>", self._validate_email)
        # Email Error Row
        email_errFrame = Frame(self)
        email_errFrame.pack(fill=tk.X)
        self.email_errLabel = Label(email_errFrame,
                                    text="",
                                    foreground="red",
                                    font=error_font)
        self.email_errLabel.pack(side=tk.LEFT,
                                 anchor="center",
                                 expand=True,
                                 padx=PADX,
                                 pady=PADY)

        # Username Row
        user_Frame = Frame(self)
        user_Frame.pack(fill=tk.X)
        user_Label = Label(user_Frame, text="Username:"******"<FocusOut>", self._validate_username)

        # Username Error Row
        user_errFrame = Frame(self)
        user_errFrame.pack(fill=tk.X)
        self.user_errLabel = Label(user_errFrame,
                                   text="",
                                   foreground="red",
                                   font=error_font)
        self.user_errLabel.pack(side=tk.LEFT,
                                anchor="center",
                                expand=True,
                                padx=PADX,
                                pady=PADY)

        # Original Password Row
        pass_Frame = Frame(self)
        pass_Frame.pack(fill=tk.X)
        pass_Label = Label(pass_Frame, text="Password:"******"*")
        self.pass_Entry.pack(fill=tk.X, padx=PADX, pady=PADY, expand=True)
        self.pass_Entry.bind("<FocusOut>", self._validate_password)
        # Confirming Password Row
        pass_cnfmFrame = Frame(self)
        pass_cnfmFrame.pack(fill=tk.X)
        pass_cnfmLabel = Label(pass_cnfmFrame,
                               text="Confirm:",
                               width=LABEL_WIDTH)
        pass_cnfmLabel.pack(side=tk.LEFT, padx=PADX, pady=PADY)
        self.pass_cnfmEntry = Entry(pass_cnfmFrame,
                                    width=ENTRY_WIDTH,
                                    textvariable=self.passcnfm,
                                    show="*")
        self.pass_cnfmEntry.pack(fill=tk.X, padx=PADX, pady=PADY, expand=True)
        self.pass_cnfmEntry.bind("<FocusOut>", self._validate_password)
        # Password Error Row
        pass_errFrame = Frame(self)
        pass_errFrame.pack(fill=tk.X)
        self.pass_errLabel = Label(pass_errFrame,
                                   text="",
                                   foreground="red",
                                   font=error_font)
        self.pass_errLabel.pack(side=tk.LEFT,
                                anchor="center",
                                expand=True,
                                padx=PADX,
                                pady=PADY)

        # Button Row
        button_Frame = Frame(self)
        button_Frame.pack(fill=tk.X)
        # Cancel Button
        cncl_Button = Button(button_Frame, text="Cancel", command=self.cancel)
        cncl_Button.pack(side=tk.RIGHT, padx=PADX, pady=PADY, expand=False)
        # Register Button
        self.register_Button = Button(button_Frame,
                                      text="Register",
                                      state="disabled",
                                      command=self._register)
        self.register_Button.pack(side=tk.RIGHT,
                                  padx=PADX,
                                  pady=PADY,
                                  expand=False)
        # View Password Button
        self.view_pass_Button = Button(button_Frame,
                                       text="View Password",
                                       command=self.view_password)
        self.view_pass_Button.pack(side=tk.LEFT, padx=PADX, pady=PADY)

        # Go Back Button Row
        gbck_Frame = Frame(self)
        gbck_Frame.pack(fill=tk.X)
        gbck_Label = Label(gbck_Frame, text="Have an Account? Go Ahead and ")
        gbck_Label.pack(side=tk.LEFT, padx=PADX, pady=PADY, expand=False)
        gbck_Button = Button(gbck_Frame,
                             text="Sign In",
                             command=self._show_sign_in)
        gbck_Button.pack(side=tk.RIGHT, padx=PADX, pady=PADY, expand=False)

    def cancel(self):
        self.email.set("")
        self.username.set("")
        self.password.set("")
        self.passcnfm.set("")
        self.email_Entry.focus()
        self.email_errLabel.configure(text="")
        self.user_errLabel.configure(text="")
        self.pass_errLabel.configure(text="")

    def view_password(self):
        self.pass_Entry.configure(show="")
        self.pass_cnfmEntry.configure(show="")
        self.view_pass_Button.configure(text="Hide Password",
                                        command=self.hide_password)

    def hide_password(self):
        self.pass_Entry.configure(show="*")
        self.pass_cnfmEntry.configure(show="*")
        self.view_pass_Button.configure(text="View Passwrod",
                                        command=self.view_password)

    def _show_sign_in(self):
        if self.show_sign_in is not None:
            self.show_sign_in()
            self.cancel()

    def _register(self):
        if self.register is not None:
            self.register()

    def _validate_email(self, event):
        email = self.email.get()
        if len(email) == 0:
            self.email_errLabel.configure(text="Email Must not be Empty...")
            self.email_valid = False
        elif not validate_email(email):
            self.email_errLabel.configure(text="Email Format Invalide...")
            self.email_valid = False
        elif self.search_email is not None and not self.search_email(email):
            self.email_errLabel.configure(text="Email Already Registered...")
            self.email_valid = False
        else:
            self.email_errLabel.configure(text="")
            self.email_valid = True
        self.enable_register()

    def _validate_username(self, event):
        username = self.username.get()
        if len(username) == 0:
            self.user_errLabel.configure(text="Username Must not be Empty...")
            self.username_valid = False
        elif self.search_username is not None and not self.search_username(
                username):
            self.username_valid = False
        else:
            self.user_errLabel.configure(text="")
            self.username_valid = True
        self.enable_register()

    def _validate_password(self, event):
        password = self.password.get()
        passcnfm = self.passcnfm.get()
        if len(password) == 0:
            self.pass_errLabel.configure(text="Password Must Not be Empty...")
            self.password_valid = False
        elif len(password) < 8:
            self.pass_errLabel.configure(
                text="Password Must be Longer than 8 Characters...")
            self.password_valid = False
        elif password != passcnfm:
            self.pass_errLabel.configure(text="Password Must Match...   ")
            self.passcnfm_valid = False
        elif self.search_password is not None and not self.search_password(
                password):
            self.pass_errLabel.configure(text="")
            self.password_valid = False
        else:
            self.pass_errLabel.configure(text="")
            self.passcnfm_valid = True
            self.password_valid = True
        self.enable_register()

    def enable_register(self):
        if (self.email_valid and self.username_valid and self.password_valid
                and self.passcnfm_valid):
            self.register_Button.configure(state="normal")

    def failed_register(self):
        self.email.set("")
        self.username.set("")
        self.pass_errLabel.configure(text="Email or Username Already used")
        self.email_Entry.focus()
예제 #33
0
class ErrorSurfaceFrame(LabelFrame):

	def __init__(self,parent):
		LabelFrame.__init__(self, parent, borderwidth=0)

		entryWidth = 7
		xPad1 = 30
		xPad2 = 5

		self.errorXLowerLimitL = Label(self)
		self.errorXLowerLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorXLowerLimitL.grid(row=0,column=0,padx=(10,xPad2),pady=5,sticky="W")
		self.errorXLowerLimitE.grid(row=0,column=1,padx=(xPad2,xPad1),pady=5)

		self.errorXUpperLimitL = Label(self)
		self.errorXUpperLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorXUpperLimitL.grid(row=1,column=0,padx=(10,xPad2),pady=5,sticky="W")
		self.errorXUpperLimitE.grid(row=1,column=1,padx=(xPad2,xPad1),pady=5)

		self.errorYLowerLimitL = Label(self)
		self.errorYLowerLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorYLowerLimitL.grid(row=0,column=2,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorYLowerLimitE.grid(row=0,column=3,padx=(xPad2,xPad1),pady=5)

		self.errorYUpperLimitL = Label(self)
		self.errorYUpperLimitE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorYUpperLimitL.grid(row=1,column=2,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorYUpperLimitE.grid(row=1,column=3,padx=(xPad2,xPad1),pady=5)

		self.errorResolutionL = Label(self,text="Resolution: ")
		self.errorResolutionE = CustomEntry(self,width=entryWidth,justify="right")
		self.errorResolutionE.insert(0,ERROR_SURFACE_DEFAULT_RESOLUTION)
		self.errorResolutionL.grid(row=0,column=4,padx=(xPad1,xPad2),pady=5,sticky="W")
		self.errorResolutionE.grid(row=0,column=5,padx=(xPad2,xPad1),pady=5,sticky="E")

		self.errorSurfaceB = Button(self,text=" Calculate error surface ")
		self.errorSurfaceB.grid(row=1,column=4,columnspan=2,padx=(xPad1,xPad1),sticky="EW")
		self.errorSurfaceB.configure(state=tkinter.ACTIVE)

	def update(self,xSymbol,ySymbol,xLL,xUL,yLL,yUL):

		self.xSymbol = xSymbol
		self.ySymbol = ySymbol

		self.errorXLowerLimitL.configure(text="Lower limit ("+self.xSymbol+"): ")
		self.errorXLowerLimitE.insertNew(xLL)

		self.errorXUpperLimitL.configure(text="Upper limit ("+self.xSymbol+"): ")
		self.errorXUpperLimitE.insertNew(xUL)

		self.errorYLowerLimitL.configure(text="Lower limit ("+self.ySymbol+"): ")
		self.errorYLowerLimitE.insertNew(yLL)

		self.errorYUpperLimitL.configure(text="Upper limit ("+self.ySymbol+"): ")
		self.errorYUpperLimitE.insertNew(yUL)

	def getSurfaceParameters(self):

		xLowerLimit = helper_functions.validateValue(self.errorXLowerLimitE.get(),
									self.xSymbol + " lower limit must be a positive number",
									"float",
									lowerBound=0)
		xUpperLimit = helper_functions.validateValue(self.errorXUpperLimitE.get(),
									self.xSymbol + " upper limit must be greater than the lower limit",
									"float",
									strictLowerBound=xLowerLimit)
		yLowerLimit = helper_functions.validateValue(self.errorYLowerLimitE.get(),
									self.ySymbol + " lower limit must be a positive number",
									"float",
									lowerBound=0)
		yUpperLimit = helper_functions.validateValue(self.errorYUpperLimitE.get(),
									self.ySymbol + " upper limit must be greater than the lower limit",
									"float",
									strictLowerBound=yLowerLimit)
		resolution = helper_functions.validateValue(self.errorResolutionE.get(),
								   "Resolution must be " + str(ERROR_SURFACE_MIN_RESOLUTION) + " \u2264 x \u2264 " + str(ERROR_SURFACE_MAX_RESOLUTION),
								   "int",
								   lowerBound=ERROR_SURFACE_MIN_RESOLUTION,
								   upperBound=ERROR_SURFACE_MAX_RESOLUTION)

		return [xLowerLimit,xUpperLimit,yLowerLimit,yUpperLimit,resolution]

	def clear(self):
		self.errorXLowerLimitE.insertNew("")
		self.errorXUpperLimitE.insertNew("")
		self.errorYLowerLimitE.insertNew("")
		self.errorYUpperLimitE.insertNew("")
예제 #34
0
파일: GUI.py 프로젝트: Hieung28/VRGlove
class GUI(Frame):
	def __init__(self, jointNumber):
		super().__init__()
		self.jointNumber = jointNumber
		self.initGUI()

	def quit(self):
		self.master.quit()
		self.master.destroy()

	def initGUI(self):
		try:
			self.master.title('VRGlove')
			self.master.geometry('1280x720')
			self.pack(fill=BOTH, expand=True)

			# Color list: https://xkcd.com/color/rgb/
			self.colorList = ['xkcd:purple', 'xkcd:green', \
			'xkcd:blue', 'xkcd:pink', 'xkcd:brown', 'xkcd:red', \
			'xkcd:light blue', 'xkcd:teal', 'xkcd:orange', 'xkcd:light green', \
			'xkcd:magenta', 'xkcd:yellow', 'xkcd:cyan', 'xkcd:grey', \
			'xkcd:lime green', 'xkcd:light purple', 'xkcd:violet', 'xkcd:dark green', \
			'xkcd:turquoise', 'xkcd:lavender', 'xkcd:dark blue', 'xkcd:tan']

			##################################################

			# frameCalibrate = Frame(self)
			# frameCalibrate.pack(side=RIGHT, fill=Y)

			# labelPredict = Label(frameCalibrate, text='CALIBRATE', width=32)
			# labelPredict.pack(side=TOP, padx=5, pady=5)

			##################################################

			framePredict = Frame(self)
			framePredict.pack(side=RIGHT, fill=Y)

			labelPredict = Label(framePredict, text='PREDICT')
			labelPredict.pack(side=TOP, padx=5, pady=5)

			self.textPredictResult = Label(framePredict, text='N/A', font=("Arial", 50), foreground='red')
			self.textPredictResult.pack(side=TOP, padx=5, pady=50)

			labelTrainer = Label(framePredict, text='TRAINER')
			labelTrainer.pack(side=TOP, padx=5, pady=5)

			labelTrainingCharacter = Label(framePredict, text='Training character')
			labelTrainingCharacter.pack(side=TOP, padx=5, pady=5)

			entryTrainingCharacter = Entry(framePredict, width=5, justify=CENTER)
			entryTrainingCharacter.pack(side=TOP, padx=5, pady=5)
			entryTrainingCharacter.insert(END, '5')

			labelSampleCount = Label(framePredict, text='Sample count')
			labelSampleCount.pack(side=TOP, padx=5, pady=5)

			self.textSampleCount = Label(framePredict, text=0)
			self.textSampleCount.pack(side=TOP, padx=5, pady=5)

			def sample():
					messagebox.showerror("Infor", "Sorry, no answer available")
					
				# global threadQuatProcess
				# if not threadQuatProcess.collectSampleEnable:
				# 	threadQuatProcess.sampleCount = 0
				# 	threadQuatProcess.collectSampleEnable = True
				# 	threadQuatProcess.trainingCharacter = entryTrainingCharacter.get()
				# 	print('\nStarted sampling!')
				# 	print('Sampling character: ' + threadQuatProcess.trainingCharacter + '\n')
				# 	buttonSample.configure(text='Stop sampling')
				# else:
				# 	threadQuatProcess.collectSampleEnable = False
				# 	print('\nStopped sampling!\n')
				# 	buttonSample.configure(text='Start sampling')

			buttonSample = Button(framePredict, text='Start sampling', command=sample)
			buttonSample.pack(side=TOP, padx=5, pady=5)

			def trainModel():
					messagebox.showerror("Infor", "Sorry, no answer available")
				# global threadPredict
				# threadPredict.predictEnable = False
				# global threadQuatProcess
				# if threadQuatProcess.collectSampleEnable:
				# 	sample()
				# global threadTrainingModel
				# threadTrainingModel.train()
				# statusText = 'Training done!\nTime elapsed: ' + str(threadTrainingModel.timeElapsed) + ' ms\n'
				# statusText += 'Testing done!\nTraining accuracy: ' + str(threadTrainingModel.trainScore) + '%\n'
				# statusText += 'Saving done!\nFilename: ' + threadTrainingModel.modelFile
				# labelTrainingStatus.configure(text=statusText)
				# threadPredict.predictEnable = True

			buttonTrain = Button(framePredict, text='Train model', command=trainModel)
			buttonTrain.pack(side=TOP, padx=5, pady=5)

			labelTrainingStatus = Label(framePredict, text='Ready')
			labelTrainingStatus.pack(side=TOP, padx=5, pady=5)

			##################################################

			frameGraph = Frame(self)
			frameGraph.pack(side=RIGHT, fill=BOTH, expand=True)

			labelGraph = Label(frameGraph, text='PREDICTION')
			labelGraph.pack(side=TOP, padx=5, pady=5)

			self.fig = plt.Figure(dpi = 100)
			ax = self.fig.add_subplot(111)
			ax.set(xlim = (0, 100), ylim = (-100, 100))
			canvas = FigureCanvasTkAgg(self.fig, frameGraph)
			canvas.get_tk_widget().pack(fill=BOTH, padx=5, expand=True)

			# self.x = np.arange(0, 101, 1)
			# self.y = []
			# self.line = []
			# for i in range(jointNumber):
			# 	self.y.append([])
			# 	for j in range(101):
			# 		self.y[i].append(0)
			# 	self.line.append(ax.plot(self.x, self.y[i], color=self.colorList[i], lw=1)[0])

			# serialPort = StringVar(frameGraph)
			# serialPort.set('/dev/rfcomm0')
			# serialPortList = ['/dev/rfcomm0', '/dev/ttyACM0', '/dev/ttyACM1']
			# serialPortOption = OptionMenu(frameGraph, serialPort, serialPortList[0], *serialPortList)
			# serialPortOption.pack(side=LEFT, padx=10, pady=10)

			def connect():
					start = timer()
					loadmodel= joblib.load('finalizedModel.sav')
					temp = np.array(jointAngle).reshape(1,-1)
					yPredict = loadmodel.predict(temp)
					end = timer()
					predictResult = characterList[int(yPredict)]
					predictTime=end-start
					predictTime=round(predictTime,3)
					self.textPredictResult.configure(text=predictTime)
					img=mpimg.imread(ImageIndex[int(yPredict)])
					imgplot=plt.imshow(img)
					plt.show()
						
			# 	global threadQuatProcess
			# 	threadQuatProcess.receiveQuatEnable = False
			# 	threadQuatProcess.changeSerialPort(serialPort.get())
			# 	threadQuatProcess.receiveQuatEnable = True
			# 	print('\nConnected to ' + threadQuatProcess.serialPort + '!\n')

			buttonConnect = Button(frameGraph, text='Connect', command=connect)
			buttonConnect.pack(side=TOP, padx=5, pady=5)

		except:
			self.quit()

	def updateGraph(self, i):
		for i in range(jointNumber):
			global jointAngle
			self.y[i].pop(0)
			self.y[i].append(jointAngle[i]*180.0/3.1416)
			# self.y[i].append(randint(-90, 90))
			self.line[i].set_ydata(self.y[i])
		return self.line[i],

	#def updateParameters(self):
		# global threadPredict
		# global threadQuatProcess
		# self.textPredictResult.configure(text=threadPredict.predictResult)
		# self.textSampleCount.configure(text=threadQuatProcess.sampleCount)
		# self.master.after(100, self.updateParameters)
		#messagebox.showerror("Infor", "Sorry, no answer available")

	def run(self):
		self.ani = animation.FuncAnimation(self.fig, self.updateGraph, interval=100)
		#self.master.after(100, self.updateParameters)
		self.master.mainloop()
예제 #35
0
파일: view.py 프로젝트: pybee/duvet
class MainWindow(object):
    def __init__(self, root, options):
        '''
        -----------------------------------------------------
        | main button toolbar                               |
        -----------------------------------------------------
        |       < ma | in content area >                    |
        |            |                                      |
        | File list  | File name                            |
        |            |                                      |
        -----------------------------------------------------
        |     status bar area                               |
        -----------------------------------------------------

        '''
        # Obtain and expand the current working directory.
        if options.path:
            base_path = os.path.abspath(options.path)
        else:
            base_path = os.path.abspath(os.getcwd())
        self.base_path = os.path.normcase(base_path)

        # Create a filename normalizer based on the CWD.
        self.filename_normalizer = filename_normalizer(self.base_path)

        # Set up dummy coverage data
        self.coverage_data = {'lines': {}, 'total_coverage': None}

        # Root window
        self.root = root
        self.root.title('Duvet')
        self.root.geometry('1024x768')

        # Prevent the menus from having the empty tearoff entry
        self.root.option_add('*tearOff', tk.FALSE)
        # Catch the close button
        self.root.protocol("WM_DELETE_WINDOW", self.cmd_quit)
        # Catch the "quit" event.
        self.root.createcommand('exit', self.cmd_quit)

        # Setup the menu
        self._setup_menubar()

        # Set up the main content for the window.
        self._setup_button_toolbar()
        self._setup_main_content()
        self._setup_status_bar()

        # Now configure the weights for the root frame
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=0)
        self.root.rowconfigure(1, weight=1)
        self.root.rowconfigure(2, weight=0)

    ######################################################
    # Internal GUI layout methods.
    ######################################################

    def _setup_menubar(self):
        # Menubar
        self.menubar = tk.Menu(self.root)

        # self.menu_Apple = Menu(self.menubar, name='Apple')
        # self.menubar.add_cascade(menu=self.menu_Apple)

        self.menu_file = tk.Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_file, label='File')

        self.menu_help = tk.Menu(self.menubar)
        self.menubar.add_cascade(menu=self.menu_help, label='Help')

        # self.menu_Apple.add_command(label='Test', command=self.cmd_dummy)

        # self.menu_file.add_command(label='New', command=self.cmd_dummy, accelerator="Command-N")
        # self.menu_file.add_command(label='Close', command=self.cmd_dummy)

        self.menu_help.add_command(label='Open Documentation', command=self.cmd_duvet_docs)
        self.menu_help.add_command(label='Open Duvet project page', command=self.cmd_duvet_page)
        self.menu_help.add_command(label='Open Duvet on GitHub', command=self.cmd_duvet_github)
        self.menu_help.add_command(label='Open BeeWare project page', command=self.cmd_beeware_page)

        # last step - configure the menubar
        self.root['menu'] = self.menubar

    def _setup_button_toolbar(self):
        '''
        The button toolbar runs as a horizontal area at the top of the GUI.
        It is a persistent GUI component
        '''

        # Main toolbar
        self.toolbar = tk.Frame(self.root)
        self.toolbar.grid(column=0, row=0, sticky=(tk.W, tk.E))

        # Buttons on the toolbar
        self.refresh_button = tk.Button(self.toolbar, text='Refresh', command=self.cmd_refresh)
        self.refresh_button.grid(column=0, row=0)

        # Coverage summary for currently selected file.
        self.coverage_total_summary = tk.StringVar()
        self.coverage_total_summary_label = Label(
            self.toolbar,
            textvariable=self.coverage_total_summary,
            anchor=tk.E,
            padding=(5, 0, 5, 0),
            font=('Helvetica','20')
        )
        self.coverage_total_summary_label.grid(column=1, row=0, sticky=(tk.W, tk.E))

        self.toolbar.columnconfigure(0, weight=0)
        self.toolbar.columnconfigure(1, weight=1)
        self.toolbar.rowconfigure(0, weight=0)

    def _setup_main_content(self):
        '''
        Sets up the main content area. It is a persistent GUI component
        '''

        # Main content area
        self.content = PanedWindow(self.root, orient=tk.HORIZONTAL)
        self.content.grid(column=0, row=1, sticky=(tk.N, tk.S, tk.E, tk.W))

        # Create the tree/control area on the left frame
        self._setup_left_frame()
        self._setup_project_file_tree()
        self._setup_global_file_tree()

        # Create the output/viewer area on the right frame
        self._setup_code_area()

        # Set up weights for the left frame's content
        self.content.columnconfigure(0, weight=1)
        self.content.rowconfigure(0, weight=1)

        self.content.pane(0, weight=1)
        self.content.pane(1, weight=4)

    def _setup_left_frame(self):
        '''
        The left frame mostly consists of the tree widget
        '''

        # The left-hand side frame on the main content area
        # The tabs for the two trees
        self.tree_notebook = Notebook(
            self.content,
            padding=(0, 5, 0, 5)
        )
        self.content.add(self.tree_notebook)

    def _setup_project_file_tree(self):

        self.project_file_tree_frame = tk.Frame(self.content)
        self.project_file_tree_frame.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        self.tree_notebook.add(self.project_file_tree_frame, text='Project')

        self.project_file_tree = FileView(self.project_file_tree_frame, normalizer=self.filename_normalizer, root=self.base_path)
        self.project_file_tree.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))

        # # The tree's vertical scrollbar
        self.project_file_tree_scrollbar = tk.Scrollbar(self.project_file_tree_frame, orient=tk.VERTICAL)
        self.project_file_tree_scrollbar.grid(column=1, row=0, sticky=(tk.N, tk.S))

        # # Tie the scrollbar to the text views, and the text views
        # # to each other.
        self.project_file_tree.config(yscrollcommand=self.project_file_tree_scrollbar.set)
        self.project_file_tree_scrollbar.config(command=self.project_file_tree.yview)

        # Setup weights for the "project_file_tree" tree
        self.project_file_tree_frame.columnconfigure(0, weight=1)
        self.project_file_tree_frame.columnconfigure(1, weight=0)
        self.project_file_tree_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.project_file_tree.bind('<<TreeviewSelect>>', self.on_file_selected)

    def _setup_global_file_tree(self):

        self.global_file_tree_frame = tk.Frame(self.content)
        self.global_file_tree_frame.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
        self.tree_notebook.add(self.global_file_tree_frame, text='Global')

        self.global_file_tree = FileView(self.global_file_tree_frame, normalizer=self.filename_normalizer)
        self.global_file_tree.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))

        # # The tree's vertical scrollbar
        self.global_file_tree_scrollbar = tk.Scrollbar(self.global_file_tree_frame, orient=tk.VERTICAL)
        self.global_file_tree_scrollbar.grid(column=1, row=0, sticky=(tk.N, tk.S))

        # # Tie the scrollbar to the text views, and the text views
        # # to each other.
        self.global_file_tree.config(yscrollcommand=self.global_file_tree_scrollbar.set)
        self.global_file_tree_scrollbar.config(command=self.global_file_tree.yview)

        # Setup weights for the "global_file_tree" tree
        self.global_file_tree_frame.columnconfigure(0, weight=1)
        self.global_file_tree_frame.columnconfigure(1, weight=0)
        self.global_file_tree_frame.rowconfigure(0, weight=1)

        # Handlers for GUI events
        self.global_file_tree.bind('<<TreeviewSelect>>', self.on_file_selected)

    def _setup_code_area(self):
        self.code_frame = tk.Frame(self.content)
        self.code_frame.grid(column=1, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))

        # Label for current file
        self.current_file = tk.StringVar()
        self.current_file_label = Label(self.code_frame, textvariable=self.current_file)
        self.current_file_label.grid(column=0, row=0, sticky=(tk.W, tk.E))

        # Code display area
        self.code = CodeView(self.code_frame)
        self.code.grid(column=0, row=1, sticky=(tk.N, tk.S, tk.E, tk.W))

        # Set up weights for the code frame's content
        self.code_frame.columnconfigure(0, weight=1)
        self.code_frame.rowconfigure(0, weight=0)
        self.code_frame.rowconfigure(1, weight=1)

        self.content.add(self.code_frame)

    def _setup_status_bar(self):
        # Status bar
        self.statusbar = tk.Frame(self.root)
        self.statusbar.grid(column=0, row=2, sticky=(tk.W, tk.E))

        # Coverage summary for currently selected file.
        self.coverage_file_summary = tk.StringVar()
        self.coverage_file_summary_label = Label(self.statusbar, textvariable=self.coverage_file_summary)
        self.coverage_file_summary_label.grid(column=0, row=0, sticky=(tk.W, tk.E))
        self.coverage_file_summary.set('No file selected')

        # Main window resize handle
        self.grip = Sizegrip(self.statusbar)
        self.grip.grid(column=1, row=0, sticky=(tk.S, tk.E))

        # Set up weights for status bar frame
        self.statusbar.columnconfigure(0, weight=1)
        self.statusbar.columnconfigure(1, weight=0)
        self.statusbar.rowconfigure(0, weight=0)

    ######################################################
    # Utility methods for controlling content
    ######################################################

    def show_file(self, filename, line=None, breakpoints=None):
        """Show the content of the nominated file.

        If specified, line is the current line number to highlight. If the
        line isn't currently visible, the window will be scrolled until it is.

        breakpoints is a list of line numbers that have current breakpoints.

        If refresh is true, the file will be reloaded and redrawn.
        """
        # Set the filename label for the current file
        self.current_file.set(self.filename_normalizer(filename))

        # Update the code view; this means changing the displayed file
        # if necessary, and updating the current line.
        if filename != self.code.filename:
            self.code.filename = filename

            missing = self.coverage_data['missing'].get(os.path.normcase(filename), [])
            executed = self.coverage_data['lines'].get(os.path.normcase(filename), [])

            n_executed = len(executed)
            n_missing = len(missing)

            self.code.highlight_missing(missing)

            self.coverage_file_summary.set('%s/%s lines executed' % (n_executed, n_executed + n_missing))

        self.code.line = line

    def load_coverage(self):
        "Load and display coverage data"
        # Store the old list of files that have coverage data.
        # We do this so we can identify stale data on the tree.
        old_files = set(self.coverage_data['lines'].keys())
        old_total_coverage = self.coverage_data['total_coverage']

        loaded = False
        retry = True
        while not loaded and retry:
            try:
                # Load the new coverage data
                cov = coverage.coverage()
                cov.load()

                # Override precision for coverage reporting.
                coverage.results.Numbers.set_precision(1)

                if cov.data.measured_files():
                    self.coverage_data = {
                        'lines': {},
                        'missing': {},
                    }
                    totals = coverage.results.Numbers()

                    # Update the coverage display of every file mentioned in the file.
                    for filename in cov.data.measured_files():
                        filename = os.path.normcase(filename)
                        node = nodify(filename)
                        dirname, basename = os.path.split(filename)

                        # If the normalized version of the filename is the same as the
                        # filename, then the file *isn't* under the project root.
                        if filename == self.filename_normalizer(filename):
                            file_tree = self.global_file_tree
                        else:
                            file_tree = self.project_file_tree

                        try:
                            # # Make sure the file exists on the tree.
                            file_tree.insert_filename(dirname, basename)

                            # Compute the coverage percentage
                            analysis = cov._analyze(filename)

                            self.coverage_data['lines'][filename] = analysis.statements
                            self.coverage_data['missing'][filename] = analysis.missing
                            file_coverage = analysis.numbers.pc_covered

                            totals = totals + analysis.numbers

                            file_tree.set(node, 'coverage', analysis.numbers.pc_covered_str)
                            # file_tree.set(node, 'branch_coverage', str(len(lines)))

                            # Set the color of the tree node based on coverage
                            if file_coverage < 70.0:
                                file_tree.item(node, tags=['file', 'code', 'bad'])
                            elif file_coverage < 80.0:
                                file_tree.item(node, tags=['file', 'code', 'poor'])
                            elif file_coverage < 90.0:
                                file_tree.item(node, tags=['file', 'code', 'ok'])
                            elif file_coverage < 99.9:
                                file_tree.item(node, tags=['file', 'code', 'good'])
                            else:
                                file_tree.item(node, tags=['file', 'code', 'perfect'])

                        except coverage.misc.NoSource:
                            # could mean the file was deleted after running coverage
                            file_tree.item(node, tags=['bad'])

                        # We've updated the file, so we know it isn't stale.
                        try:
                            old_files.remove(filename)
                        except KeyError:
                            # File wasn't loaded before; ignore this.
                            pass

                        # Clear out any stale coverage data
                        for filename in old_files:
                            node = nodify(filename)
                            if file_tree.exists(node):
                                file_tree.set(node, 'coverage', '')
                                file_tree.item(node, tags=['file', 'code'])

                    # Compute the overall coverage
                    total_coverage = totals.pc_covered
                    self.coverage_data['total_coverage'] = total_coverage

                    coverage_text = u'%.1f%%' % total_coverage

                    # Update the text with up/down arrows to reflect change
                    if old_total_coverage is not None:
                        if total_coverage > old_total_coverage:
                            coverage_text = coverage_text + u' ⬆'
                        elif total_coverage < old_total_coverage:
                            coverage_text = coverage_text + u' ⬇'

                    self.coverage_total_summary.set(coverage_text)

                    # Set the color based on coverage level.
                    if total_coverage < 70.0:
                        self.coverage_total_summary_label.configure(foreground='red')
                    elif total_coverage < 80.0:
                        self.coverage_total_summary_label.configure(foreground='orange')
                    elif total_coverage < 90.0:
                        self.coverage_total_summary_label.configure(foreground='blue')
                    elif total_coverage < 99.9:
                        self.coverage_total_summary_label.configure(foreground='cyan')
                    else:
                        self.coverage_total_summary_label.configure(foreground='green')

                    # Refresh the file display
                    current_file = self.code._filename
                    if current_file:
                        self.code._filename = None
                        self.show_file(current_file)

                    loaded = True
                else:
                    retry = tkMessageBox.askretrycancel(
                        message="Couldn't find coverage data file. Have you generated coverage data? Is the .coverage in your current working directory",
                        title='No coverage data found'
                    )
            except Exception as e:
                retry = tkMessageBox.askretrycancel(
                    message="Couldn't load coverage data -- data file may be corrupted (Error was: %s)" % e,
                    title='Problem loading coverage data'
                )

        return loaded

    ######################################################
    # TK Main loop
    ######################################################

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

    ######################################################
    # TK Command handlers
    ######################################################

    def cmd_quit(self):
        "Quit the program"
        self.root.quit()

    def cmd_refresh(self, event=None):
        "Refresh the coverage data"
        self.load_coverage()

    def cmd_duvet_page(self):
        "Show the Duvet project page"
        webbrowser.open_new('http://pybee.org/duvet')

    def cmd_duvet_github(self):
        "Show the Duvet GitHub repo"
        webbrowser.open_new('http://github.com/pybee/duvet')

    def cmd_duvet_docs(self):
        "Show the Duvet documentation"
        # If this is a formal release, show the docs for that
        # version. otherwise, just show the head docs.
        if len(NUM_VERSION) == 3:
            webbrowser.open_new('https://duvet.readthedocs.io/en/v%s/' % VERSION)
        else:
            webbrowser.open_new('https://duvet.readthedocs.io/')

    def cmd_beeware_page(self):
        "Show the BeeWare project page"
        webbrowser.open_new('http://pybee.org/')

    ######################################################
    # Handlers for GUI actions
    ######################################################

    def on_file_selected(self, event):
        "When a file is selected, highlight the file and line"
        if event.widget.selection():
            filename = event.widget.selection()[0]

            # Display the file in the code view
            if os.path.isfile(filename):
                self.show_file(filename=filename)
            else:
                self.code.filename = None
class TtkScale(Scale):
    def __init__(self,
                 parent,
                 length=0,
                 from_=0,
                 to=255,
                 orient='horizontal',
                 variable=0,
                 digits=0,
                 tickinterval=None,
                 sliderlength=32,
                 command=None,
                 style=None,
                 showvalue=True,
                 resolution=1):

        self.from_ = from_
        self.to = to
        self.variable = variable
        self.length = length
        self.command = command
        self.parent = parent
        self.orient = orient

        super().__init__(parent,
                         length=length,
                         from_=from_,
                         to=to,
                         orient=orient,
                         variable=variable,
                         command=command,
                         style=style)

        self.digits = digits
        self.tickinterval = tickinterval
        self.showvalue = showvalue
        self.resolution = resolution
        self.sliderlength = sliderlength  # = 32

        theme_sl = {
            'alt': 9,
            'clam': 30,
            'classic': 30,
            'default': 30,
            'lime': 9,
            'winnative': 9
        }

        theme_bw = {
            'alt': 0,
            'clam': 1,
            'classic': 2,
            'default': 1,
            'lime': 6,
            'winnative': 0
        }

        # set trough borderwidth
        st = Style(self)
        theme_used = st.theme_use()
        if theme_used in ('alt', 'clam', 'classic', 'default', 'lime',
                          'winnative'):
            self.bw_val = bw_val = theme_bw[theme_used]
            self.sliderlength = sliderlength = theme_sl[theme_used]
        else:
            self.bw_val = bw_val = 1
        if showvalue:
            self.configure(command=self.display_value)

        def_font = font.nametofont('TkDefaultFont')
        # if from_ more than to swap values
        if from_ < to:
            pass
        else:
            from_, to = to, from_

        data = np.arange(from_,
                         (to + 1 if tickinterval >= 1 else to + tickinterval),
                         tickinterval)
        self.data = data = np.round(data, 1)
        range_vals = tuple(data)
        len_rvs = len(range_vals)
        if self.orient == 'horizontal':
            vals_size = [def_font.measure(str(i)) for i in range_vals]
            data_size = sum(vals_size)
            space_size = len_rvs * def_font.measure('0')
        else:
            lspace = def_font.metrics('linespace')
            data_size = len_rvs * lspace
            space_size = len_rvs * 3
        sizes = data_size + space_size
        min_len = (sizes if sizes % 50 == 0 else sizes + 50 - sizes % 50)
        self.len_val = len_val = min_len if length < min_len else length
        self.configure(length=len_val)

        self.rel_min = rel_min = (sliderlength // 2 + bw_val) / len_val
        self.rel_max = rel_max = 1 - (sliderlength // 2 + bw_val) / len_val

        if range_vals[-1] == to:
            pass
        else:
            max_rv = range_vals[-1]
            self.mult_l = ((max_rv - from_) * rel_max / (to - from_))

        self.bind("<Button-1>", self.resolve)

        self.build(from_, to, rel_min, rel_max, range_vals, len_rvs)

    def build(self, from_, to, rel_min, rel_max, range_vals, len_rvs):
        if self.orient == 'horizontal':
            for i, rv in enumerate(range_vals):
                item = Label(self.parent, text=rv)
                item.place(
                    in_=self,
                    bordermode='outside',
                    relx=(rel_min + i / (len_rvs - 1) *
                          ((rel_max if range_vals[-1] == to else self.mult_l) -
                           rel_min)),
                    rely=1,
                    anchor='n')
        else:
            for i, rv in enumerate(range_vals):
                item = Label(self.parent, text=rv)
                item.place(
                    in_=self,
                    bordermode='outside',
                    rely=(rel_min + i / (len_rvs - 1) *
                          ((rel_max if range_vals[-1] == to else self.mult_l) -
                           rel_min)),
                    relx=1,
                    anchor='w')

        if self.showvalue:
            self.disp_lab = Label(self.parent, text=self.get())
            rel_l = self.convert_to_rel(float(self.get()))
            if self.orient == 'horizontal':
                self.disp_lab.place(in_=self,
                                    bordermode='outside',
                                    relx=rel_l,
                                    rely=0,
                                    anchor='s')
            else:
                self.disp_lab.place(in_=self,
                                    bordermode='outside',
                                    rely=rel_l,
                                    relx=0,
                                    anchor='e')

    def convert_to_rel(self, curr_val):
        return ((curr_val - self.from_) * (self.rel_max - self.rel_min) /
                (self.to - self.from_) + self.rel_min)

    def convert_to_act(self, curr_val):
        l_max = self.rel_max * self.len_val
        l_min = self.rel_min * self.len_val
        return ((curr_val - self.from_) * (l_max - l_min) /
                (self.to - self.from_) + l_min)

    def display_value(self, value):
        # position (in pixel) of the center of the slider
        rel_l = self.convert_to_rel(float(value))
        self.disp_lab.config(text=value)  # text=""
        if self.orient == 'horizontal':
            self.disp_lab.place_configure(relx=rel_l)
        else:
            self.disp_lab.place_configure(rely=rel_l)
        digits = self.digits
        self.disp_lab.configure(text=f'{float(value):.{digits}f}')
        # if your python is not 3.6 or above use the following 2 lines
        #   instead of the line above
        #my_precision = '{:.{}f}'.format
        #self.disp_lab.configure(text=my_precision(float(value), digits))

    def resolve(self, evt):
        resolution = self.resolution
        if resolution < 1 or self.tickinterval < 1:
            pass
        else:
            value = self.get()
            curr_l = self.convert_to_act(value)
            if self.orient == 'horizontal':
                if evt.x < curr_l - self.sliderlength / 2:
                    self.set(value - resolution + 1)
                elif evt.x > curr_l + self.sliderlength / 2:
                    self.set(value + resolution - 1)
            else:
                if evt.y < curr_l - self.sliderlength / 2:
                    self.set(value - resolution + 1)
                elif evt.y > curr_l + self.sliderlength / 2:
                    self.set(value + resolution - 1)