Beispiel #1
0
def getWidthAndHeight(currentMessage: Message, settings: Settings,
                      font: Font) -> (int, int):
    fontColor = currentMessage.overrides.fontColor if currentMessage.overrides.fontColor else settings.messageSettings.color
    xCoord = 0
    yCoord = 0
    canvas = Canvas()
    box = (0, 0, 0, 0)
    for part in sorted(currentMessage.parts, key=lambda x: x.sortOrder):
        if part.partType == "Pixel Gap":
            xCoord += int(part.value)
        elif part.partType == "Text":
            for char in part.value:
                canvas.create_text(xCoord,
                                   yCoord,
                                   fill=fontColor,
                                   text=char,
                                   font=font,
                                   tags="currentMessage",
                                   anchor=W)
                box = canvas.bbox(canvas.find_withtag("currentMessage")[-1])
                xCoord = box[2]
        elif part.partType == "Text From File":
            fileText = readFile(part.value)
            for char in fileText:
                canvas.create_text(xCoord,
                                   yCoord,
                                   fill=fontColor,
                                   text=char,
                                   font=font,
                                   tags="currentMessage",
                                   anchor=W)
                box = canvas.bbox(canvas.find_withtag("currentMessage")[-1])
                xCoord = box[2]
        elif part.partType == "Image":
            try:
                img = PhotoImage(Image.open(part.value))
                canvas.create_image(xCoord,
                                    yCoord,
                                    image=img,
                                    anchor=W,
                                    tags="currentMessage")
                box = canvas.bbox(canvas.find_withtag("currentMessage")[-1])
                xCoord = box[2]
            except Exception as e:
                print("Error loading image: " + str(e))
    width = box[2]
    height = 0
    for elem in canvas.find_withtag("currentMessage"):
        box = canvas.bbox(elem)
        height = max(height, box[3] - box[1])
    canvas.delete("all")
    del canvas
    return width, height
Beispiel #2
0
class ScrollableFrame(ttk.Frame):
    """ Consider me a regular frame with a vertical scrollbar 
        on the right, after adding/removing widgets to/from me 
        call my method update() to refresh the scrollable area. 
        Don't pack() me, nor place() nor grid(). 
        I work best when I am alone in the parent frame.
        https://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter/3092341#3092341
    """
    def __init__(self, win_frame, x_frame, y_frame, *args, **kw):
        # scrollbar on right in parent
        yscrollbar = Scrollbar(y_frame)
        yscrollbar.pack(side=RIGHT, fill=Y, expand=False)

        # scrollbar on bottom in parent
        xscrollbar = Scrollbar(x_frame, orient=HORIZONTAL)
        xscrollbar.pack(side="top", fill=X, expand=False, pady=10)

        # canvas on left in parent
        self.canvas = Canvas(win_frame,
                             yscrollcommand=yscrollbar.set,
                             xscrollcommand=xscrollbar.set,
                             background="#ffffff")
        self.canvas.pack(side=LEFT, fill=BOTH, expand=True)

        def fill_canvas(event):
            "enlarge the windows item to the canvas width"
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))

        self.canvas.bind("<Configure>", fill_canvas)

        yscrollbar.config(command=self.canvas.yview)
        xscrollbar.config(command=self.canvas.xview)

        # create the scrollable frame and assign it to the windows item of the canvas
        style = ttk.Style()
        style.configure("BW.TLabel", foreground="black", background="white")
        kw["style"] = "BW.TLabel"
        ttk.Frame.__init__(self, win_frame, *args, **kw)

        self.windows_item = self.canvas.create_window(0,
                                                      0,
                                                      window=self,
                                                      anchor=NW)

    def update(self):
        """
        Update changes to the canvas before the program gets
        back the mainloop, then update the scrollregion
        """
        self.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))
Beispiel #3
0
def zipForward(settings: Settings, canvas: Canvas, scrollSpeed: float):
    deltaY = 1
    try:
        for elem in canvas.find_withtag("currentMessage"):
            crashPrevention = 0
            while crashPrevention < 5000 and int(
                (canvas.bbox(elem)[3] + canvas.bbox(elem)[1]) / 2) != int(
                    int(settings.windowSettings.height) / 2):
                canvas.move(elem, 0, deltaY)
                pause(scrollSpeed)
                crashPrevention += 1
            deltaY = deltaY * -1
    except TypeError:
        return
def rotateImage(angle):
    global imagePath
    global image
    global im
    global im_width
    global im_height
    global im_size
    global photo
    global canvas
    global xscrollbar
    global yscrollbar
    global t
    canvas.destroy()
    canvas = Canvas(root,
                    height=canvasHeight,
                    width=canvasWidth,
                    xscrollcommand=xscrollbar.set,
                    yscrollcommand=yscrollbar.set)
    canvas.place(x=canvasxPosition, y=canvasyPosition)
    im = Image.open(imagePath.get())
    im_width, im_height = im.size
    im = im.resize((int(im_width * imageMagnification.get()),
                    int(im_height * imageMagnification.get())),
                   Image.ANTIALIAS)
    im = im.rotate(angle * 180 / pi)
    photo = ImageTk.PhotoImage(im)
    image = canvas.create_image(0, 0, anchor=NW, image=photo)
    canvas.grid(row=0, column=0, sticky=N + S + E + W)
    canvas.config(scrollregion=canvas.bbox(ALL))
    xscrollbar.config(command=canvas.xview)
    yscrollbar.config(command=canvas.yview)
    canvas.bind("<Motion>", crop)
    canvas.bind("<ButtonPress-1>", printcoord)
    canvas.bind('<B1-Motion>', onGrow)
Beispiel #5
0
    def query_and_result(self,query_from_client):
        query = str(query_from_client)
        n_relevant_docs,relevant_docs = self.start_search(query=query)

        # create canvas
        canvas = Canvas(self.master)
        canvas.grid(row=4, columnspan=3, sticky="news")

        # create another frame
        canvas_Frame = Frame(canvas)
        canvas.create_window((0, 0), window=canvas_Frame, anchor=N + W)

        if n_relevant_docs > 0:
            sort_var = IntVar()
            sort_time_chack_btn = Checkbutton(self.master,text="sort by time",onvalue=0 ,variable=sort_var,command=lambda :self.sort_by_time(canvas_Frame,relevant_docs))
            sort_pop_chack_btn = Checkbutton(self.master,text="sort by popularity",onvalue=1,variable=sort_var,command=lambda :self.sort_by_pop(canvas_Frame,relevant_docs))
            sort_chack_btn = Checkbutton(self.master, text="sort by relevant", onvalue=2, variable=sort_var,
                                         command=lambda: self.print_results(canvas_Frame, relevant_docs))
            sort_chack_btn.grid(row=3, column=0)
            sort_pop_chack_btn.grid(row=3, column=1)
            sort_time_chack_btn.grid(row=3, column=2)

        #create scrollbar
        scrollbar = Scrollbar(self.master, orient="vertical", command=canvas.yview)
        scrollbar.grid(row=3, columnspan=4,sticky=E)

        #bind canvas and scrollbar
        canvas.configure(yscrollcommand=scrollbar.set)
        canvas.bind('<Configure>',lambda e: canvas.configure(scrollregion=canvas.bbox("all")))

        n_text = "There is "+str(n_relevant_docs)+" results"
        n_lable = Label(canvas_Frame, text=n_text, font=("serif", 10))
        n_lable.grid(row=3, column=1)
        self.print_results(canvas_Frame= canvas_Frame,relevant_docs=relevant_docs)
Beispiel #6
0
def add_scrolling_figure(figure, frame):

    canvas = Canvas(frame)

    canvas.grid(row=0, column=0, sticky=tk.NSEW)

    x_scrollbar = Scrollbar(frame, orient=tk.HORIZONTAL)

    y_scrollbar = Scrollbar(frame)

    x_scrollbar.grid(row=1, column=0, sticky=tk.EW)

    y_scrollbar.grid(row=0, column=1, sticky=tk.NS)

    canvas.config(xscrollcommand=x_scrollbar.set)

    x_scrollbar.config(command=canvas.xview)

    canvas.config(yscrollcommand=y_scrollbar.set)

    y_scrollbar.config(command=canvas.yview)

    # plug in the figure

    fig_agg = FigureCanvasTkAgg(figure, canvas)

    mpl_canvas = fig_agg.get_tk_widget()

    mpl_canvas.grid(sticky=tk.NSEW)

    # and connect figure with scrolling region

    canvas.create_window(0, 0, window=mpl_canvas)

    canvas.config(scrollregion=canvas.bbox(tk.ALL))
def on_frame_configure(canvas: tkinter.Canvas) -> None:
    """
    Resets the scrollbar region to encompass the inner frame
    :param canvas:
    """
    # Note: bbox is a bounding box
    canvas.configure(scrollregion=canvas.bbox("all"))
Beispiel #8
0
class MsgWindow(Frame):
    def __init__(self, parent, **kwargs):
        self.parent = parent
        self.canvas = Canvas(self.parent, borderwidth=0, width=500, height=500)
        super().__init__(self.canvas, **kwargs)
        scroll_frame = Frame(self.parent, height=504, width=20)
        scroll_frame.pack(side="right", anchor="ne", fill="y")
        self._scrollbar = Scrollbar(scroll_frame,
                                    command=self.canvas.yview,
                                    orient="vertical")
        self._scrollbar.place(x=1, y=0, height=504)
        self.canvas.config(yscrollcommand=self._scrollbar.set)
        self.canvas.pack(fill="both")
        self.frame_id = self.canvas.create_window((2, 4),
                                                  window=self,
                                                  anchor="nw",
                                                  tags="self")
        self.canvas.bind("<Configure>", self.onConfig)

    def onConfig(self, event=None):
        """
            update scroll region, keep the bottom text in view
        """
        self.canvas.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))
        if event is not None:
            self.canvas.itemconfig(self.frame_id, width=event.width)
            # if called and not event bound, no scrolling
            self.canvas.yview_moveto(1.0)
    def createListFrame(self):  # TODO rename
        self.list_frame = Frame(master=self)
        self.list_frame.pack(side='left',
                             padx=0,
                             pady=0,
                             fill="both",
                             expand=True)

        canvas = Canvas(self.list_frame, bg="gray")
        scroll_y = Scrollbar(self.list_frame,
                             orient="vertical",
                             command=canvas.yview)
        scroll_frame = Frame(canvas, bg="gray")
        void_label = Label(master=scroll_frame, text=" " * 255, bg="gray")
        void_label.pack(padx=2, pady=2, side="bottom")

        for e in self.windowList:
            self.createWindowFrame(scroll_frame, windowObject=e)

        canvas.create_window(0, 0, anchor='nw', window=scroll_frame)
        canvas.update_idletasks()
        scroll_frame.update()
        canvas.configure(
            scrollregion=canvas.bbox(
                'all'
            ),  # scrollregion=canvas.bbox('all') #TODO: #20 scrollregion
            yscrollcommand=scroll_y.set)
        canvas.pack(fill='both', expand=True, side='left')
        scroll_y.pack(fill='y', side='right')
Beispiel #10
0
def ayudaArchivo(raizMain):
        
    raizVetana = tkinter.Toplevel(raizMain)
    raizVetana.title("Definición de variables")
    raizVetana.geometry("760x600")
    
    scrollbar = Scrollbar(raizVetana)
    can = Canvas(raizVetana, yscrollcomman=scrollbar.set)
    scrollbar.config(command=can.yview)
    scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
    
 #Frame principal   
    frameIniForm = Frame(can)
    can.pack(side="left", fill="both", expand=True)
    can.create_window(0,0,window=frameIniForm,anchor='nw')
    
    frameHead = Frame(frameIniForm)
    frameHead.grid(row=0 , column=0, padx=0,pady=15)
    
#Frame de logos y titulo  
    presentaFra = Frame(frameHead, highlightbackground="black", highlightcolor="black", highlightthickness=1, bd= 5)
    presentaFra.grid(row=0 , column=0, padx=10)
    
    tituloFra = Frame(presentaFra)
    tituloFra.grid(row=0, column=0)
    Label(tituloFra,text="Ingresar información del comportamineto de pago", font=("Times New Roman",18,"bold","italic"),width=49).grid(row=0, column=0, padx=5)
#Frame de banderas
    frameAmar = Frame(frameHead, background="#FFFB00", width="715", height="5")
    frameAmar.grid(row=1, column=0)
    frameAmar = Frame(frameHead, background="#FFFFFF", width="715", height="5")
    frameAmar.grid(row=2, column=0)
    frameAmar = Frame(frameHead, background="#0D6AE1", width="715", height="5")
    frameAmar.grid(row=3, column=0)

    frameExpli = Frame(frameIniForm)
    frameExpli.grid(row=1, column=0)
    
    Label(frameExpli, text="Los siguientes pasos describen el proceso para ingresar información", font=("",10)).grid(row=0,column=0)
    Label(frameExpli, text="de una persona con respecto a su comportamiento de pago.", font=("",10)).grid(row=1,column=0)
    
    Label(frameExpli, text="Paso 1:", font=("",10,"bold")).grid(row=2,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Con la ayuda de la herramiento Microsoft Excel creee un archivo en formato .csv (Separado por comas).", font=("",10)).grid(row=3, column=0,sticky="w", padx=5, pady=5)    
    
    Label(frameExpli, text="Paso 2:", font=("",10,"bold")).grid(row=4,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Ingrese solo el valor del comportamineto de pago mes a mes de manera vertical en la columana 'A' del documento.", font=("",10)).grid(row=5, column=0,sticky="w", padx=5, pady=5) 
    
    Label(frameExpli, text="Paso 3:", font=("",10,"bold")).grid(row=6,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Ingrese la información de manera ascendente conforme al tiempol ejemplo: Mes 1, Mes 2 ... Mes n.", font=("",10)).grid(row=7, column=0,sticky="w", padx=5, pady=5) 
    
    Label(frameExpli, text="Paso 4:", font=("",10,"bold")).grid(row=8,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Guarde el documento asegurandoce que el formato a guardar es de tipo .csv.", font=("",10)).grid(row=9, column=0,sticky="w", padx=5, pady=5) 
    
    Label(frameExpli, text="Paso 5:", font=("",10,"bold")).grid(row=10,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Selecione el boton 'Subir archivo' del formulario y busque el documento guardado anteriormente.", font=("",10)).grid(row=11, column=0,sticky="w", padx=5, pady=5) 
    
    Label(frameExpli, text="Paso 6:", font=("",10,"bold")).grid(row=12,column=0,sticky="w", padx=5, pady=5)
    Label(frameExpli, text="Selecione el boton 'Abrir'.", font=("",10)).grid(row=13, column=0,sticky="w", padx=5, pady=5) 
        
    raizVetana.update()
    can.config(scrollregion=can.bbox("all"))
    def right_frame(parent):
        rf_width = 300
        rf_height = 360
        # right side frame
        frame_right = LabelFrame(
            parent.building_pos_window,
            text="Building Position",
            width=rf_width - 10,
            height=rf_height - 10,
        )

        frame_right.grid_rowconfigure(0, weight=1)
        frame_right.grid_columnconfigure(0, weight=1)
        frame_right.grid_propagate(False)

        canvas_right = Canvas(frame_right)
        canvas_right.grid(row=0, column=0, sticky=N + W)

        # Link a scrollbar to the canvas
        def on_mousewheel(event):
            canvas_right.yview_scroll(int(-1 * (event.delta / 120)), "units")

        def bound_to_mousewheel(event):
            canvas_right.bind_all("<MouseWheel>", on_mousewheel)

        def unbound_to_mousewheel(event):
            canvas_right.unbind_all("<MouseWheel>")

        y_scrollbar = Scrollbar(frame_right,
                                orient="vertical",
                                command=canvas_right.yview)
        y_scrollbar.grid(row=0, column=1, sticky='ns')
        canvas_right.configure(yscrollcommand=y_scrollbar.set)

        inner_frame_right = Frame(canvas_right)
        inner_frame_right.bind('<Enter>', bound_to_mousewheel)
        inner_frame_right.bind('<Leave>', unbound_to_mousewheel)

        canvas_right.create_window((0, 0),
                                   window=inner_frame_right,
                                   anchor='nw')

        idx = 0
        for e_name in BuildingNames:
            building_name_xy_config_frame(
                inner_frame_right, idx, e_name.value,
                parent.bot_building_pos.get(e_name.value, [-1, -1])
                if parent.bot_building_pos is not None else [-1, -1])
            idx = idx + 1

        inner_frame_right.update_idletasks()

        frame_right.config(width=rf_width - 10, height=360 - 10)
        canvas_right.config(width=rf_width - 10,
                            height=360 - 10,
                            scrollregion=canvas_right.bbox("all"))

        frame_right.grid(row=0, column=1, padx=5, pady=5, sticky=N + W)

        return inner_frame_right
class ScrollFrame(Frame):  # https://gist.github.com/mp035/9f2027c3ef9172264532fcd6262f3b01 by mp035
    def __init__(self, parent):
        super().__init__(parent)  # create a frame (self)

        self.canvas = Canvas(self, borderwidth=0, background='white')  # place canvas on self
        self.viewPort = Frame(self.canvas,
                              background='white')  # place a frame on the canvas, this frame will hold the child widgets
        self.vsb = Scrollbar(self, orient="vertical", command=self.canvas.yview)  # place a scrollbar on self
        self.vsb2 = Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(yscrollcommand=self.vsb.set)  # attach scrollbar action to scroll of canvas
        self.canvas.configure(xscrollcommand=self.vsb2.set)

        self.vsb.pack(side="right", fill="y")  # pack scrollbar to right of self
        self.vsb2.pack(side="bottom", fill="x")
        self.canvas.pack(side="left", fill="both", expand=True)  # pack canvas to left of self and expand to fil
        self.canvas_window = self.canvas.create_window((4, 4), window=self.viewPort, anchor="nw",
                                                       # add view port frame to canvas
                                                       tags="self.viewPort")

        self.viewPort.bind("<Configure>",
                           self.onFrameConfigure)  # bind an event whenever the size of the viewPort frame changes.

        self.onFrameConfigure(
            None)  # perform an initial stretch on render, otherwise the scroll region has a tiny border until the first resize

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox(
            "all"))  # whenever the size of the frame changes, alter the scroll region respectively.
Beispiel #13
0
class ScrollableFrame(Frame):

    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

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

        self.canvas = Canvas(self)
        self.inner_frame = Frame(self.canvas)
        self.vertical_scrollbar = Scrollbar(self, orient=VERTICAL, command=self.canvas.yview)
        self.horizontal_scrollbar = Scrollbar(self, orient=HORIZONTAL, command=self.canvas.xview)
        self.canvas.configure(yscrollcommand=self.vertical_scrollbar.set,
                              xscrollcommand=self.horizontal_scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky='news')
        self.vertical_scrollbar.grid(row=0, column=1, sticky='ns')
        self.horizontal_scrollbar.grid(row=1, column=0, stick='we')

        self.canvas.create_window((4, 4), window=self.inner_frame, anchor='nw')
        self.inner_frame.bind("<Configure>", self._on_frame_configure)

    # noinspection PyUnusedLocal
    def _on_frame_configure(self, event):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
Beispiel #14
0
class ScrollFrame(Frame):
    def __init__(self, parent):
        super().__init__(parent)  # create a frame (self)
        self.canvas = Canvas(self, borderwidth=0)  #place canvas on self
        self.viewPort = Frame(
            self.canvas
        )  #place a frame on the canvas, this frame will hold the child widgets
        self.vsb = Scrollbar(
            self, orient="vertical",
            command=self.canvas.yview)  #place a scrollbar on self
        self.canvas.configure(yscrollcommand=self.vsb.set
                              )  #attach scrollbar action to scroll of canvas

        self.vsb.pack(side="right", fill="y")  #pack scrollbar to right of self
        self.canvas.pack(
            side="left", fill="both",
            expand=True)  #pack canvas to left of self and expand to fil
        self.canvas.create_window(
            (4, 4),
            window=self.viewPort,
            anchor="nw",  #add view port frame to canvas
            tags="self.viewPort")
        self.viewPort.bind(
            "<Configure>", self.onFrameConfigure
        )  #bind an event whenever the size of the viewPort frame changes.

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(
            scrollregion=self.canvas.bbox("all")
        )  #whenever the size of the frame changes, alter the scroll region respectively.
Beispiel #15
0
    def create(self):
        self.pack(side=BOTTOM, fill=BOTH, expand=TRUE)
        canv = Canvas(self, bg="white", relief=SUNKEN)
        # canv.config(width=300, height=200)
        canv.config(scrollregion=(0, 0, 300, 1000))
        canv.config(highlightthickness=0)  #, scrollregion=canv.bbox(ALL))

        sbar = Scrollbar(self)
        sbar.config(command=canv.yview)
        canv.config(yscrollcommand=sbar.set)
        sbar.pack(side=RIGHT, fill=Y)
        canv.pack(expand=YES, fill=BOTH, scrollregion=canv.bbox(ALL))

        for i in range(10):
            canv.create_text(150, 50 + (i * 100), fill='beige')
        canv.bind('<Double-1>', self.onDoubleClick)  # set event handler
        self.canvas = canv
        self.main_elements.canvas = self.canvas

        self.shape_setup.canvas = self.canvas
        self.shape_setup.set_binds()

        # self.canvas.bind('<4>', lambda event: self.canvas.xview('scroll', -1, 'units'))
        # self.canvas.bind('<5>', lambda event: self.canvas.xview('scroll', 1, 'units'))

        canv.bind('<MouseWheel>', self.rollWheel)
        # canv.bind('<Button-5>', self.rollWheel)

        self.parent.update()
Beispiel #16
0
class ScrolledFrame(Frame):
    def __init__(self, master=None, **kw):
        self.frame = Frame(master)
        self.vbar = Scrollbar(self.frame)
        self.vbar.pack(side='right', fill='y')
        self.canvas = Canvas(self.frame,
                             yscrollcommand=self.vbar.set,
                             borderwidth=0,
                             relief='flat',
                             highlightthickness=0,
                             height=400,
                             width=300)
        super().__init__(self.canvas, **kw)
        self.canvas.pack(side='left', fill='both')
        self.vbar.configure(command=self.canvas.yview)
        self.canvas.create_window((4, 4), window=self, anchor='nw')

        self.bind(
            "<Configure>",
            lambda e: self.canvas.config(scrollregion=self.canvas.bbox("all")))

        frame_meths = vars(Frame).keys()
        methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()
        methods = methods.difference(frame_meths)

        for m in methods:
            if m[0] != '_' and m != 'config' and m != 'configure':
                setattr(self, m, getattr(self.frame, m))
Beispiel #17
0
 def addcheck():
     global canvas
     canvas = Canvas(window)
     scroll_y = Scrollbar(window,
                          orient="vertical",
                          command=canvas.yview)
     global frame
     frame = Frame(canvas)
     for item in return_val:
         #Checkbutton(frame, text=item,variable=self.var,onvalue=(lambda x=item:x),offvalue="")
         Button(frame,
                text=item,
                command=(lambda x=item: BUTTON(x))).pack(side=TOP,
                                                         fill=BOTH)
     canvas.create_window(0, 0, anchor='nw', window=frame)
     canvas.update_idletasks()
     canvas.configure(scrollregion=canvas.bbox('all'),
                      yscrollcommand=scroll_y.set)
     canvas.pack(fill='both', expand=True, side='left')
     scroll_y.pack(fill='y', side='right')
     btngetauc.destroy()
     ent2.pack(side=TOP, fill=BOTH)
     ent2.insert(0, "Year")
     entlot.pack(side=TOP, fill=BOTH)
     entlot.insert(0, "LOT")
     btn.pack(side=TOP, fill=BOTH)
     lable.pack(side=TOP, fill=BOTH)
Beispiel #18
0
class VerticalScrollGrid(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.canvas = Canvas(root, borderwidth=0)
        self.frame = Frame(self.canvas)
        self.vsb = Scrollbar(root,
                             orient="vertical",
                             command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.vsb.grid(row=0, column=1, sticky='NS')
        self.vsb.configure(command=self.canvas.yview)
        self.canvas.grid(row=0, column=0, sticky='NSEW')
        self.canvas.create_window((4, 4),
                                  window=self.frame,
                                  anchor="nw",
                                  tags="self.frame")
        self.frame.bind("<Configure>", self.onFrameConfigure)
        self.frame.bind_all("<MouseWheel>", self.on_mousewheel)
        # self.frame.bind("<Button-4>", self.on_mousewheel_up)
        # self.frame.bind("<Button-5>", self.on_mousewheel_down)
    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    # def on_mousewheel_down(self, event): self.canvas.yview_scroll(1, "units")
    # def on_mousewheel_up(self, event): self.canvas.yview_scroll(-1, "units")
    def on_mousewheel(self, event):
        self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")

    def go_to_top(self, event=None):
        self.canvas.yview_moveto(0)
Beispiel #19
0
class VerticalScrollPack(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.canvas = Canvas(root, borderwidth=0)
        self.frame = Frame(self.canvas)
        self.vsb = Scrollbar(root,
                             orient="vertical",
                             command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4, 4),
                                  window=self.frame,
                                  anchor="nw",
                                  tags="self.frame")
        self.frame.bind("<Configure>", self.onFrameConfigure)
        self.frame.bind_all("<MouseWheel>", self.on_mousewheel)

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def on_mousewheel(self, event):
        self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")

    def go_to_top(self, event=None):
        self.canvas.yview_moveto(0)
Beispiel #20
0
class Scrollable(Frame):
    def __init__(self, master, outer_kwargs={}):
        Frame.__init__(self, master, **outer_kwargs)
        self.master = master
        self.canvas = Canvas(self, borderwidth=0, highlightthickness=0)
        self.frame = Frame(self.canvas, borderwidth=0)
        self.scrollbar = Scrollbar(self,
                                   orient=VERTICAL,
                                   command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.scrollbar.pack(side=RIGHT, fill=Y, expand=False)
        self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
        self.canvas.create_window((0, 0), window=self.frame, tag='self.frame')
        self.frame.bind(
            '<Configure>', lambda event: self.canvas.configure(
                scrollregion=self.canvas.bbox('all')))
        self.canvas.bind(
            '<Configure>',
            lambda event: self.canvas.itemconfig('self.frame',
                                                 width=event.width))
        self.canvas.bind_all(
            '<MouseWheel>', lambda event: self.canvas.yview_scroll(
                -2 * event.delta // 120, 'units'))
        self.canvas.yview_moveto(0)

    def scroll_to(self, coord: float):
        self.canvas.yview_moveto(coord)

    def get_coord(self):
        return self.canvas.yview()
class Scrollable(ttk.Frame):
    """Luo tkinter-frame:n, joka sisältää scrollbarin.
    Koodi (pienin muutoksin) on saatu täältä:
    https://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter/3092341
    """
    def __init__(self, frame):
        scrollbar = ttk.Scrollbar(frame)
        scrollbar.pack(side=constants.RIGHT, fill=constants.Y, expand=False)

        self.canvas = Canvas(frame, yscrollcommand=scrollbar.set)
        self.canvas.pack(side=constants.LEFT, fill=constants.BOTH, expand=True)

        scrollbar.config(command=self.canvas.yview)

        self.canvas.bind('<Configure>', self.__fill_canvas)

        ttk.Frame.__init__(self, frame)

        self.windows_item = self.canvas.create_window(0,
                                                      0,
                                                      window=self,
                                                      anchor=constants.NW)

    def __fill_canvas(self, event):
        """Suurentaa windows item:n canvas-leveyteen"""

        canvas_width = event.width
        self.canvas.itemconfig(self.windows_item, width=canvas_width)

    def update(self):
        """Päivittää canvas-olion scrollregionin"""

        self.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))
Beispiel #22
0
 def change_map(map: Map, canvas: Canvas, path: str, button_index: int,
                window):
     if path:
         map.change_map(path, window)
         width = canvas.winfo_width()
         height = canvas.winfo_height()
         if map.image_id:
             canvas.delete(map.image_id)
         map.image_id = canvas.create_image(width / 2,
                                            height / 2,
                                            anchor="center",
                                            image=map.image)
         print(canvas.bbox(map.image_id))
         if map.last_line_id:
             canvas.tag_raise(map.last_line_id)
         for oval in map.path_delimitation:
             canvas.tag_raise(oval)
         if map.current_button:
             map.current_button.configure(bg="white")
         map.boutons_heures[button_index].configure(bg="gray")
         print(map.boutons_heures[button_index])
         map.current_button = map.boutons_heures[button_index]
         map.current_button_index = button_index
         if map.etape == "tracé":
             map.show_instruction("Tracez la route voulue")
         elif map.etape == "courant":
             map.show_instruction(
                 "Choisissez une heure de départ et tracez les courants du trajet"
             )
         for foreground_item in map.foreground_items:
             canvas.tag_raise(foreground_item)
def addScrollingFigure(figure, frame):
  global canvas, mplCanvas, interior, interior_id, cwid
  # set up a canvas with scrollbars
  canvas = Canvas(frame)
  canvas.grid(row=1, column=1, sticky=Tkconstants.NSEW)

  xScrollbar = Scrollbar(frame, orient=Tkconstants.HORIZONTAL)
  yScrollbar = Scrollbar(frame)

  xScrollbar.grid(row=2, column=1, sticky=Tkconstants.EW)
  yScrollbar.grid(row=1, column=2, sticky=Tkconstants.NS)

  canvas.config(xscrollcommand=xScrollbar.set)
  xScrollbar.config(command=canvas.xview)
  canvas.config(yscrollcommand=yScrollbar.set)
  yScrollbar.config(command=canvas.yview)

  # plug in the figure
  figAgg = FigureCanvasTkAgg(figure, canvas)
  mplCanvas = figAgg.get_tk_widget()
  #mplCanvas.grid(sticky=Tkconstants.NSEW)

  # and connect figure with scrolling region
  cwid = canvas.create_window(0, 0, window=mplCanvas, anchor=Tkconstants.NW)
  printBboxes("Init")
  canvas.config(scrollregion=canvas.bbox(Tkconstants.ALL),width=200,height=200)
Beispiel #24
0
def update_accidents_table():
    for widget in accidents_tab.winfo_children():
        widget.destroy()
    headers = ['Cars', 'Lap', 'Session', '', '']

    scrollbar = Scrollbar(accidents_tab, orient='vertical')
    scrollbar.grid(row=0, column=1, sticky='ns')

    canvas = Canvas(accidents_tab, yscrollcommand=scrollbar.set)
    canvas.create_image(0, 0, anchor='ne')
    canvas['scrollregion'] = (0, 0, 0, (len(listed_accidents) + 1) * 30)
    canvas['width'] = 565
    canvas['height'] = 370
    canvas.grid(row=0, column=0)

    scrollbar.config(command=canvas.yview)
    canvas.config(scrollregion=canvas.bbox("all"))

    table = Frame(canvas)

    for j, column in enumerate(headers):
        label = Label(table,
                      text=column,
                      width=15,
                      height=2,
                      font='Helvetica 8 bold')
        label.grid(row=0, column=j, sticky="nsew", padx=1, pady=1)
        table.grid_columnconfigure(j, weight=1)
    for i, row in enumerate(listed_accidents):
        for j, column in enumerate(row):
            label = Label(table, text=column, bg='Light Gray', height=1)
            label.grid(row=i + 1, column=j, sticky="nsew", padx=1, pady=1)
            table.grid_columnconfigure(j, weight=1)
            if j == 2:
                dismiss_button = Button(
                    table,
                    text="Racing Incident",
                    bg='medium sea green',
                    width=5,
                    command=lambda row=i: dismiss_accident(row))
                penalty_button = Button(table,
                                        text="Penalty",
                                        bg='indian red',
                                        width=5,
                                        command=lambda row=i: add_penalty(row))

                dismiss_button.grid(row=i + 1,
                                    column=j + 1,
                                    padx=1,
                                    pady=1,
                                    sticky="nsew")
                penalty_button.grid(row=i + 1,
                                    column=j + 2,
                                    padx=1,
                                    pady=1,
                                    sticky="nsew")
                table.grid_columnconfigure(j + 1, weight=1)

    canvas.create_window((0, 0), window=table, anchor='nw')
Beispiel #25
0
def canvas_write(input_image, canvas_width=800, canvas_height=600):
   
    def get_char_dimensions(canvas, selected_font):
        oneChar = canvas.create_text(20, 20, text=" ", font=selected_font)
        bounds = canvas.bbox(oneChar)  # returns a tuple like (x1, y1, x2, y2)
        char_width = bounds[2] - bounds[0]
        char_height = bounds[3] - bounds[1]
        print(f'Char width: {char_width} Char height: {char_height}')
        canvas.delete(oneChar)
        return (char_width, char_height)
    
    def resize_to_ratio(input_image, char_dimensions):
        width, height = input_image.size
        image_ratio = width  / height
        adjusted_width, adjusted_height = width, height
           
        if width * char_dimensions[0] > canvas_width:
            adjusted_width = math.floor(canvas_width / char_dimensions[0])
            adjusted_height = math.floor(adjusted_width / image_ratio)
         
        while adjusted_height * char_dimensions[1] > canvas_height:   
            adjusted_width = adjusted_width - 1
            adjusted_height = math.floor(adjusted_width / image_ratio)
        
        # Font has usually has higher height, so we increase width accordinly to avoid elongated images
        font_ratio = char_dimensions[0]/char_dimensions[1]
        adjusted_width = math.floor(adjusted_width / font_ratio)
        
        print(f'Width: {adjusted_width} Height: {adjusted_height}')
        resized_image = input_image.resize((adjusted_width, adjusted_height), Image.ANTIALIAS)
        return resized_image
          
    
    root = Tk()
    canvas = Canvas(root,  width=canvas_width, height=canvas_height)
    
    #Smaller font gives more details
    font_size = 4
    monospace_font = font.Font(family='Consolas', size=font_size)
    char_dimensions = get_char_dimensions(canvas, monospace_font)
    
    resized_input = resize_to_ratio(input_image, char_dimensions) 
    resized_input = find_edges(resized_input)    

    ascii_image = convert_to_ascii(resized_input)
    
    text_file = open("res.txt", "w")
    text_file.write(ascii_image)
    text_file.close() 

    # Draw image to canvas  
    drawn_text = canvas.create_text(canvas_width/2, canvas_height/2, text=ascii_image, font=monospace_font, anchor="c")
    
    text_bbox = canvas.bbox(drawn_text)
    rect_item = canvas.create_rectangle(text_bbox, outline="red", fill="white")  
    canvas.tag_raise(drawn_text,rect_item)

    canvas.pack()
    root.mainloop()
class Window(Frame):
    def __init__(self, parent):
        super(Window, self).__init__(parent)
        self.parent = parent
        self.grid(row=0,column=0)      

        # Entry, Start
        self.entry = Entry(self)
        self.entry.grid(column=0, row=0, padx=1,pady=0)
        self.entry.bind('<Return>',self.started)
        self.btn_start = Button(self, text='start',command=self.started)
        self.btn_start.grid(column=1, row=0, padx=2, pady=2)

        # Result
        self.results=Frame(self, background='blue')
        self.canvas=Canvas(self.results, background='green')
        self.labels_frame=Frame(self.canvas, background='pink')
        self.scrollbar = ttk.Scrollbar(self.results, orient='vertical', command=self.canvas.yview)
        self.heading=Label(self.labels_frame, text='Suchergebnisse:', anchor='w',width=50)     

        self.results.grid(row=1,column=0,sticky='w',padx=2,pady=2, columnspan=2)
        self.canvas.grid(row=0,column=0, padx=2,pady=2)#todo delete padding
        #self.labels_frame.grid(row=0,column=0, padx=2,pady=2)#benötigt obwohl canvas.create_window?
        self.heading.grid(column=0,row=0,columnspan=3,sticky='wesn', padx=2, pady=2)
        self.canvas.create_window(0, 0, anchor='nw', window=self.labels_frame)#,height=250,width=300)
        
    def started(self, events=None): 
        self.found_foods=[]
        for i in range(int(self.entry.get())):
            self.found_foods.append(i)
        self.create_labels()
                
    def create_labels(self):
        labels=[]
        for found_food in self.found_foods:
            name_label = Label(self.labels_frame, text=found_food, anchor='w') 
            category_label = Label(self.labels_frame, text='--missing yet--', anchor='w')
            labels.append([name_label,category_label])
        self.update_view(labels)

    def update_view(self,labels):
        self.del_old_labels()
        for row,labelrow in enumerate(labels):
            for col,element in enumerate(labelrow):
                element.grid(row=row+1, column=col, padx=1,pady=1, sticky='wsen')

        if len(self.found_foods)>10: #10 nur als Bsp
            0self.canvas.update_idletasks() #no idea what this does
            self.canvas.config(yscrollcommand=self.scrollbar.set)
            self.canvas.config(height=250,width=300)
            self.canvas.configure(scrollregion=self.canvas.bbox('all'))
            self.scrollbar.grid(row=0,column=1, sticky='ns',padx=2,pady=2)
        else:
            self.scrollbar.grid_forget()

    def del_old_labels(self):
        for label in self.labels_frame.grid_slaves():
            if int(label.grid_info()["row"]) > 0:
                label.grid_forget()            
Beispiel #27
0
 def calculer_decalage_latitude(event, map: Map, canvas: Canvas):
     x, y, _, _ = canvas.bbox(map.image_id)
     map.settings["decalage_pixels_latitude"] = event.y - y
     if map.last_line_id:
         canvas.delete(map.last_line_id)
     map.save_settings()
     map.etape = "tracé"
     map.show_instruction("Tracez la route voulue")
Beispiel #28
0
class ListDialog(object):
    def __init__ (self, master, items, message, accept_func):
        self.accept_func = accept_func

        self.top = Toplevel(master)
        self.top.transient(master)
        self.top.rowconfigure(0, weight=1)
        self.top.rowconfigure(1, weight=3)
        self.top.rowconfigure(2, weight=0)
        self.top.columnconfigure(0, weight=1)
        self.top.columnconfigure(1, weight=1)
        self.top.resizable(width=True, height=True)

        self.frame = Frame(self.top)
        self.frame.rowconfigure(0, weight=1)
        self.frame.rowconfigure(1, weight=0)
        self.frame.columnconfigure(0, weight=1)
        self.frame.columnconfigure(1, weight=0)
        self.frame.grid(row=0, column=0, sticky=(N, S, W, E), columnspan=2)
        self.canvas = Canvas(self.frame)
        self.canvas.create_text(0, 0, text=message, anchor=NW)
        self.canvas.grid(row=0, column=0, sticky=(N, W, S, E))

        self.vscroll = Scrollbar(self.frame, command=self.canvas.yview)
        self.vscroll.grid(row=0, column=1, sticky=(N, S))
        self.canvas['yscrollcommand'] = self.vscroll.set

        self.hscroll = Scrollbar(self.frame, command=self.canvas.xview, orient=HORIZONTAL)
        self.hscroll.grid(row=1, column=0, sticky=(W, E), columnspan=2)
        self.canvas['xscrollcommand'] = self.hscroll.set

        self.canvas['scrollregion'] = self.canvas.bbox('all')
        self.canvas.bind('<Button-4>', self.scroll)
        self.canvas.bind('<Button-5>', self.scroll)
        self.canvas.bind('<MouseWheel>', self.scroll)

        self.view = NameView(self.top, sorted(items))
        self.view.widget.grid(row=1, column=0, columnspan=2, sticky=(N, W, E, S))

        self.delbutton = Button(self.top, text='Ok', command=self.accept )
        self.cancelbutton = Button(self.top, text='Cancel', command=self.cancel)
        self.delbutton.grid(row=2, column=0)
        self.cancelbutton.grid(row=2, column=1)
        self.view.widget.focus_set()

    def accept(self):
        self.accept_func(self.view.selection())
        self.top.destroy()

    def cancel(self):
        self.result = None
        self.top.destroy()

    def scroll(self, event):
        if event.num == 4 or event.delta > 0:
            self.canvas.yview(SCROLL, -1, UNITS)
        elif event.num == 5 or event.delta < 0:
            self.canvas.yview(SCROLL, 1, UNITS)
Beispiel #29
0
def view_admin():
    try:
        admin_list = [session.query(Admin).filter_by(username="******").first()]
        admin_list += session.query(Admin).filter(
            Admin.username != "admin").all()
    except:
        messagebox.showerror("Error",
                             "Couldn't Fetch The Admins' Table From The DB")
        session.rollback()
        return

    subwindow = Toplevel(window)
    subwindow.title("Admins")
    subwindow.geometry("450x600+400+200")

    canvas = Canvas(subwindow)
    scrollable_frame = Frame(canvas)
    scrollable_frame.bind(
        "<Configure>",
        lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
    canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")

    scrollbary = Scrollbar(subwindow, orient="vertical", command=canvas.yview)
    scrollbarx = Scrollbar(subwindow,
                           orient="horizontal",
                           command=canvas.xview)

    canvas.configure(xscrollcommand=scrollbarx.set)
    canvas.configure(yscrollcommand=scrollbary.set)

    scrollbary.pack(side="right", fill="y")
    scrollbarx.pack(side="bottom", fill="x")
    canvas.pack(side="left", fill="both", expand=True)

    ttk.Label(scrollable_frame, text="index").grid(row=0,
                                                   column=0,
                                                   ipadx=5,
                                                   ipady=1)
    ttk.Label(scrollable_frame, text="UserName").grid(row=0,
                                                      column=1,
                                                      ipadx=5,
                                                      ipady=1)

    for i in range(len(admin_list)):
        ttk.Label(scrollable_frame, text=i + 1).grid(row=i + 1,
                                                     column=0,
                                                     ipadx=5,
                                                     ipady=1)
        ttk.Label(
            scrollable_frame,
            text=admin_list[i].username,
        ).grid(row=i + 1, column=1, ipadx=5, ipady=1)
        ttk.Button(
            scrollable_frame,
            text="Remove",
            command=lambda username=admin_list[i].username: remove_admin(
                username),
        ).grid(row=i + 1, column=7, ipadx=1, ipady=1)
Beispiel #30
0
def upload_film_data():
    current_folder = os.getcwd()
    os.chdir(os.path.dirname(sys.argv[0]))
    img = Image.open(Globals.map_dose_film_dataset.get())
    if(not (img.width == 1016 or img.width == 576)):
        messagebox.showerror("Error", "Dpi in image has to be 127 or 72")
        return

    Globals.map_dose_isocenter_map_x_coord_scaled = []
    Globals.map_dose_isocenter_map_x_coord_unscaled = []
    Globals.map_dose_isocenter_map_y_coord_scaled = []
    Globals.map_dose_isocenter_map_y_coord_unscaled = []

    mark_isocenter_window = tk.Toplevel(Globals.tab3)
    mark_isocenter_window.grab_set()
    frame = Frame(mark_isocenter_window, bd=2, relief=SUNKEN)
    frame.grid_rowconfigure(0, weight=1)
    frame.grid_columnconfigure(0, weight=1)
    canvas = Canvas(frame, bd=0)
    canvas.grid(row=0, column=0, sticky=N+S+E+W)

    
    scale_horizontal = img.width/408
    scale_vertical = img.height/508
    img = img.resize((408,508))
    img = ImageTk.PhotoImage(image=img)
    os.chdir(current_folder)
    canvas.image = img

    w = 10 + img.width()
    h = 10 + img.height()
    mark_isocenter_window.geometry("%dx%d+0+0" % (w, h))
    canvas.create_image(0,0,image=img,anchor="nw")
    canvas.config(scrollregion=canvas.bbox(ALL), cursor='sb_up_arrow')
    #x_coor = []
    #y_coor = []
    
    def findCoords(event):
        Globals.map_dose_isocenter_map_x_coord_scaled.append(event.x*scale_vertical)
        Globals.map_dose_isocenter_map_y_coord_scaled.append(event.y*scale_horizontal)
        Globals.map_dose_isocenter_map_x_coord_unscaled.append(event.x)
        Globals.map_dose_isocenter_map_y_coord_unscaled.append(event.y)
        canvas.create_oval(event.x-2, event.y-2, event.x+2, event.y+2, fill='red')
        if (len(Globals.map_dose_isocenter_map_x_coord_scaled)==1):
            canvas.config(cursor='sb_down_arrow')
        elif(len(Globals.map_dose_isocenter_map_x_coord_scaled)==2):
            canvas.config(cursor='sb_right_arrow')
        elif(len(Globals.map_dose_isocenter_map_x_coord_scaled)==3):
            canvas.config(cursor='sb_left_arrow')
        else:
            #mark_isocenter_window.destroy()
            draw_image_with_marks(img, scale_horizontal, scale_vertical, mark_isocenter_window, frame)
            
    
    
    canvas.bind("<Button 1>",findCoords)
    frame.pack(fill='both', expand=1)
Beispiel #31
0
class GUI():

    """
    Method gets a Tk instance (master) and a model instance implemented with nengo.
    It then creates a GUI with the polts that where specified in create_plot(...).
    """

    def __init__(self, master, model):
        self.f = 0

        master.rowconfigure(0, weight=1)
        master.columnconfigure(0, weight=1)

        self.frame = tk.Frame(master)
        self.frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.frame.grid(sticky=NSEW)
        self.frame.rowconfigure(0, weight=1)
        self.frame.columnconfigure(0, weight=1)

        self.scroll_canvas = Canvas(self.frame)
        self.scroll_canvas.grid(row=0, column=0, sticky=NSEW)

        xScrollbar = Scrollbar(self.frame, orient=HORIZONTAL)
        yScrollbar = Scrollbar(self.frame)

        xScrollbar.grid(row=1, column=0, sticky=EW)
        yScrollbar.grid(row=0, column=1, sticky=NS)

        self.scroll_canvas.config(xscrollcommand=xScrollbar.set)
        xScrollbar.config(command=self.scroll_canvas.xview)
        self.scroll_canvas.config(yscrollcommand=yScrollbar.set)
        yScrollbar.config(command=self.scroll_canvas.yview)

        self.create_plot(model)

        self.figure_canvas = FigureCanvasTkAgg(self.f, master=self.scroll_canvas)
        self.canvas = self.figure_canvas.get_tk_widget()
        self.canvas.pack(side=tk.TOP, fill=tk.BOTH, padx=5, pady=5, expand=1)

        self.scroll_canvas.create_window(0, 0, window=self.canvas)
        self.scroll_canvas.config(scrollregion=self.scroll_canvas.bbox(ALL))
        self.figure_canvas.show()

        self.toolbar = NavigationToolbar2TkAgg(self.figure_canvas, self.scroll_canvas)
        self.toolbar.pack()
        self.toolbar.update()

        """
        Adds the specified plots to the figure displayed in the GUI. It gets a model instance implemented with nengo
        """
    def create_plot(self, model):

        self.f = Figure(figsize=(16, 9), dpi=80)

        """
        Example plot which plots the integrators back connection, its input, its real value and the real robot goal angle
        """
        self.ax00 = self.f.add_axes((.2, .2, .6, .6), axisbg=(.75, .75, .75), frameon=True)
        self.ax00.plot(model.sim.trange(), model.sim.data[model.integrator_probe], label = 'Integrator')
        self.ax00.plot(model.sim.trange(), model.sim.data[model.integrator_connection_probe], label = 'Con')
        self.ax00.plot(model.sim.trange(), model.sim.data[model.integrator_self_connection_probe], label = 'Self Con')
        self.ax00.plot(model.sim.trange(), model.sim.data[model.robot_goal_neuron_probe][:, 2], label = 'Real')
        self.ax00.legend()
class RadiobuttonEntry(ttk.Frame):
    """State entry for the entire conflict. A set of RadioButtonSeries."""

    def __init__(self, master, conflict):
        """State entry widget for the entire conflict."""
        ttk.Frame.__init__(self, master)

        self.conflict = conflict

        self.rbeCanvas = Canvas(self)
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.scrollY = ttk.Scrollbar(self, orient=VERTICAL,
                                     command=self.rbeCanvas.yview)

        self.rbeCanvas.grid(column=0, row=0, columnspan=2, sticky=NSEW)
        self.scrollY.grid(column=2, row=0, sticky=NSEW)
        self.rbeCanvas.configure(yscrollcommand=self.scrollY.set)
        self.canvWindow = self.rbeCanvas.create_window((0, 0),
                                                       window=self.rdBtnFrame,
                                                       anchor='nw')

        self.rowconfigure(0, weight=1)

        self.entryText = StringVar(value='')

        vcmd = self.register(self.onValidate)
        self.entryBx = ttk.Entry(self, textvariable=self.entryText,
                                 validate="key",
                                 validatecommand=(vcmd, '%S', '%P'))
        self.entryBx.grid(column=0, row=1, sticky=NSEW)
        self.entryBx.bind('<Return>', self.generateAdd)

        self.warnText = StringVar(value='')
        self.warnLab = ttk.Label(self, textvariable=self.warnText, width=18)
        self.warnLab.grid(column=1, row=1, sticky=NSEW)

        self.codeText = StringVar(value='')

        vcmd2 = self.register(self.onValidate2)
        self.codeBx = ttk.Entry(self, textvariable=self.codeText,
                                validate="key",
                                validatecommand=(vcmd2, '%S', '%P'))
        self.codeBx.grid(column=0, row=2, sticky=NSEW)
        self.codeBx.bind('<Return>', self.generateAdd)

        self.warnText2 = StringVar(value='')
        self.warnLab2 = ttk.Label(self, textvariable=self.warnText2)
        self.warnLab2.grid(column=1, row=2, sticky=NSEW)

        self.addBtn = ttk.Button(self, text='Add as Prefered State',
                                 command=self.generateAdd)
        self.stageBtn = ttk.Button(self, text='Add to Staging',
                                   command=self.generateStage)

        self.addBtn.grid(column=0, row=4, columnspan=2, sticky=NSEW)
        self.stageBtn.grid(column=0, row=5, columnspan=2, sticky=NSEW)

        self.isDisabled = False

        self.columnconfigure(0, weight=1)

        self.reloadOpts()

        self.regexValidChars = re.compile(r'^[-\d, fi]*$')
        self.regexStatesIf = re.compile(r'^ *(-)?(\d+) *iff? *(-)?(\d+) *$')
        self.regexStates = re.compile(r' *(-)?(\d+) *')

        self.hasValidIf = False

    def resize(self, event=None):
        """Adjust the canvas widget if the window is resized."""
        self.rbeCanvas.configure(scrollregion=self.rbeCanvas.bbox("all"))
        self.rbeCanvas["width"] = self.rbeCanvas.bbox("all")[2]

    def generateAdd(self, event=None):
        """Generate event if a preference is added."""
        self.event_generate('<<AddPref>>')

    def generateStage(self, event=None):
        """Generate event if a preference is staged."""
        self.event_generate('<<StagePref>>')

    def reloadOpts(self):
        """Reload options for all decision makers."""
        self.rbeCanvas.delete(self.canvWindow)
        self.rdBtnFrame.destroy()
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.canvWindow = self.rbeCanvas.create_window((0, 0),
                                                       window=self.rdBtnFrame,
                                                       anchor='nw')
        self.rdBtnFrame.bind('<<RdBtnChg>>', self.rdBtnChgCmd)
        self.rdBtnFrame.bind("<Configure>", self.resize)

        self.rdBtnSrs = []
        self.stringVarList = []

        for x, dm in enumerate(self.conflict.decisionMakers):
            a = RadiobuttonSeries(self.rdBtnFrame, dm)
            self.rdBtnSrs.append(a)
            a.setOpts(dm.options)
            a.grid(column=0, row=int(x), sticky=NSEW)
            self.stringVarList += a.stringVarList

        self.rdBtnChgCmd()

        if self.isDisabled:
            self.disable()

    def disable(self, event=None):
        """Disable the widget and all children."""
        self.isDisabled = True
        self.entryBx['state'] = 'disabled'
        self.codeBx['state'] = 'disabled'
        self.addBtn['state'] = 'disabled'
        self.stageBtn['state'] = 'disabled'
        for srs in self.rdBtnSrs:
            srs.disable()

    def enable(self, event=None):
        """Enable the widget and all children."""
        self.isDisabled = False
        self.entryBx['state'] = 'normal'
        self.codeBx['state'] = 'normal'
        self.addBtn['state'] = 'normal'
        self.stageBtn['state'] = 'normal'
        for srs in self.rdBtnSrs:
            srs.enable()

    def setStates(self, dashOne):
        """Set the states shown on the radiobuttons."""
        if dashOne == 'clear':
            for var in self.stringVarList:
                var.set('-')
            self.entryText.set('-' * len(self.stringVarList))
            return
        if len(dashOne) != len(self.stringVarList):
            raise Exception("string is wrong length: {}".format(dashOne))
        for x, y in enumerate(dashOne):
            self.stringVarList[x].set(y)
        self.entryText.set(dashOne)
        self.hasValidIf = False

    def getStates(self):
        """Get the states shown on the radiobuttons in YN- format."""
        if self.hasValidIf:
            return self.ifCond

        states = []
        for srs in self.rdBtnSrs:
            states.extend(srs.getStates())
        return states

    def onValidate(self, chg, res):
        """Validation of entrybox state description string."""
        if chg in ['Y', 'N', 'y', 'n', '-']:
            if len(res) < len(self.stringVarList):
                self.warnText.set('Entry too short')
                return True
            if len(res) == len(self.stringVarList):
                self.setStates(res.upper())
                self.warnText.set('')
                return True
        return False

    def onValidate2(self, chg, res):
        """Validate condition input string."""
        if self.regexValidChars.match(res):
            if "if" in res:
                m = self.regexStatesIf.match(res)
                if m:
                    self.warnText2.set('')
                    self.handleIf(res, m.groups())
                else:
                    self.warnText2.set('Invalid')
            else:
                states = res.split(',')
                sts2 = []
                for st in states:
                    m = self.regexStates.match(st)
                    if m:
                        sts2.append(m.groups())
                    else:
                        self.warnText2.set('Invalid')
                        return True
                self.warnText2.set('')
                setTo = '-' * len(self.stringVarList)
                for neg, st in sts2:
                    if int(st) > len(self.stringVarList):
                        self.warnText2.set(st + ' is too large')
                        return True
                    if setTo[int(st) - 1] != "-":
                        self.warnText2.set("Too many " + st + "s")
                        return True
                    if neg:
                        setTo = setTo[:(int(st) - 1)] + 'N' + setTo[int(st):]
                    else:
                        setTo = setTo[:(int(st) - 1)] + 'Y' + setTo[int(st):]
                self.setStates(setTo)

            return True
        self.warnText2.set('Invalid')
        return False

    def handleIf(self, string, states):
        """Q if P (equivalent to 'If p, then q')."""
        if int(states[1]) > len(self.stringVarList):
            self.warnText2.set(states[1] + ' is too large')
            return True
        elif int(states[3]) > len(self.stringVarList):
            self.warnText2.set(states[3] + ' is too large')
            return True
        elif states[1] == states[3]:
            self.warnText2.set("duplicate")
            return True

        q = [self.conflict.options[int(states[1]) - 1],
             "N" if states[0] else "Y"]
        nq = [self.conflict.options[int(states[1]) - 1],
              "Y" if states[0] else "N"]   # not q
        p = [self.conflict.options[int(states[3]) - 1],
             "N" if states[2] else "Y"]
        np = [self.conflict.options[int(states[3]) - 1],
              "Y" if states[2] else "N"]   # not p

        newCondition = None

        if "iff" in string:
            newCondition = self.conflict.newCompoundCondition([[p, q],
                                                               [np, nq]])
        else:
            newCondition = self.conflict.newCompoundCondition([[p, q], [np, q],
                                                               [np, nq]])

        self.setStates(' ' * len(self.stringVarList))
        self.hasValidIf = True
        self.ifCond = newCondition

    def rdBtnChgCmd(self, *args):
        """Update display on input through radiobuttons."""
        val = ''.join([x.get() for x in self.stringVarList])
        self.entryText.set(val)
        self.warnText.set('')

        val = [[i + 1, x.get()] for i, x in enumerate(self.stringVarList)
               if (x.get() != "-")]
        outVar = []
        for i, x in val:
            if x == "N":
                outVar.append("-" + str(i))
            else:
                outVar.append(str(i))

        self.codeText.set(", ".join(outVar))

        self.warnText2.set('')
class RadiobuttonEntry(ttk.Frame):
    """State entry for all DMs, and controls for adding the infeasibles.

    Uses a set of RadioButtonSeries elements.
    """

    def __init__(self, master, conflict):
        """Initialize the widget."""
        ttk.Frame.__init__(self, master)

        self.conflict = conflict

        self.dmLookup = {dm.name: dm for dm in self.conflict.decisionMakers}
        dmNames = tuple(self.dmLookup.keys())
        self.activeDMname = StringVar(value=dmNames[0])
        self.activeDM = self.dmLookup[dmNames[0]]

        dmSelLabel = ttk.Label(self, text="Decision Maker")
        dmSelLabel.grid(column=0, row=0)

        self.dmSelector = ttk.Combobox(self, textvariable=self.activeDMname,
                                       values=dmNames, state='readonly')
        self.dmSelector.grid(column=1, row=0, sticky=NSEW)
        self.dmSelector.bind('<<ComboboxSelected>>', self.dmSel)

        self.rbeCanvas = Canvas(self)
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.scrollY = ttk.Scrollbar(self, orient=VERTICAL,
                                     command=self.rbeCanvas.yview)

        self.rbeCanvas.grid(column=0, row=1, columnspan=2, sticky=NSEW)
        self.scrollY.grid(column=2, row=1, sticky=NSEW)
        self.rbeCanvas.configure(yscrollcommand=self.scrollY.set)
        self.canvWindow = self.rbeCanvas.create_window(
            (0, 0), window=self.rdBtnFrame, anchor='nw')

        self.rowconfigure(1, weight=1)

        self.entryText = StringVar(value='')

        vcmd = self.register(self.onValidate)
        self.entryBx = ttk.Entry(self, textvariable=self.entryText,
                                 validate="key",
                                 validatecommand=(vcmd, '%S', '%P'))
        self.entryBx.grid(column=0, row=2, columnspan=2, sticky=NSEW)
        self.entryBx.bind('<Return>', self.generateAdd)

        self.warnText = StringVar(value='')

        self.addBtn = ttk.Button(self, text='Remove as Misperceived Condition',
                                 command=self.generateAdd)
        self.mutExBtn = ttk.Button(self,
                                   text='Perceived as Mutually Exclusive',
                                   command=self.generateMutEx)
        self.warnLab = ttk.Label(self, textvariable=self.warnText)
        self.warnLab.grid(column=0, row=3, sticky=NSEW)
        self.addBtn.grid(column=0, row=4, columnspan=2, sticky=NSEW)
        self.mutExBtn.grid(column=0, row=5, columnspan=2, sticky=NSEW)

        self.reloadOpts()

    def resize(self, event=None):
        """Resize the scroll region of the main canvas element."""
        self.rbeCanvas.configure(scrollregion=self.rbeCanvas.bbox("all"))
        self.rbeCanvas["width"] = self.rbeCanvas.bbox("all")[2]

    def generateAdd(self, *args):
        """Prompt response to addition of an infeasible state."""
        self.event_generate('<<addMisperceived>>')

    def generateMutEx(self, *args):
        """Prompt response to addition of a mutually exclusive set."""
        self.event_generate('<<AddMutEx>>')

    def reloadOpts(self):
        """Reload all options for all DMs."""
        self.rbeCanvas.delete(self.canvWindow)
        self.rdBtnFrame.destroy()
        self.rdBtnFrame = ttk.Frame(self.rbeCanvas)
        self.canvWindow = self.rbeCanvas.create_window(
            (0, 0), window=self.rdBtnFrame, anchor='nw')
        self.rdBtnFrame.bind('<<RdBtnChg>>', self.rdBtnChgCmd)
        self.rdBtnFrame.bind("<Configure>", self.resize)

        self.rdBtnSrs = []
        self.stringVarList = []

        for x, dm in enumerate(self.conflict.decisionMakers):
            a = RadiobuttonSeries(self.rdBtnFrame, dm)
            self.rdBtnSrs.append(a)
            a.setOpts(dm.options)
            a.grid(column=0, row=int(x), sticky=NSEW)
            self.stringVarList += a.stringVarList

        self.rdBtnChgCmd()

    def setStates(self, dashOne):
        """Change the condition selected on the radio buttons."""
        if len(dashOne) != len(self.stringVarList):
            raise Exception('string length does not match number '
                            'of options: {}'.format(dashOne))
        for x, y in enumerate(dashOne):
            self.stringVarList[x].set(y)
        self.entryText.set(dashOne)

    def getStates(self):
        """Get the condition selected on the radio buttons."""
        states = []
        for srs in self.rdBtnSrs:
            states.extend(srs.getStates())
        return states

    def onValidate(self, chg, res):
        """Validate manually entered condition characters and length."""
        if chg in ['Y', 'N', 'y', 'n', '-']:
            if len(res) < len(self.stringVarList):
                self.warnText.set('Entry too short')
                return True
            if len(res) == len(self.stringVarList):
                self.setStates(res.upper())
                self.warnText.set('')
                return True
        return False

    def rdBtnChgCmd(self, *args):
        """Set the entry box value to match the radiobuttons."""
        val = ''.join([x.get() for x in self.stringVarList])
        self.entryText.set(val)

    def dmSel(self, *args):
        """Prompt response to a different DM being selected."""
        dmName = self.activeDMname.get()
        self.activeDM = self.dmLookup[dmName]
        self.event_generate('<<ChangeDM>>')
Beispiel #34
0
class GraphView(View):
	WIN_PADDING_Y = 16
	POINT_MARGIN = 2

	def __init__(self, params):
		super(GraphView, self).__init__(params)

		self._ids = params["ids"] if "ids" in params else ""
		self._ids = [int(i) for i in self._ids.split(' ')]
		self._labels = params["labels"] if "labels" in params else ""
		self._labels = [l for l in self._labels.split(' ')]
		self._colors = [c for c in params["colors"].split(' ')] if "colors" in \
				params else None
		if not self._colors:
			self._colors = self._get_auto_colors(len(self._ids))
		if not len(self._ids) == len(self._labels) == len(self._colors):
			raise RuntimeError("ids, labels and colors must share the same size")

		self._min = float(params["min"]) if "min" in params else -1000
		self._max = float(params["max"]) if "max" in params else 1000
		if self._min > self._max:
			self._min, self._max = self._max, self._min
		self._diff = abs(self._max - self._min)

		self._data = [_GraphData() for _ in range(len(self._ids))]
		self._data_view = [_GraphDataView(self._colors[i]) for i in range(
				len(self._ids))]
		self._graph_x = 0

		self._tk = Tk()
		self._tk.title("Graph view %s" % str(self._labels))

		self._canvas = Canvas(self._tk, width = 640, height = 480)
		self._canvas.pack(fill = tkinter.BOTH, expand = 1)

		self._tk.update()
		self._win_size = self._tk.winfo_width(), self._tk.winfo_height()
		# graph_rect only works as providing the area but not coord
		self._graph_rect = self._win_size
		self._tk.minsize(320, 240)
		self._tk.protocol("WM_DELETE_WINDOW", self.on_press_close)

		self._tk.bind("<Configure>", self.on_config)
		self._canvas.config(background = config.COL_GREY_900)

		self._full_redraw()

		self._file = open("graph_%s_%i.csv" % (str(self._labels),
				int(time.time() * 1000)), "w")
		self._file.write(','.join(self._labels) + '\n')

		self._tk.after(16, self._refresh)

	def run(self):
		super(GraphView, self).run()
		self._tk.mainloop()

	def on_new_input(self):
		try:
			hex_data = binascii.unhexlify(self.get_input())
		except TypeError as e:
			logging.debug(str(e))
			return

		count = int(len(hex_data) / GraphView._MSG_SIZE)
		for i in (x * 6 for x in range(count)):
			if hex_data[i] in self._ids:
				value_type = hex_data[i + 1]
				value_bytes = hex_data[i + 2:i + 6]
				if value_type == GraphView._MSG_TYPE_INT:
					value = int.from_bytes(value_bytes, byteorder = "big",
							signed = True)
				elif value_type == GraphView._MSG_TYPE_FLOAT:
					value = struct.unpack(">f", value_bytes)[0]
				else:
					logging.error("Unknown type: " + str(value_type))
					continue
				self._tk.after_idle(self._put_value, hex_data[i], value)

	def on_dismiss(self):
		self._tk.after_idle(self.on_press_close)

	def on_press_close(self):
		self._tk.destroy()
		self.join_io_thread()

	def on_config(self, event):
		win_size = (event.width, event.height)
		if win_size != self._win_size:
			self._win_size = win_size
			self._full_redraw()

	def is_test_input(self):
		return False

	def gen_test_input(self):
		while True:
			for i in range(int(self._min), int(self._max)):
				sleep(0.1)
				yield "0000%08x" % (random.randrange(-100, 100) & 0xFFFFFFFF) \
						+ "0100%08x\n" % (i & 0xFFFFFFFF)

	def _put_value(self, id, value):
		pos = self._ids.index(id)
		if self._data[pos].size() == 0:
			for d in self._data:
				d.append()
		elif self._data[pos].get_value(-1) is not None:
			for d in self._data:
				d.append()
			if self._data[pos].size() > 1:
				self._write_prev_records()
		self._data[pos].put_value(value)

		graph_w = self._win_size[0] - self._graph_x;
		count = int(graph_w / GraphView.POINT_MARGIN + 1)

		for d in self._data:
			d.shrink(count)

	def _write_prev_records(self):
		write = ','.join((str(d.get_value(-2)) for d in self._data)) + '\n'
		self._file.write(write)
		self._file.flush()

	def _refresh(self):
		self._redraw_graph()
		self._tk.after(16, self._refresh)

	def _full_redraw(self):
		self._canvas.delete("all")
		bounding_box = self._redraw_data_labels()
		self._graph_rect = 0, 0, self._win_size[0], bounding_box[1]
		self._redraw_y_labels()
		for v in self._data_view:
			v.clear_lines();
		self._redraw_graph()

	def _redraw_data_labels(self):
		top = self._win_size[1]
		x = GraphView._DATA_LABEL_PADDING
		for l, c in zip(self._labels, self._colors):
			t = self._canvas.create_text(x,
					self._win_size[1] - GraphView._DATA_LABEL_PADDING,
					anchor = tkinter.SW, fill = c, font = config.FONT,
					text = '-' + l)
			bounding_box = self._canvas.bbox(t)
			top = min(top, bounding_box[1])
			x = bounding_box[2] + GraphView._DATA_LABEL_PADDING
		return 0, top, x, self._win_size[1]

	def _redraw_y_labels(self):
		height = self._graph_rect[3] - self._graph_rect[1] \
				- GraphView.WIN_PADDING_Y * 2
		count = max(int(height / 50), 2)

		labels = []
		max_label_size = 0
		longest_label = None
		longest_label_i = None
		for i in range(count):
			ratio = i / (count - 1)
			value = self._max - self._diff * ratio
			value_label = ("%.2f" % value) if value % 1 != 0 else str(value)
			labels.append(value_label)
			if len(value_label) > max_label_size:
				max_label_size = len(value_label)
				longest_label = value_label
				longest_label_i = i

		label_id = self._canvas.create_text(0, height * (longest_label_i \
						/ (count - 1)) + GraphView.WIN_PADDING_Y,
				anchor = tkinter.W, fill = config.COL_GREY_100,
				font = config.FONT, text = longest_label)
		bounding_box = self._canvas.bbox(label_id)
		width = bounding_box[2] - bounding_box[0]
		self._graph_x = width + GraphView.POINT_MARGIN

		for i in range(count):
			ratio = i / (count - 1)
			y = height * ratio + GraphView.WIN_PADDING_Y
			if i != longest_label_i:
				self._canvas.create_text(width, y, anchor = tkinter.E,
						fill = config.COL_GREY_100, font = config.FONT,
						text = labels[i])
			self._canvas.create_line(self._graph_x, y, self._graph_rect[2], y,
					fill = config.COL_GREY_700)

	def _redraw_graph(self):
		graph_h = self._graph_rect[3] - GraphView.WIN_PADDING_Y * 2
		for d, v in zip(self._data, self._data_view):
			v.populate(d.get_values(), self._max, self._diff, self._graph_x,
					graph_h)
			v.draw(self._canvas)

	def _get_auto_colors(self, size) -> list:
		product = GraphView._COLOR_REPO[:min(size, len(GraphView._COLOR_REPO))]
		while len(product) < size:
			product.append("#%06x" % random.randrange(0xFFFFFF))
		return product

	_LABEL_SIZE = 10
	_DATA_LABEL_PADDING = 8
	_MSG_SIZE = 6
	_MSG_TYPE_INT = 0
	_MSG_TYPE_FLOAT = 1
	_COLOR_REPO = ["#F44336", "#4CAF50", "#2196F3", "#FFEB3B", "#607D8B",
			"#9C27B0", "#009688", "#673AB7", "#795548"]
Beispiel #35
0
class mainGUI(Frame, bootloader, GuiController):
    """ Contains the main view for the application """

    def __init__(self):
        """ Create the initial application GUI environment (tool bars, and other static elements) """
        Frame.__init__(self, self.root)
        self.thread_entry_field = ''  # Hold both search string, and drives autoRefresh logic

        self.menuBar = Menu()
        self.fileMenu = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="File", menu=self.fileMenu, underline=1)
        self.fileMenu.add_command(label="Quit", command=self.root.destroy, underline=1)

        self.optionsMenu = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="Options", menu=self.optionsMenu)
        self.optionsMenu.add_command(label="Settings", command=self.editSettings, underline=1)
        self.helpMenu = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="Help", menu=self.helpMenu)
        self.helpMenu.add_command(label="Help", command=self.program_help, underline=1)
        self.helpMenu.add_command(label="About", command=self.program_about, underline=1)
        self.master.config(menu=self.menuBar)

        self.topFrame = Frame()
        self.thread_entry_box = Entry(self.topFrame)
        self.thread_entry_box.insert(0, self.DEFAULT_THREAD_TEXT)
        self.thread_entry_box.bind('<Return>', lambda event: self.add_thread_GUI())
        # Bind needs to send the event to the handler
        self.thread_entry_box.pack(side='left', fill='x', expand='True', padx=5)

        self.add_thread_btn = Button(self.topFrame)
        self.add_thread_btn['text'] = 'Add New Thread'
        self.add_thread_btn['command'] = lambda: self.add_thread_GUI()
        self.add_thread_btn.pack(side='left', padx=0)

        self.topFrame.pack(fill='x')

        self.create_thread_frame()

    def create_thread_frame(self):
        """ Sets up the main thread frame (where the magic happens) """

        # Sets up frame
        self.thread_list_canvas = Canvas(self.root, borderwidth=0)
        self.thread_list_frame = Frame(self.thread_list_canvas)

        # Creates scroll bar
        self.vsb = Scrollbar(self.root, orient="vertical", command=self.thread_list_canvas.yview)
        self.thread_list_canvas.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")

        self.hsb = Scrollbar(self.root, orient="horizontal", command=self.thread_list_canvas.xview)
        self.thread_list_canvas.configure(xscrollcommand=self.hsb.set)
        self.hsb.pack(side="bottom", fill="x")

        # Packs frame
        self.thread_list_canvas.pack(side="left", fill="both", expand=True)
        self.thread_list_canvas.create_window((4, 4), window=self.thread_list_frame, anchor="nw", tags="self.frame")
        self.thread_list_frame.bind("<Configure>", self.OnFrameConfigure)

        self.create_thread_list_box()

    def OnFrameConfigure(self, event):
        """Reset the scroll region to encompass the inner frame"""
        self.thread_list_canvas.configure(scrollregion=self.thread_list_canvas.bbox("all"))

    # noinspection PyAttributeOutsideInit
    def create_thread_list_box(self):
        """ Creates the message list box for the create method """

        def hover_on(widget):
            widget['fg'] = 'dark blue'
            # widget['underline'] = True

        def hover_off(widget):
            widget['fg'] = 'black'
            # widget['underline'] = False

        for individual_thread in self.MESSAGE_THREADS:  # Fetch Message List from model

            if individual_thread.is_valid_thread():
                self.bg_color = 'green'
            else:
                self.bg_color = 'red'

            self.individual_thread_frame = Frame(self.thread_list_frame,
                                                 bg=self.bg_color)  # Create frame for each thread

            rowToInsertAt = self.MESSAGE_THREADS.index(individual_thread)

            self.text_color = 'black'
            self.threadText = Label(self.individual_thread_frame, bg=self.bg_color, fg=self.text_color)
            self.threadText['text'] = "[ Thread #:  " + individual_thread.threadId + " ]"

            self.threadText.bind("<Enter>", lambda event, text=self.threadText: hover_on(text))
            self.threadText.bind("<Leave>", lambda event, text=self.threadText: hover_off(text))

            self.threadText.bind("<Button-1>",
                                 lambda event, thread_in=individual_thread: self.open_in_web_browser(thread_in))
            self.threadText.grid(column=0, row=0, sticky='w', padx=0)

            self.image_count_text = Label(self.individual_thread_frame, bg=self.bg_color)
            num_of_images = individual_thread.get_number_of_images()
            if 0 < int(num_of_images) < 10:  # Format padding
                num_of_images = '00' + num_of_images
            if 10 < int(num_of_images) < 100:  # Format padding
                num_of_images = '0' + num_of_images

            self.image_count_text['text'] = "  [ # Images: " + num_of_images + " ]"
            self.image_count_text.bind("<Enter>", lambda event, text=self.image_count_text: hover_on(text))
            self.image_count_text.bind("<Leave>", lambda event, text=self.image_count_text: hover_off(text))

            self.image_count_text.bind("<Button-1>",
                                       lambda event, thread_in=individual_thread: self.open_in_file_browser(thread_in))

            self.image_count_text.grid(column=1, row=0, sticky='e', padx=0)

            self.deleteButton = Button(self.individual_thread_frame)
            self.deleteButton['text'] = 'Delete'
            self.deleteButton['command'] = lambda thread_in=individual_thread: self.delete_thread_GUI(thread_in)
            self.deleteButton.grid(column=2, row=0, sticky='e', padx=0)

            self.individual_thread_frame.grid(row=rowToInsertAt, sticky='w', pady=2)

    @staticmethod
    def open_in_file_browser(individual_thread):
        logging.debug(os.getcwd() + os.sep + individual_thread.threadId)
        if os.name == "nt":
            subprocess.Popen('explorer "' + os.getcwd() + os.sep + individual_thread.threadId + '"')

    @staticmethod
    def open_in_web_browser(individual_thread):
        webbrowser.open(
            url="http://boards.4chan.org/" + individual_thread.board + "/thread/" + individual_thread.threadId, new=2)

    def add_thread_GUI(self):
        entry_box_text = str(self.thread_entry_box.get())
        if entry_box_text not in self.MESSAGE_THREADS and entry_box_text != self.DEFAULT_THREAD_TEXT \
                and entry_box_text.isnumeric():
            try:
                self.add_thread(entry_box_text.strip(' '))
            except ThreadNotFound:
                messagebox.showwarning(message="Thread Not Found")
        else:
            messagebox.showwarning(message="Please enter a valid new thread ID")
        self.thread_entry_box.select_range(start=0, end=99)
        # Selects the contents so the user can just type the next message
        self.refresh_GUI()

    def delete_thread_GUI(self, thread_in):
        self.delete_thread(thread_in)
        self.refresh_GUI()

    def refresh_GUI(self):
        """ Refreshes the message list AND GUI window (used by auto refresh)"""
        self.refresh_thread_list()
        self.refresh_GUI_Window()

    def refresh_GUI_Window(self):
        """ Refreshes just the GUI window"""
        self.thread_list_canvas.destroy()
        self.vsb.destroy()
        self.hsb.destroy()
        self.create_thread_frame()

    @staticmethod
    def program_about():
        message = settings.__desc__ + '\n' + settings.__version__
        messagebox.showinfo(title='About', message=message)

    @staticmethod
    def program_help():
        message = 'See readme.md'
        messagebox.showinfo(title='About', message=message)
 def __createWindowOnId(self, itemId, content):
     if self.currentlyRenderedWindow != None:
         self.currentlyRenderedWindow()
     # self.__remove(self.currentlyRenderedWindow)
     idtuple = self.localCanvas.coords(itemId)
     if idtuple:
         x = idtuple[0]
         y = idtuple[1]
         frm = Frame(self.localCanvas)
         frm.grid(row=0, column=0)
         canv = Canvas(frm)            
         
         vscroll = Scrollbar(frm, orient="vertical", command=canv.yview)
         vscroll.grid(row=0, column=1, sticky=N + S)
         
         canv.grid(row=0, column=0)
         
         canv["yscrollcommand"] = vscroll.set
         aframe = Frame(canv)
         aframe.grid(row=0, column=0)
         Label(aframe, text=content, anchor="center", background="#CCFFCC", borderwidth=6, relief="ridge", justify="left").grid(row=1, column=0)
         canvWindow = canv.create_window(x, y, window=aframe)
         canv.coords(canvWindow, x, y)
         self.localCanvas.update_idletasks()
         canv["scrollregion"] = canv.bbox("all")
         
         def destroyAll():
             self.__remove(canvWindow)
             canv.destroy()
             aframe.destroy()
             vscroll.destroy()
             frm.destroy()
             
         self.currentlyRenderedWindow = destroyAll 
         Button(frm, text="Close", command=lambda :  destroyAll()).grid(row=2, column=0)
class TKinterDisplay(Display):
    '''
    classdocs
    '''
    
    
    '''
    Constructor
    '''
    def __init__(self, lineThickness=3, maxH=1920, maxW=1080):
        master = Tk()
        master.maxsize(maxH, maxW)
        self.localCanvas = Canvas(master, width=400, height=400)
        
        self.currentlyRenderedWindow = None
        self.lineThickness = lineThickness
        
        self.vsb = Scrollbar(master, orient="vertical", command=self.localCanvas.yview)
        self.hsb = Scrollbar(master, orient="horizontal", command=self.localCanvas.xview)
        
        self.localCanvas.configure(yscrollcommand=self.vsb.set)
        self.localCanvas.configure(xscrollcommand=self.hsb.set)
        
        master.bind("<Configure>", self.__eventOnFrameConfigure)
        self.hsb.pack(side="bottom", fill="x")
        self.vsb.pack(side="right", fill="y")
        self.localCanvas.pack()
        self.__sampleDraw()
        
        ''''''
    @abstractmethod    
    def drawSquare(self, xywhTuple, tags=None, colour=None, content=None):
        x2 = xywhTuple[0] + xywhTuple[2]
        y2 = xywhTuple[1] + xywhTuple[3]
        square = self.localCanvas.create_rectangle(xywhTuple[0], xywhTuple[1], x2, y2, width=self.lineThickness, tags=tags, fill=colour, activeoutline="white")
        def handler(event, self=self, content=content):
                return self.__eventOnClick(event, content)
        self.localCanvas.tag_bind(square, "<ButtonRelease-1>", handler)
        return square
    
    @abstractmethod
    def drawCircle(self, xywhTuple, tags=None , colour=None, content=None):
        x2 = xywhTuple[0] + xywhTuple[2]
        y2 = xywhTuple[1] + xywhTuple[3]
        circle = self.localCanvas.create_oval(xywhTuple[0], xywhTuple[1], x2, y2, width=self.lineThickness, tags=tags, fill=colour, activeoutline="white")
        
        def handler(event, self=self, content=content):
            return self.__eventOnClick(event, content)
        self.localCanvas.tag_bind(circle, "<ButtonRelease-1>", handler)
        return circle
    
    @abstractmethod
    def connectIdWithLine(self, id1, id2, tags=None, colour=None):
        
        # Gets the coordinates of id1 and then calulates centre point
        id1tuple = self.__getCoords(id1)
        x1 = id1tuple[0] + ((id1tuple[2] - id1tuple[0]) / 2)
        y1 = id1tuple[1] + ((id1tuple[3] - id1tuple[1]) / 2)
        
        # Gets the coordinates of id2 and then calulates centre point
        id2tuple = self.__getCoords(id2)
        x2 = id2tuple[0] + ((id2tuple[2] - id2tuple[0]) / 2)
        y2 = id2tuple[1] + ((id2tuple[3] - id2tuple[1]) / 2)
        
        # Calculates, using trig, the angle of the line at shape id1. This gives the radius of the ellipse
        opposite = y1 - y2
        adjacent = x1 - x2
        x1angle = 0
        x2angle = 0
        hyp = 0
        if adjacent != 0 and opposite != 0:
            hyp = math.sqrt(math.pow(opposite, 2) + math.pow(adjacent, 2))
            x1angle = math.tan(opposite / adjacent)
            x2angle = math.tan(adjacent / opposite)           
        else:
            
            if opposite == 0:
                hyp = adjacent
            else:
                hyp = opposite    
            x1angle = math.radians(90)
            x2angle = math.radians(270)
        
        a1 = (id1tuple[2] - id1tuple[0]) / 2
        b1 = (id1tuple[3] - id1tuple[1]) / 2
        
        a2 = (id2tuple[2] - id2tuple[0]) / 2
        b2 = (id2tuple[3] - id2tuple[1]) / 2
        
        r1 = a1 * b1 / (math.sqrt(((a1 * a1) * (math.pow(math.sin(x1angle), 2))) + ((b1 * b1) * math.pow(math.cos(x1angle), 2))))
        r2 = a2 * b2 / (math.sqrt(((a2 * a2) * (math.pow(math.sin(x2angle), 2))) + ((b2 * b2) * math.pow(math.cos(x2angle), 2))))
        
        x1 = x1 + ((r1 / hyp) * (x2 - x1))
        y1 = y1 + ((r1 / hyp) * (y2 - y1))
        
        #x2 = x2 + ((r2 / hyp) * (x1 - x2))
        #y2 = y2 - ((r2 / hyp) * (y1 - y2))
                    
        return self.__drawLine(x1, y1, x2, y2, tags, colour)
    
    @abstractmethod
    def renderTextInId(self, tagTocentreOn, tagsToAddTo, content, funcContent):
        id1tuple = self.__getCoords(tagTocentreOn)
        x1 = id1tuple[0] + ((id1tuple[2] - id1tuple[0]) / 2)
        y1 = id1tuple[1] + ((id1tuple[3] - id1tuple[1]) / 2)       
        txt = self.__renderText(x1, y1, (id1tuple[2] - id1tuple[0]), content, tagsToAddTo)
        
        def handler(event, self=self, content=funcContent):
            return self.__eventOnClick(event, content)
        
        self.localCanvas.tag_bind(txt, "<ButtonRelease-1>", handler)
        return txt
    
    @abstractmethod
    def move(self, tag, xamount, yamount):
        self.localCanvas.move(tag, xamount, yamount)

    @abstractmethod    
    def runDisplay(self):
        self.localCanvas.mainloop()
    
    
    def __hideId(self, objectId):
        self.localCanvas.itemconfigure(objectId, state="hidden")
        pass
        
    def __showId(self, objectId):
        self.localCanvas.itemconfigure(objectId, state="normal")
        pass
    
    def __sampleDraw(self):
        self.localCanvas.create_oval(0, 0, 0, 0, width=0)
    
    def __renderText(self, x, y, width, content, tag):
        val = self.localCanvas.create_text(x, y, width=width, text=content, tags=tag, justify="center", font="Helvetica 8 bold", anchor="center")
        self.localCanvas.tag_raise(val)
        return val
    
    def __drawLine(self, x1, y1, x2, y2, tags=None, colour="black"):
        line = self.localCanvas.create_line(x1, y1, x2, y2, tags=tags, width=self.lineThickness, arrow="first", arrowshape=(16,20,6),fill=colour, smooth=True)
        self.localCanvas.tag_lower(line)
        return  # line
    
    def __remove(self, num):
        self.localCanvas.delete(num)
    
    def __getCoords(self, ident):
        return self.localCanvas.coords(ident)
    
    def __eventOnFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        assert self.localCanvas
        coord_tuple = self.localCanvas.bbox("all")
        if not coord_tuple:
            logging.error("Frame reconfigure error on coordinate acquire.")
        else:
            reconWidth = coord_tuple[2] - coord_tuple[0]
            reconHeight = coord_tuple[3] - coord_tuple[1]
            self.localCanvas.configure(width=reconWidth)
            self.localCanvas.configure(height=reconHeight)
            self.localCanvas.configure(scrollregion=self.localCanvas.bbox("all"))
            self.localCanvas.update_idletasks()
    
    def __eventOnClick(self, event, content):
        self.__createWindowOnId(self.localCanvas.find_withtag(CURRENT), content)
        
    def __createWindowOnId(self, itemId, content):
        if self.currentlyRenderedWindow != None:
            self.currentlyRenderedWindow()
        # self.__remove(self.currentlyRenderedWindow)
        idtuple = self.localCanvas.coords(itemId)
        if idtuple:
            x = idtuple[0]
            y = idtuple[1]
            frm = Frame(self.localCanvas)
            frm.grid(row=0, column=0)
            canv = Canvas(frm)            
            
            vscroll = Scrollbar(frm, orient="vertical", command=canv.yview)
            vscroll.grid(row=0, column=1, sticky=N + S)
            
            canv.grid(row=0, column=0)
            
            canv["yscrollcommand"] = vscroll.set
            aframe = Frame(canv)
            aframe.grid(row=0, column=0)
            Label(aframe, text=content, anchor="center", background="#CCFFCC", borderwidth=6, relief="ridge", justify="left").grid(row=1, column=0)
            canvWindow = canv.create_window(x, y, window=aframe)
            canv.coords(canvWindow, x, y)
            self.localCanvas.update_idletasks()
            canv["scrollregion"] = canv.bbox("all")
            
            def destroyAll():
                self.__remove(canvWindow)
                canv.destroy()
                aframe.destroy()
                vscroll.destroy()
                frm.destroy()
                
            self.currentlyRenderedWindow = destroyAll 
            Button(frm, text="Close", command=lambda :  destroyAll()).grid(row=2, column=0)