class Example(Frame): def __init__(self): super().__init__() self.initUI() def initUI(self): self.master.title("Scale") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=True) self.scale = Scale(self, from_=0, to=100, command=self.onScale) self.scale.grid(row=0, column=0, padx=10, pady=10, sticky=E + W) self.var = IntVar() self.label = Label(self, text=0, textvariable=self.var) self.label.grid(row=0, column=1, sticky=W, padx=10) self.grid_columnconfigure(0, weight=1) def onScale(self, val): v = int(float(val)) self.var.set(v)
class Example(Frame): def __init__(self): super().__init__() self.initUI() def initUI(self): self.master.title("Scale") self.style = Style() self.style.theme_use("default") self.frame = Frame(height=10, width=100, relief=SUNKEN) self.frame.pack(fill=X, expand=1) self.frame.grid_columnconfigure(0, weight=1) self.scale = Scale(self.frame, from_=0, to=100, command=self.onScale) self.scale.grid(row=0, column=0, columnspan=2, padx=10, pady=10, sticky=E + W) #scale.pack(fill=X, padx=15, expand=1) #scale.pack(fill=X, padx=15) self.var = IntVar() self.label = Label(self.frame, text=0, textvariable=self.var) self.label.grid(row=0, column=2, sticky=W, padx=10) # self.label.pack(side=LEFT) def onScale(self, val): v = int(float(val)) self.var.set(v)
def __build_fog_slider(self): """ Builds a slider that allows the user to adjust light intensity on the scene """ can = self.canvas self.add_title('Fog Scalar',6) def adjust(event=None): d = 1 s = int(fog_meter.get()) can.config('lighting').set_fog_scale(s) if s > 0 and s != 70: textvar.set("Fog Magnitude: "+str(s)) elif s == 70: textvar.set("Fog Magnitude: :)") else: textvar.set("Fog Magnitude: OFF") can.update_idletasks() fog_meter = Scale( self, to = 120, from_ = 0, length = 200 ) fog_meter.grid(row=7,column=0) textvar = tk.StringVar() textvar.set("Darkness: 0") tk.Label(self,textvariable=textvar).grid(row=7,column=1) fog_meter.set(0) fog_meter.configure(command=adjust)
class paint: def __init__(self,root): self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.configure(background = 'white') self.root.resizable(0,0) self.pen_color="black" self.eraser_color = "white" #adding widgets to tkinter window self.color_frame = LabelFrame(self.root,text="Color",font=('arial',15),bd=4,relief=RIDGE,bg="white") self.color_frame.place(x = 0,y = 0, width =98, height = 195) colors = ['#ff0000', '#00ff00', '#0000ff' , '#ffff00', '#00ffff', '#ff00ff','#ffffff', '#000000', '#99ffcc', '#ff99cc'] i = j = 0 for color in colors: Button(self.color_frame,bg = color,bd =2, relief=RIDGE,width=2,command = lambda col=color:self.select_color(col)).grid(row = i, column = j) i += 1 if i==5: i = 0 j+=1 self.eraser_button = Button(self.root, text = "Eraser",bd = 4,bg="white",command = self.eraser,width = 8,relief=RIDGE) self.eraser_button.place(x = 0,y = 207) self.clear_button = Button(self.root, text = "Clear",bd = 4,bg="white",command = lambda:self.canvas.delete("all"),width = 8,relief=RIDGE) self.clear_button.place(x = 0,y = 247) self.canvas_color = Button(self.root, text = "Canvas",bd = 4,bg="white",command = self.canvas,width = 8,relief=RIDGE) self.canvas_color.place(x = 0,y = 287) #creating a scale for pen and eraser size.. self.pen_size_scale_frame = LabelFrame(self.root, text="Size", bd=5,bg='white',font=('arial', 15,'bold'),relief=RIDGE) self.pen_size = Scale(self.pen_size_scale_frame,orient=VERTICAL,from_=50,to=0,length=170) self.pen_size.set(1) self.pen_size.grid(row=0,column=1,padx=15) #creating canvas self.canvas = Canvas(self.root,bg='white',bd=5,relief=GROOVE, height=488,width=680) self.canvas.place(x=105,y=7) self.pen_size_scale_frame.place(x=0,y=325,height=190,width=98) #bind canvas with mouse drag self.canvas.bind("<B1-Motion>",self.paint) #function creation def paint(self,event): x1,y1 = (event.x-2),(event.y-2) x2,y2 = (event.x+2),(event.y+2) self.canvas.create_oval(x1,y1,x2,y2,fill=self.pen_color,outline=self.pen_color,width=self.pen_size.get()) def select_color(self,col): self.pen_color =col def eraser(self): self.pen_color = self.eraser_color def canvas(self): color = colorchooser.askcolor() self.canvas.configure(background = color[1]) self.eraser_color = color[1]
def __build_lightness_slider(self): """ Builds a slider that allows the user to adjust light intensity on the scene """ can = self.canvas self.add_title('Light Brightness',4) def adjust(event=None): d = 1 s = int(light_meter.get()) pos = can.config('lighting').get_lighting_parameters()[2][0] can.config('lighting').clear() can.create_light([s,s,s,s],Lighting.Point,position=pos,sharpness=4) can.create_light([s,s,s,s],Lighting.Ambient) textvar.set("Brightness: "+str(s)) can.update_idletasks() light_meter = Scale( self, to = 255, from_ = 1, length = 200 ) light_meter.grid(row=5,column=0) textvar = tk.StringVar() textvar.set("Brightness: 178") tk.Label(self,textvariable=textvar).grid(row=5,column=1) light_meter.set(178) light_meter.configure(command=adjust)
class SliderFrequency(Frame): def __init__(self,root, freq, val, Min=0.0, Max=1.0, sId=0): Frame.__init__(self,root) self.root = root self.id = sId self.freq = freq self.min = Min self.max = Max self.gain = StringVar() self.gain.set(val) self.value = StringVar() self.value.set( str(self._Gain(val))+" dB") self.initialize() self.gain.set(self._Gain(val)) def initialize(self): self.slider = Scale(self.root, orient=VERTICAL, from_=self.min, to=self.max, value=float(self.gain.get()), command=self._updateValue) self.slider.grid(row=0,column=self.id, padx=10) self.valueLbl = Label(self.root, anchor="w", textvariable=self.value) self.valueLbl.grid(row=1,column=self.id, padx=10) self.freqLbl = Label(self.root,text=str(self.freq)+" Hz") self.freqLbl.grid(row=2,column=self.id, padx=10) def _updateValue(self,event): self.gain.set(self._Gain(self.slider.get())) self.value.set(str(self.gain.get())+" dB") self.valueLbl.update() def _Gain(self, value): v = -(float(value)-((self.max-self.min)/2)) v = int(v*10)/10 return v def getGain(self): return float(self.gain.get())
class ConfidenceScale(Frame): def __init__(self, master, **kw): super().__init__(master) # self.grid_propagate(0) # self.columnconfigure(0, weight=1) # self.rowconfigure(0, weight=1) self.var = kw.get('variable', IntVar()) kw['variable'] = self.var kw['from_'] = ConfidenceLevel.Low.value kw['to'] = ConfidenceLevel.VeryHigh.value # kw['command'] = self.scale_change kw['orient'] = HORIZONTAL self.lbl_scale = Label(self) self.scale = Scale(self, **kw) self.scale_font = tkfont.nametofont(Style().lookup('TLabel', 'font')).copy() self.scale_font.config(weight=tkfont.BOLD, size=9) self.lbl_scale.config(font=self.scale_font, width=3, anchor=CENTER) self.var.trace_variable('w', lambda a, b, c: self.scale_change()) self.scale.grid(row=0, column=0, sticky='ns') self.lbl_scale.grid(row=0, column=1, sticky='ns', padx=(3, 0)) def scale_change(self): rval = self.get() if rval >= ConfidenceLevel.High: fg = '#4CAF50' elif rval >= ConfidenceLevel.Medium: fg = '#FF9800' else: fg = '#FF5722' self.lbl_scale.config(foreground=fg, text=str(rval)) def get(self): return round(float(self.var.get()))
class SliderFrequency(Frame): """ A slider with label wich indicate the gain in dB and Frequency in Hz parameters: root: Canvas the canvas to place the slider freq: float the frequency in Hz val: float initial value of the slider Min: float the min value of the slider Max: float the maximum of value of the slider sId: int the ID of the slider """ def __init__(self,root, freq, val, Min=0.0, Max=1.0, sId=0): Frame.__init__(self,root) self.root = root self.id = sId self.freq = freq self.min = Min self.max = Max self.gain = StringVar() self.gain.set(self._Gain(val)) self.value = StringVar() self.value.set( str(val)+" dB") self.initialize() self.gain.set(self._Gain(val)) def initialize(self): """ Initialize the slider and the label""" self.slider = Scale(self.root, orient=VERTICAL, from_=self.min, to=self.max, value=float(self.gain.get()), command=self._updateValue) self.slider.grid(row=0,column=self.id, padx=14) self.valueLbl = Label(self.root, anchor="w", textvariable=self.value) self.valueLbl.grid(row=1,column=self.id, padx=14) self.freqLbl = Label(self.root,text=str(self.freq)+" Hz") self.freqLbl.grid(row=2,column=self.id, padx=14) def _updateValue(self,event): """ update the gain value and label when the slider is changing """ self.gain.set(self.slider.get()) self.value.set(str(self._Gain(self.gain.get()))+" dB") self.valueLbl.update() def _Gain(self, value): """ Transform the value of the slider to correct gain value """ v = (((self.max-self.min))-float(value)) v = int(v*10)/10.0 return v def getGain(self): """ Return the gain """ return float(self._Gain(self.gain.get())) def getFrequency(self): """ Return the frequency """ return self.freq
class Paint(): def __init__(self, root): self.root = root self.root.title("MyPaint") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0, 0) self.pen_color = "black" self.eraser_color = "white" self.color_frame = LabelFrame(self.root, text="Color", font=( "arial,15"), bd=5, relief=RIDGE, bg="white") self.color_frame.place(x=0, y=0, width=76, height=185) # self.canvas_shapes_frame = LabelFrame(self.root, text="Shapes", font=( # "arial", 15), bd=5, relief=RIDGE, bg="white") # self.canvas_shapes_frame.place(x=0, y=105, width=76, height=80) colors = ["#000000", "#FFFFFF", "#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#00FFFF", "#FF00FF", "#FFFACD", "#F5DEB3", "#C0C0C0", "#DEB887"] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=1, height=2, command=lambda col=color: self.select_color(col)).grid(row=i, column=j) i += 1 if i == 3 or i == 6: i = 0 j += 1 self.color_other_button = Button( self.color_frame, text="Others", bd=4, bg="white", command=self.color_other, width=8, relief=RIDGE) self.color_other_button.place(x=0, y=130, width=68) self.eraser_button = Button( self.root, text="Eraser", bd=4, bg="white", command=self.eraser, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=187, width=76) self.clear_button = Button( self.root, text="Clear", bd=4, bg="white", command=lambda: self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=217, width=76) self.save_button = Button( self.root, text="Save", bd=4, bg="white", command=self.save_image, width=8, relief=RIDGE) self.save_button.place(x=0, y=247, width=76) self.canvas_color_button = Button( self.root, text="Canvas", bd=4, bg="white", command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=277, width=76) # creating a scale for pen and eraser self.pen_size_scale_frame = LabelFrame( self.root, text="Size", bd=5, bg="white", font=("arial", 15, "bold"), relief=RIDGE) self.pen_size_scale_frame.place(x=0, y=310, height=200, width=76) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length=170) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) # creating the canvas self.canvas = Canvas(self.root, bg="white", bd=5, relief=GROOVE, height=500, width=680) self.canvas.place(x=100, y=0) # binding the canvas self.canvas.bind("<B1-Motion>", self.paint) def paint(self, event): x1, y1 = (event.x-2), (event.y-2) x2, y2 = (event.x+2), (event.y+2) self.canvas.create_oval( x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): self.pen_color = col def eraser(self): self.pen_color = self.eraser_color def color_other(self): color = colorchooser.askcolor() self.pen_color = color[1] def canvas_color(self): color = colorchooser.askcolor() self.canvas.configure(background=color[1]) self.eraser_color = color[1] def save_image(self): try: filename = filedialog.asksaveasfilename(defaultextension=".jpg") x = self.root.winfo_rootx()+self.canvas.winfo_x() y = self.root.winfo_rooty()+self.canvas.winfo_y() x1 = x + self.canvas.winfo_width() y1 = y + self.canvas.winfo_height() ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo( "MyPaint says", "Image is saved as" + str(filename)) except: messagebox.showerror("MyPaint says", "Unable to save image")
class Timeline(Frame): def __init__(self, w, *args, **kwargs): super().__init__(w, *args, **kwargs) #___ self.state_txt_time1 = StringVar() self.state_txt_time1.set(INIT_TIME) self.txt_time1 = Label(self, textvariable=self.state_txt_time1, background=config.colors["BG"], font=font.nametofont("font_small_size")) self.txt_time1.grid(row=0, column=0, sticky="sw") #___ self.state_txt_song = StringVar() self.state_txt_song.set(INIT_SONG) self.txt_song = Label(self, textvariable=self.state_txt_song, background=config.colors["BG"]) self.txt_song.grid(row=0, column=1, pady=(0,2)) #___ self.state_txt_time2 = StringVar() self.state_txt_time2.set(INIT_TIME) self.txt_time1 = Label(self, textvariable=self.state_txt_time2, background=config.colors["BG"], font=font.nametofont("font_small_size")) self.txt_time1.grid(row=0, column=2, sticky="se") #___ self.state_scale_time = DoubleVar() self.scale_time = Scale(self, orient="horizontal", length=300, from_=0, to_=100, value=0, variable=self.state_scale_time) self.scale_time.grid(row=1, column=0, columnspan=3) #___ #Set time when direct click on the timeline self.scale_time.bind("<Button-1>", self._setTimeDirect) #___ self.song_playing = None #__________________________________________________ def _setTimeDirect(self, event): self.scale_time.event_generate("<Button-3>", x=event.x, y=event.y) return "break" #Avoid recoil when holding #___ def setNewSong(self, song:Song): self.song_playing = song self.state_scale_time.set(0) self.state_txt_time1.set(INIT_TIME) self.state_txt_time2.set(song.getTimeFormat()) self.state_txt_song.set(song.name if len(song.name) < MAX_LEN_VISIBLE else song.name[:MAX_LEN_VISIBLE]+"...") #Avoid long names #___ ''' Scale time to Song time scale.time -> 100 | x -> song.time | => x = time*100/song.time ''' def getTime(self, song:Song=None) -> int: song = self.song_playing if song is None else song return round((self.state_scale_time.get() * song.time) / 100) ''' #Song time to Scale time #time -> song.time | x -> 100 | => x = time*100/song.time ''' def setTime(self, time:int): self.state_scale_time.set((time * 100) / self.song_playing.time) self.state_txt_time1.set(Song.timeFormat(time))
class Paint(object): def __init__(self, root): self.root = root self.root.title("Paint") self.width_value = self.root.winfo_screenwidth() self.height_value = self.root.winfo_screenheight() self.root.geometry("900x700") self.root.configure(background='white') #self.root.resizable(0, 0) self.pen_color = "black" self.eraser_color = "white" self.save_color = "black" self.old_x = None self.old_y = None self.stack = [] self.line_stack = [] self.item = None self.choice = " Pencil" self.add_widgets() def add_widgets(self): #self.controls.grid(row = 0, column = 0, sticky=NE) self.color_frame = Frame(self.root, bd=1, relief=RIDGE, bg="white") #self.color_frame.place(x = 0, y = 0, width = 185, height = 70) self.color_frame.grid(sticky=NW, row=0, column=0, padx=15, pady=10) self.color_frame.config(cursor="hand2") #self.color_frame.pack() self.palette_image = PhotoImage(file='paint.png') self.palette_button = Button(self.root, image=self.palette_image, command=self.select_palette_color) #self.canvas_button.place(x = 247, y = 0) self.palette_button.grid(sticky="W", row=0, column=1, padx=10, pady=10) self.palette_button.config(cursor="hand2") self.palette_tooltip = CreateToolTip( self.palette_button, 'Select a color from the color palette') colors = [ 'black', 'white', '#4d4d4d', 'grey', '#990033', '#993300', 'red', 'pink', 'orange', '#ffcc99', 'yellow', '#ffff99', 'lime', '#d9ffb3', 'green', '#88cc00', '#0099ff', 'turquoise', '#3333ff', '#6699cc', 'purple', '#bfbff2' ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, height=1, width=3, command=lambda col=color: self.select_color(col)).grid( row=i, column=j) i += 1 if i == 2: i = 0 j += 1 self.pencil_image = PhotoImage(file='pencil.png') self.pencil_button = Button(self.root, image=self.pencil_image, command=self.pencil) #self.pencil.place(x = 0, y = 187) self.pencil_button.grid(sticky="W", row=1, column=0, padx=16) self.pencil_button.config(cursor="hand2") self.pencil_tooltip = CreateToolTip(self.pencil_button, 'Pencil') self.bg_image = PhotoImage(file='bg.png') self.bg_button = Button(self.root, image=self.bg_image, command=self.bg_color) self.bg_button.grid(sticky="W", row=2, column=0, padx=16) self.bg_button.config(cursor="hand2") self.bg_tooltip = CreateToolTip(self.bg_button, 'Change background color') self.eraser_image = PhotoImage(file='eraser.png') self.eraser_button = Button(self.root, image=self.eraser_image, command=self.eraser) #self.eraser.place(x = 0, y = 187) self.eraser_button.grid(sticky="W", row=3, column=0, padx=16) self.eraser_button.config(cursor="hand2") self.eraser_tooltip = CreateToolTip(self.eraser_button, 'Eraser') self.clear_image = PhotoImage(file='clear.png') self.clear_button = Button(self.root, image=self.clear_image, command=self.clear) #self.clear.place(x = 0, y = 217) self.clear_button.grid(sticky="W", row=4, column=0, padx=16) self.clear_button.config(cursor="hand2") self.clear_tooltip = CreateToolTip(self.clear_button, 'Clear the canvas area') self.line_image = PhotoImage(file='line.png') self.line_button = Button(self.root, image=self.line_image, command=self.line) #self.line.place(x = 0, y = 367) self.line_button.grid(sticky="W", row=5, column=0, padx=16) self.line_button.config(cursor="hand2") self.line_tooltip = CreateToolTip(self.line_button, 'Draw a line') self.arrow_image = PhotoImage(file='arrow.png') self.arrow_button = Button(self.root, image=self.arrow_image, command=self.arrow) #self.line.place(x = 0, y = 367) self.arrow_button.grid(sticky="W", row=6, column=0, padx=16) self.arrow_button.config(cursor="hand2") self.arrow_tooltip = CreateToolTip(self.arrow_button, 'Draw an arrow') self.rectangle_image = PhotoImage(file='rectangle.png') self.rectangle_button = Button(self.root, image=self.rectangle_image, command=self.rectangle) #self.rectangle.place(x = 0, y = 307) self.rectangle_button.grid(sticky="W", row=7, column=0, padx=16) self.rectangle_button.config(cursor="hand2") self.rectangle_tooltip = CreateToolTip(self.rectangle_button, 'Draw a rectangle') self.oval_image = PhotoImage(file='oval.png') self.oval_button = Button(self.root, image=self.oval_image, command=self.oval) #self.oval.place(x = 0, y = 397) self.oval_button.grid(sticky="W", row=8, column=0, padx=16) self.oval_button.config(cursor="hand2") self.oval_tooltip = CreateToolTip(self.oval_button, 'Draw an oval/a circle') self.undo_image = PhotoImage(file='undo.png') self.undo_button = Button(self.root, image=self.undo_image, command=self.undo) #self.oval.place(x = 0, y = 397) self.undo_button.grid(sticky="W", row=9, column=0, padx=16) self.undo_button.config(cursor="hand2") self.undo_tooltip = CreateToolTip(self.undo_button, 'Undo') # creating a scale for pen and eraser size self.slider = Frame(self.root, bd=3, bg="white", relief=RIDGE) #self.slider.place(x = 0, y = 400) self.slider.grid(sticky="W", row=10, column=0, padx=16, pady=20) self.pen_size = Scale(self.slider, orient=VERTICAL, from_=50, to=0, length=170) self.pen_size.set(1) self.pen_size.grid(sticky="W", row=10, column=0, ipadx=2, padx=7, pady=7) self.slider.config(cursor="hand2") self.slider_tooltip = CreateToolTip(self.slider, 'Size') # creating canvas self.canvas = Canvas(self.root, relief=GROOVE, height=self.height_value, width=self.width_value, bg="white") self.canvas.place(x=70, y=75) # self.canvas.grid(row = 0, column = 1) # bind the canvas with mouse drag self.canvas.bind('<B1-Motion>', self.paint) self.canvas.bind('<ButtonRelease-1>', self.reset) self.msg = Message(self.root, text=self.choice, width=70, bg="white") self.msg.grid(sticky="W", row=11, column=0) menu = Menu(self.root) self.root.config(menu=menu) filemenu = Menu(menu) colormenu = Menu(menu) menu.add_cascade(label='File', menu=filemenu) filemenu.add_command(label='Save File', command=self.save_file) optionmenu = Menu(menu) menu.add_cascade(label='Options', menu=optionmenu) optionmenu.add_command(label='Exit', command=self.root.destroy) # functions def change_label(self): self.msg.config(text=self.choice) def paint(self, event): if self.old_x and self.old_y: self.line_stack.append( self.canvas.create_line(self.old_x, self.old_y, event.x, event.y, width=self.pen_size.get(), fill=self.pen_color, capstyle=ROUND, smooth=True)) self.oldx = self.old_x self.oldy = self.old_y self.old_x = event.x self.old_y = event.y self.newx = event.x self.newy = event.y def reset(self, event): # reset x and y # self.line_stack.append(self.canvas.create_line(self.oldx, self.oldy, self.newx, self.newy, arrow = 'last', width = self.pen_size.get(), fill = self.pen_color, capstyle=ROUND, smooth=True)) self.old_x = None self.old_y = None self.line_stack.append('#') # print(self.line_stack) def select_color(self, col): self.pen_color = col self.save_color = col def eraser(self): self.pen_color = self.eraser_color self.canvas.bind('<B1-Motion>', self.paint) self.canvas.bind('<ButtonRelease-1>', self.reset) self.canvas.config(cursor="dot") self.choice = " Eraser" self.change_label() def select_palette_color(self): self.choice = " Palette" self.change_label() color = colorchooser.askcolor() self.pen_color = color[1] self.save_color = color[1] #self.canvas.configure(background = color[1]) #self.eraser_color = color[1] def bg_color(self): self.canvas.configure(background=self.pen_color) self.eraser_color = self.pen_color self.choice = " Canvas\n Color" self.change_label() def clear(self): self.canvas.configure(background="white") self.canvas.delete("all") def undo(self): try: if self.line_stack[-1] == '$': self.item = self.stack.pop() self.line_stack.pop() else: if self.line_stack[-1] == '#': self.item = self.line_stack.pop() while (1): if len(self.line_stack) == 0: break elif len(self.stack) != 0 or len(self.line_stack) != 0: # print(self.line_stack) if self.line_stack[-1] != '#' and self.line_stack[ -1] != '$': self.item = self.line_stack.pop() self.canvas.delete(self.item) else: break else: break self.canvas.delete(self.item) except LookupError: print("LookupError: list index out of range") self.choice = " Undo" self.change_label() def pencil(self): self.pen_color = self.save_color self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<B1-Motion>", self.paint) self.canvas.bind("<ButtonRelease-1>", self.reset) self.canvas.config(cursor="pencil") self.choice = " Pencil" self.change_label() def rectangle(self): self.rectx0 = 0 self.recty0 = 0 self.rectx1 = 0 self.recty1 = 0 self.rectid = None self.pen_color = self.save_color self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startRect) self.canvas.bind("<ButtonRelease-1>", self.stopRect) self.canvas.bind("<B1-Motion>", self.movingRect) self.canvas.config(cursor="crosshair") self.choice = " Rectangle" self.change_label() def startRect(self, event): self.rectx0 = self.canvas.canvasx(event.x) self.recty0 = self.canvas.canvasy(event.y) self.rectid = self.canvas.create_rectangle(self.rectx0, self.recty0, self.rectx0, self.recty0, outline=self.pen_color, width=self.pen_size.get()) def movingRect(self, event): self.rectx1 = self.canvas.canvasx(event.x) self.recty1 = self.canvas.canvasy(event.y) self.canvas.coords(self.rectid, self.rectx0, self.recty0, self.rectx1, self.recty1) def stopRect(self, event): self.rectx1 = self.canvas.canvasx(event.x) self.recty1 = self.canvas.canvasy(event.y) self.canvas.coords(self.rectid, self.rectx0, self.recty0, self.rectx1, self.recty1) self.stack.append(self.rectid) self.line_stack.append('$') def line(self): self.linex0 = 0 self.liney0 = 0 self.linex1 = 0 self.liney1 = 0 self.lineid = None self.pen_color = self.save_color self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startLine) self.canvas.bind("<ButtonRelease-1>", self.stopLine) self.canvas.bind("<B1-Motion>", self.movingLine) self.canvas.config(cursor="crosshair") self.choice = " Line" self.change_label() def startLine(self, event): self.linex0 = self.canvas.canvasx(event.x) self.liney0 = self.canvas.canvasy(event.y) self.lineid = self.canvas.create_line(self.linex0, self.liney0, self.linex0, self.liney0, fill=self.pen_color, width=self.pen_size.get()) def movingLine(self, event): self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) def stopLine(self, event): self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) self.stack.append(self.lineid) self.line_stack.append('$') def arrow(self): self.arrowx0 = 0 self.arrowy0 = 0 self.arrowx1 = 0 self.arrowy1 = 0 self.arrowid = None self.pen_color = self.save_color self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startArrow) self.canvas.bind("<ButtonRelease-1>", self.stopArrow) self.canvas.bind("<B1-Motion>", self.movingArrow) self.canvas.config(cursor="crosshair") self.choice = " Arrow" self.change_label() def startArrow(self, event): self.arrowx0 = self.canvas.canvasx(event.x) self.arrowy0 = self.canvas.canvasy(event.y) self.arrowid = self.canvas.create_line(self.arrowx0, self.arrowy0, self.arrowx0, self.arrowy0, arrow='last', fill=self.pen_color, width=self.pen_size.get()) def movingArrow(self, event): self.arrowx1 = self.canvas.canvasx(event.x) self.arrowy1 = self.canvas.canvasy(event.y) self.canvas.coords(self.arrowid, self.arrowx0, self.arrowy0, self.arrowx1, self.arrowy1) def stopArrow(self, event): self.arrowx1 = self.canvas.canvasx(event.x) self.arrowy1 = self.canvas.canvasy(event.y) self.canvas.coords(self.arrowid, self.arrowx0, self.arrowy0, self.arrowx1, self.arrowy1) self.stack.append(self.arrowid) self.line_stack.append('$') def oval(self): self.ovalx0 = 0 self.ovaly0 = 0 self.ovalx1 = 0 self.ovaly1 = 0 self.ovalid = None self.pen_color = self.save_color self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startOval) self.canvas.bind("<ButtonRelease-1>", self.stopOval) self.canvas.bind("<B1-Motion>", self.movingOval) self.canvas.config(cursor="crosshair") self.choice = " Oval" self.change_label() def startOval(self, event): self.ovalx0 = self.canvas.canvasx(event.x) self.ovaly0 = self.canvas.canvasy(event.y) self.ovalid = self.canvas.create_oval(self.ovalx0, self.ovaly0, self.ovalx0, self.ovaly0, outline=self.pen_color, width=self.pen_size.get()) def movingOval(self, event): self.ovalx1 = self.canvas.canvasx(event.x) self.ovaly1 = self.canvas.canvasy(event.y) self.canvas.coords(self.ovalid, self.ovalx0, self.ovaly0, self.ovalx1, self.ovaly1) def stopOval(self, event): self.ovalx1 = self.canvas.canvasx(event.x) self.ovaly1 = self.canvas.canvasy(event.y) self.canvas.coords(self.ovalid, self.ovalx0, self.ovaly0, self.ovalx1, self.ovaly1) self.stack.append(self.ovalid) self.line_stack.append('$') def save_file(self): try: filename = filedialog.asksaveasfilename(defaultextension='.png') '''x = self.root.winfo_rootx() + self.canvas.winfo_x() y = self.root.winfo_rooty() + self.canvas.winfo_y() x1 = x + self.canvas.winfo_width() y1 = y + self.canvas.winfo_height()''' ImageGrab.grab().save(filename) messagebox.showinfo('Paint', 'Image is saved as ' + str(filename)) except: messagebox.showerror('Paint', 'Unable to save image!')
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0, 0) self.pen_color = "#000000" self.color_frame = LabelFrame(self.root, text="Color", font=('arial', 15, 'bold'), bd=5, relief=RIDGE, bg='white') self.color_frame.place(x=0, y=0, width=70, height=185) Colors = [ '#ff0000', '#ff4dd2', '#ffff33', '#000000', '#0066ff', '#660033', '#4dff4d', '#b300b3', '#00ffff', '#808080', '#99ffcc', '#336600', '#ff9966', '#ff99ff', '#00cc99', ] i = j = 0 for color in Colors: Button(self.color_frame, bg=color, command=lambda col=color: self.select_color(col), width=3, bd=2, relief=RIDGE).grid(row=i, column=j) i += 1 if i == 6: i = 0 j = 1 self.erase_button = Button(self.root, text="Eraser", bd=4, relief=RIDGE, width=8, command=self.eraser, bg="white") self.erase_button.place(x=0, y=187) self.clear_sreen_button = Button( self.root, text="Clear", bd=4, relief=RIDGE, width=8, command=lambda: self.canvas.delete("all"), bg="white") self.clear_sreen_button.place(x=0, y=217) self.save_button = Button(self.root, text="Save", bd=4, relief=RIDGE, width=8, command=self.save_paint, bg="white") self.save_button.place(x=0, y=247) self.canvas_color_button = Button(self.root, text="Canvas", bd=4, relief=RIDGE, width=8, command=self.canvas_color, bg="white") self.canvas_color_button.place(x=0, y=277) self.pen_size_scale_frame = LabelFrame(self.root, text="Size", bd=5, relief=RIDGE, bg="white", font=('arial', 15, 'bold')) self.pen_size_scale_frame.place(x=0, y=310, height=200, width=70) self.pen_size = Scale(self.pen_size_scale_frame, orient='vertical', from_=50, to=0, command=None, length=170) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) self.canvas = Canvas(self.root, bg='white', bd=5, relief='groove', height=500, width=700) self.canvas.place(x=80, y=0) # Blind mouse dragging event to canvas self.canvas.bind("<B1-Motion>", self.paint) def paint(self, event): global pen_color x1, y1 = (event.x - 2), (event.y - 2) x2, y2 = (event.x + 2), (event.y + 2) if (i): self.canvas.config(cursor='plus') self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): global i i = 1 self.pen_color = col def eraser(self): global color global i self.pen_color = color self.canvas.config(cursor='dot') i = 0 def canvas_color(self): global color color = colorchooser.askcolor() color = color[1] self.canvas.config(background=color) def save_paint(self): try: self.canvas.update() filename = asksaveasfilename(defaultextension='.jpg') print(filename) x = self.root.winfo_rootx() + self.canvas.winfo_x() #print(x) y = self.root.winfo_rooty() + self.canvas.winfo_y() #print(y) x1 = x + self.canvas.winfo_width() #print(x1) y1 = y + self.canvas.winfo_height() #print(y1) ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo('paint says ', 'image is saved as ' + str(filename)) except: pass
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.configure(background="#353535") self.root.resizable(0, 0) self.pen_color = "black" self.eraser_color = "white" self.color_frame = LabelFrame(self.root, text="Color", font=("Arial", 15), bd=0, relief=RIDGE, bg="grey") self.color_frame.place(x=0, y=0, width=62, height=185) colors = [ "#5CFF45", "#45F7FF", "#4561FF", "#FF4545", "#000000", "#EFFF32", "#FC32FF", "#FF9C32", "#382500", "#00FFC5", "#FF00BA", "#7E0000" ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=0, relief=RIDGE, width=3, command=lambda col=color: self.select_color(col)).grid( row=i, column=j) i += 1 if i == 6: i = 0 j = 1 self.eraser_button = Button(self.root, text="Eraser", bd=0, bg="#FF6B91", command=self.eraser, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=187) self.clear_button = Button( self.root, text="Clear", bd=0, bg="Red", command=lambda: self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=217) self.canvas_color_button = Button(self.root, text="Fill", bd=0, bg="#6BFFA8", command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=247) self.save_button = Button(self.root, text="Save", bd=0, bg="#00AEFF", command=self.save_paint, width=8, relief=RIDGE) self.save_button.place(x=0, y=277) self.pen_size_scale_frame = LabelFrame(self.root, text="Size", bd="0", bg="grey", font=("Arial", 15), relief=RIDGE) self.pen_size_scale_frame.place(x=0, y=301, height=200, width=62) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length=170) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) self.canvas = Canvas(self.root, bg="white", bd=0, relief=GROOVE, height=500, width=700) self.canvas.place(x=80, y=5) self.canvas.bind("<B1-Motion>", self.paint) def paint(self, event): x1, y1 = (event.x - 2), (event.y - 2) x2, y2 = (event.x - 2), (event.y - 2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): self.pen_color = col def eraser(self): self.pen_color = "white" def canvas_color(self): color = colorchooser.askcolor() self.canvas.configure(background=color[1]) def save_paint(self): try: filename = filedialog.asksaveasfilename( defaultextension='.jpg') x = self.root.winfo_rootx() + self.canvas.winfo_x() y = self.root.winfo_rooty() + self.canvas.winfo_y() x1 = x + self.canvas.winfo_width() y1 = y + self.canvas.winfo_height() ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo("Image Saved:", str(filename)) except: messagebox.showerror("Error: \nSomething went wrong :(")
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint Application") self.root.geometry("900x750") self.root.configure(background='white') self.stack = [] self.item = None self.old_x = None self.old_y = None self.old_x_arrow = None self.old_y_arrow = None self.width_val = self.root.winfo_screenwidth() self.height_val = self.root.winfo_screenheight() self.pen_color = 'black' self.eraser_color = 'white' self.save_color = self.pen_color self.choice = 'Pencil' # Adding widgets to tkinter window self.color_frame = LabelFrame(self.root, bd=4, relief=RIDGE, bg="white") self.color_frame.grid(row=0, column=0, pady=(5, 0)) self.color_frame_tooltip = CreateToolTip(self.color_frame, 'Select Brush Color') self.color_frame.config(cursor="hand2") colors = [ '#800000', '#FF0000', '#FFA500', '#FFFF00', '#808000', '#800080', '#FF00FF', '#808080', '#00FF00', '#008000', '#000080', '#0000FF', '#00FFFF', '#008080', '#000000', '#C0C0C0' ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=3, command=lambda col=color: self.select_color(col)).grid( row=i, column=j) i += 1 if i == 8: i = 0 j += 1 self.clear_image = PhotoImage(file='signs.png') self.clear_button = Button(self.root, image=self.clear_image, command=self.clear, width=64) self.clear_button.grid(row=1, column=0, pady=(5, 0)) self.clear_button.config(cursor="hand2") self.clear_button_tooltip = CreateToolTip(self.clear_button, 'Clear the Canvas') self.eraser_image = PhotoImage(file='eraser.png') self.eraser_button = Button(self.root, image=self.eraser_image, command=self.eraser, width=64) self.eraser_button.grid(row=2, column=0) self.eraser_button.config(cursor="hand2") self.eraser_button_tooltip = CreateToolTip(self.eraser_button, 'Eraser') self.line_image = PhotoImage(file='line.png') self.line_button = Button(self.root, image=self.line_image, command=self._createLine, width=64) self.line_button.grid(row=3, column=0) self.line_button.config(cursor="hand2") self.line_button_tooltip = CreateToolTip(self.line_button, 'Straight Line') self.line_arrow_image = PhotoImage(file='arrows.png') self.line_arrow_button = Button(self.root, image=self.line_arrow_image, command=self._createArrowLine, width=64) self.line_arrow_button.grid(row=4, column=0) self.line_arrow_button.config(cursor="hand2") self.line_arrow_button_tooltip = CreateToolTip( self.line_arrow_button, 'Straight Line with Arrow') self.rectangle_image = PhotoImage(file='rectangle.png') self.rectangle_button = Button(self.root, image=self.rectangle_image, command=self._createRectangle, width=64) self.rectangle_button.grid(row=5, column=0) self.rectangle_button.config(cursor="hand2") self.rectangle_button_tooltip = CreateToolTip(self.rectangle_button, 'Rectangle and Square') self.oval_image = PhotoImage(file='oval.png') self.oval_button = Button(self.root, image=self.oval_image, command=self._createOval, width=64) self.oval_button.grid(row=6, column=0) self.oval_button.config(cursor="hand2") self.oval_button_tooltip = CreateToolTip(self.oval_button, 'Oval and Circle') self.pencil_image = PhotoImage(file='pencil.png') self.pencil_button = Button(self.root, image=self.pencil_image, command=self._pencil, width=64) self.pencil_button.grid(row=7, column=0) self.pencil_button.config(cursor="hand2") self.pencil_button_tooltip = CreateToolTip(self.pencil_button, 'Pencil') self.undo_image = PhotoImage(file='undo.png') self.undo_button = Button(self.root, image=self.undo_image, command=self.undo, width=64) self.undo_button.grid(row=9, column=0) self.undo_button.config(cursor="hand2") self.undo_button_tooltip = CreateToolTip(self.undo_button, 'Undo') # self.redo_image = PhotoImage(file='redo.png') # self.redo_button = Button(self.root, image=self.redo_image, command=self.redo, width=64) # self.redo_button.grid(row=8, column=0) # self.redo_button.config(cursor="hand2") # Creating a Scale for pen and eraser size... self.pen_size_scale_frame = Frame(self.root, bd=5, bg='lightblue', relief=RIDGE) self.pen_size_scale_frame.grid(row=10, column=0, pady=5) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=30, to=2, length=170) self.pen_size_tooltip = CreateToolTip( self.pen_size, 'Adjust the size of pen and eraser using this slider.') self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15, pady=5) self.pen_size.config(cursor="hand2") # Creating Canvas self.canvas = Canvas(self.root, bg='white', relief=GROOVE, height=self.height_val, width=self.width_val, cursor="crosshair") self.canvas.place(x=70, y=0) # Binding the canvas with the mouse drag self.canvas.bind("<B1-Motion>", self.paint) self.canvas.bind("<ButtonRelease-1>", self.reset) self.msg = tk.Message(self.root, text=self.choice) self.msg.grid(row=11, column=0, pady=(20, 0)) menu = Menu(self.root) self.root.config(menu=menu) filemenu = Menu(menu) colormenu = Menu(menu) menu.add_cascade(label='Colors', menu=colormenu) colormenu.add_command(label='Brush Color', command=self.brush_color) colormenu.add_command(label='Background Color', command=self.canvas_color) optionmenu = Menu(menu) menu.add_cascade(label='Options', menu=optionmenu) optionmenu.add_command(label='Clear Canvas', command=self.clear) optionmenu.add_command(label='Exit', command=self.root.destroy) menu.add_cascade(label='File', menu=filemenu) filemenu.add_command(label='Save', command=self.save_it) filemenu.add_command(label='Save and Exit', command=self.save_it_destroy) # Function definitions def choice_disp(self): self.msg.config(text=self.choice) def _createRectangle(self): self.choice = 'Rectangle/\nSquare' self.choice_disp() self.rectx0 = 0 self.recty0 = 0 self.rectx1 = 0 self.recty1 = 0 self.rectid = None self.pen_color = self.save_color self.canvas.config(cursor="fleur") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startRect) self.canvas.bind("<ButtonRelease-1>", self.stopRect) self.canvas.bind("<B1-Motion>", self.movingRect) def startRect(self, event): #Translate mouse screen x0,y0 coordinates to canvas coordinates self.rectx0 = self.canvas.canvasx(event.x) self.recty0 = self.canvas.canvasy(event.y) #Create rectangle self.rectid = self.canvas.create_rectangle(self.rectx0, self.recty0, self.rectx0, self.recty0, outline=self.pen_color, width=self.pen_size.get()) def movingRect(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.rectx1 = self.canvas.canvasx(event.x) self.recty1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.rectid, self.rectx0, self.recty0, self.rectx1, self.recty1) def stopRect(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.rectx1 = self.canvas.canvasx(event.x) self.recty1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.rectid, self.rectx0, self.recty0, self.rectx1, self.recty1) self.stack.append(self.rectid) self.stack.append('$') # Delimeter def _createOval(self): self.choice = 'Oval and\nCircle' self.choice_disp() self.ovalx0 = 0 self.ovaly0 = 0 self.ovalx1 = 0 self.ovaly1 = 0 self.ovalid = None self.pen_color = self.save_color self.canvas.config(cursor="fleur") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startOval) self.canvas.bind("<ButtonRelease-1>", self.stopOval) self.canvas.bind("<B1-Motion>", self.movingOval) def startOval(self, event): #Translate mouse screen x0,y0 coordinates to canvas coordinates self.ovalx0 = self.canvas.canvasx(event.x) self.ovaly0 = self.canvas.canvasy(event.y) #Create rectangle self.ovalid = self.canvas.create_oval(self.ovalx0, self.ovaly0, self.ovalx0, self.ovaly0, outline=self.pen_color, width=self.pen_size.get()) def movingOval(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.ovalx1 = self.canvas.canvasx(event.x) self.ovaly1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.ovalid, self.ovalx0, self.ovaly0, self.ovalx1, self.ovaly1) def stopOval(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.ovalx1 = self.canvas.canvasx(event.x) self.ovaly1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.ovalid, self.ovalx0, self.ovaly0, self.ovalx1, self.ovaly1) self.stack.append(self.ovalid) self.stack.append('$') # Delimeter def _createLine(self): self.choice = 'Line' self.choice_disp() self.linex0 = 0 self.liney0 = 0 self.linex1 = 0 self.liney1 = 0 self.lineid = None self.pen_color = self.save_color self.canvas.config(cursor="tcross") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startLine) self.canvas.bind("<ButtonRelease-1>", self.stopLine) self.canvas.bind("<B1-Motion>", self.movingLine) def startLine(self, event): #Translate mouse screen x0,y0 coordinates to canvas coordinates self.linex0 = self.canvas.canvasx(event.x) self.liney0 = self.canvas.canvasy(event.y) #Create rectangle self.lineid = self.canvas.create_line(self.linex0, self.liney0, self.linex0, self.liney0, fill=self.pen_color, width=self.pen_size.get(), smooth=True, capstyle=ROUND) def movingLine(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) def stopLine(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) self.stack.append(self.lineid) self.stack.append('$') # Delimeter def _createArrowLine(self): self.choice = 'Arrow Line' self.choice_disp() self.linex0 = 0 self.liney0 = 0 self.linex1 = 0 self.liney1 = 0 self.lineid = None self.pen_color = self.save_color self.canvas.config(cursor="tcross") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<Button-1>", self.startArrowLine) self.canvas.bind("<ButtonRelease-1>", self.stopArrowLine) self.canvas.bind("<B1-Motion>", self.movingArrowLine) def startArrowLine(self, event): #Translate mouse screen x0,y0 coordinates to canvas coordinates self.linex0 = self.canvas.canvasx(event.x) self.liney0 = self.canvas.canvasy(event.y) #Create rectangle self.lineid = self.canvas.create_line(self.linex0, self.liney0, self.linex0, self.liney0, fill=self.pen_color, arrow="last", arrowshape=(10, 10, 5), width=self.pen_size.get(), smooth=True, capstyle=ROUND) def movingArrowLine(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) def stopArrowLine(self, event): #Translate mouse screen x1,y1 coordinates to canvas coordinates self.linex1 = self.canvas.canvasx(event.x) self.liney1 = self.canvas.canvasy(event.y) #Modify rectangle x1, y1 coordinates self.canvas.coords(self.lineid, self.linex0, self.liney0, self.linex1, self.liney1) self.stack.append(self.lineid) self.stack.append('$') # Delimeter def _pencil(self): self.choice = 'Pencil' self.choice_disp() self.pen_color = self.save_color self.canvas.config(cursor="crosshair") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<B1-Motion>", self.paint) self.canvas.bind("<ButtonRelease-1>", self.reset) def _pencilArrow(self): self.choice = 'Pencil with\nArrow' self.choice_disp() self.pen_color = self.save_color self.canvas.config(cursor="crosshair") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<B1-Motion>", self.paint_arrow) self.canvas.bind("<ButtonRelease-1>", self.reset_arrow) def undo(self): self.item = self.stack.pop() if ( self.item == '$' ): # For undoing figures like rectangle, oval, circle, square, straight lines. self.item = self.stack.pop() self.canvas.delete(self.item) elif (self.item == '#'): self.item = self.stack.pop() while (self.item != '#' and self.item != '$'): self.canvas.delete(self.item) if len(self.stack) == 0: break self.item = self.stack.pop() if self.item == '#' or self.item == '$': self.stack.append(self.item) # def redo(self): # self.item = self.stack.pop() # self.canvas.delete(self.x) def clear(self): self.canvas.delete(ALL) self.canvas.configure(background='white') def paint(self, event): if self.old_x and self.old_y: self.stack.append( self.canvas.create_line(self.old_x, self.old_y, event.x, event.y, width=self.pen_size.get(), fill=self.pen_color, capstyle=ROUND, smooth=True)) self.old_x = event.x self.old_y = event.y def reset(self, e): # Resetting self.old_x = None self.old_y = None self.stack.append('#') def select_color(self, col): self.pen_color = col self.save_color = col def eraser(self): self.choice = 'Eraser' self.choice_disp() self.canvas.config(cursor="dotbox") self.canvas.unbind("<Button-1>") self.canvas.unbind("<ButtonRelease-1>") self.canvas.unbind("<B1-Motion>") self.canvas.bind("<B1-Motion>", self.paint) self.canvas.bind("<ButtonRelease-1>", self.reset) self.pen_color = self.eraser_color def brush_color(self): #changing the pen color self.pen_color = colorchooser.askcolor(color=self.pen_color)[1] self.save_color = self.pen_color def canvas_color(self): color = colorchooser.askcolor() self.canvas.configure(background=color[1]) self.eraser_color = color[1] def save_it(self): try: filename = filedialog.asksaveasfilename(defaultextension='.jpg') ImageGrab.grab().save(filename) messagebox.showinfo('Paint says', 'image is saved as ' + str(filename)) except: messagebox.showerror( 'Paint says', 'unable to save image, \n something went wrong') def save_it_destroy(self): try: filename = filedialog.asksaveasfilename(defaultextension='.jpg') ImageGrab.grab().save(filename) messagebox.showinfo('Paint says', 'image is saved as ' + str(filename)) self.root.destroy() except: messagebox.showerror( 'Paint says', 'unable to save image, \n something went wrong')
command=mute, ) volume_frame.grid(row=1, column=12, padx=10) volume_frame.bind('<Enter>', volume_hobar) volume_frame.bind('<Leave>', volume_leave) #volum button vol = Scale(fm2, from_=0, to=1, orient=HORIZONTAL, value=.33, length=160, command=volume) vol.grid(row=1, column=12) vol_label_plus = Label(fm2, text='v+', font='lucida 10 bold') vol_label_plus.grid(row=1, column=14, padx=10) #song length song_time_frame = Frame(fm2) song_time_frame.grid(rowspan=30, columnspan=60, ipady=20) song_length_slider = Scale(song_time_frame, from_=0, to=100, orient=HORIZONTAL, value=0, length=360, command=s_length) song_length_slider.grid(rowspan=30, columnspan=60, ipady=20)
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0, 0) self.pen_color = "black" self.eraser_color = "white" self.color_frame = LabelFrame(self.root, text='Color', font=('arial', 15), bd=5, relief=RIDGE, bg="white") self.color_frame.place(x=0, y=0, width=70, height=185) colors = [ 'red', 'blue', 'yellow', 'green', 'cyan', 'purple', 'violet', 'pink', 'orange', 'brown', 'black', 'white' ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=3, command=lambda col=color: self.select_color(col)).grid( row=i, column=j) i += 1 if i == 6: i = 0 j += 1 self.eraser_button = Button(self.root, text="ERASER", bd=4, bg='white', command=self.eraser, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=187) self.clear_button = Button(self.root, text="CLEAR", bd=4, bg='white', command=lambda: self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=217) self.save_button = Button(self.root, text="SAVE", bd=4, bg='white', command=self.save_paint, width=8, relief=RIDGE) self.save_button.place(x=0, y=247) self.canvas_color_button = Button(self.root, text="CANVAS", bd=4, bg='white', command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=277) self.custom_color_button = Button(self.root, text="COLOR", bd=4, bg='white', command=self.custom_color, width=8, relief=RIDGE) self.custom_color_button.place(x=0, y=307) self.pen_size_scale_frame = LabelFrame(self.root, text='Size', font=('arial', 15), bd=5, relief=RIDGE, bg="white") self.pen_size_scale_frame.place(x=0, y=337, width=70, height=170) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length=140) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) self.canvas = Canvas(self.root, bg='white', bd=5, relief=GROOVE, height=500, width=700) self.canvas.place(x=80, y=0) self.canvas.bind("<B1-Motion>", self.paint) def paint(self, event): x1, y1 = (event.x - 2), (event.y - 2) x2, y2 = (event.x + 2), (event.y + 2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): self.pen_color = col def eraser(self): self.pen_color = self.eraser_color def canvas_color(self): color = colorchooser.askcolor() self.eraser_color = color[1] self.canvas.configure(background=color[1]) def custom_color(self): color = colorchooser.askcolor() self.pen_color = color[1] def save_paint(self): try: self.canvas.update() filename = filedialog.asksaveasfilename(defaultextension='.jpg') x = self.root.winfo_rootx() + self.canvas.winfo_x() y = self.root.winfo_rooty() + self.canvas.winfo_y() x1 = x + self.canvas.winfo_width() y1 = y + self.canvas.winfo_height() ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo('Paint Says ', 'Image Is Saved As ' + str(filename)) except: messagebox.showinfo('Paint Says ', 'Something Went Wrong, Cannot Save File')
class Config(Toplevel): def __init__(self, master): Toplevel.__init__(self, master) self.title(_("Preferences")) self.grab_set() self.resizable(False, False) self.protocol("WM_DELETE_WINDOW", self.quit) self.changes = {}, {} # --- style style = Style(self) style.theme_use("clam") style.configure("TScale", sliderlength=20) style.map("TCombobox", fieldbackground=[('readonly', 'white')], selectbackground=[('readonly', 'white')], selectforeground=[('readonly', 'black')]) style.configure("prev.TLabel", background="white") style.map("prev.TLabel", background=[("active", "white")]) color = CONFIG.get("Categories", CONFIG.get("General", "default_category")) style.configure("titlebar.TFrame", background=color) style.configure("titlebar.TLabel", background=color) style.configure("text.TFrame", background="white") # --- body self.notebook = Notebook(self) okcancel_frame = Frame(self) okcancel_frame.columnconfigure(0, weight=1) okcancel_frame.columnconfigure(1, weight=1) self.notebook.pack(expand=True, fill="both") okcancel_frame.pack(fill="x", expand=True) # --- * General settings general_settings = Frame(self.notebook) general_settings.columnconfigure(0, weight=1) self.notebook.add(general_settings, text=_("General"), sticky="ewsn", padding=4) # --- *-- language lang = {"fr": "Français", "en": "English"} self.lang = StringVar(self, lang[CONFIG.get("General", "language")]) lang_frame = Frame(general_settings) Label(lang_frame, text=_("Language")).grid(row=0, sticky="w", padx=4, pady=4) menu_lang = Menu(lang_frame, tearoff=False) Menubutton(lang_frame, menu=menu_lang, width=9, textvariable=self.lang).grid(row=0, column=1, padx=8, pady=4) menu_lang.add_radiobutton(label="English", value="English", variable=self.lang, command=self.translate) menu_lang.add_radiobutton(label="Français", value="Français", variable=self.lang, command=self.translate) # --- *-- opacity self.opacity_scale = Scale(general_settings, orient="horizontal", length=200, from_=0, to=100, value=CONFIG.get("General", "opacity"), command=self.display_label) self.opacity_label = Label( general_settings, text="{val}%".format(val=self.opacity_scale.get())) # --- *-- position frame_position = Frame(general_settings) self.position = StringVar(self, CONFIG.get("General", "position")) Label(frame_position, text=_("Default position of the notes")).grid(row=0, columnspan=3, sticky="w", padx=4, pady=4) Radiobutton(frame_position, text=_("Always above"), value="above", variable=self.position).grid(row=1, column=0) Radiobutton(frame_position, text=_("Always below"), value="below", variable=self.position).grid(row=1, column=1) Radiobutton(frame_position, text=_("Normal"), value="normal", variable=self.position).grid(row=1, column=2) # --- *-- titlebar self.titlebar_disposition = StringVar( self, CONFIG.get("General", "buttons_position")) 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) frame_titlebar = Frame(general_settings) frame_titlebar.columnconfigure(1, weight=1) frame_titlebar.columnconfigure(3, weight=1) Label(frame_titlebar, text=_("Title bar disposition")).grid(row=0, columnspan=4, sticky="w", padx=4, pady=4) Radiobutton(frame_titlebar, value="right", variable=self.titlebar_disposition).grid(row=1, column=0) right = Frame(frame_titlebar, style="titlebar.TFrame") right.grid(row=1, column=1, sticky="ew") def select_right(event): self.titlebar_disposition.set("right") Label(right, text=_("Title"), style="titlebar.TLabel", anchor="center", font=font_title).pack(side="left", fill="x", expand=True) Label(right, image="img_close", style="titlebar.TLabel").pack(side="right") Label(right, image="img_roll", style="titlebar.TLabel").pack(side="right") for ch in right.children.values(): ch.bind("<Button-1>", select_right) Radiobutton(frame_titlebar, value="left", variable=self.titlebar_disposition).grid(row=1, column=2) left = Frame(frame_titlebar, style="titlebar.TFrame") left.grid(row=1, column=3, sticky="ew") def select_left(event): self.titlebar_disposition.set("left") Label(left, image="img_close", style="titlebar.TLabel").pack(side="left") Label(left, image="img_roll", style="titlebar.TLabel").pack(side="left") Label(left, text=_("Title"), style="titlebar.TLabel", anchor="center", font=font_title).pack(side="right", fill="x", expand=True) for ch in left.children.values(): ch.bind("<Button-1>", select_left) # --- *-- placement lang_frame.grid(sticky="w") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) Label(general_settings, text=_("Opacity")).grid(sticky="w", padx=4, pady=4) self.opacity_scale.grid(padx=4, pady=(4, 10)) self.opacity_label.place(in_=self.opacity_scale, relx=1, rely=0.5, anchor="w", bordermode="outside") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) frame_position.grid(sticky="ew") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) frame_titlebar.grid(sticky="ew", pady=4) if LATEX: Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) Button(general_settings, text=_('Delete unused LaTex data'), command=self.cleanup).grid(padx=4, pady=4, sticky='w') # --- * Font settings font_settings = Frame(self.notebook) font_settings.columnconfigure(0, weight=1) self.notebook.add(font_settings, text=_("Font"), sticky="ewsn", padding=4) # --- *-- title fonttitle_frame = Frame(font_settings) title_size = CONFIG.get("Font", "title_size") title_family = CONFIG.get("Font", "title_family") self.sampletitle = Label(fonttitle_frame, text=_("Sample text"), anchor="center", style="prev.TLabel", relief="groove") self.sampletitle.grid(row=2, columnspan=2, padx=4, pady=6, ipadx=4, ipady=4, sticky="eswn") self.fonts = list(set(font.families())) self.fonts.append("TkDefaultFont") self.fonts.sort() w = max([len(f) for f in self.fonts]) self.sizes = [ "%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2))) ] self.fonttitle_family = Combobox(fonttitle_frame, values=self.fonts, width=(w * 2) // 3, exportselection=False, validate="key") self._validate_title_size = self.register( lambda *args: self.validate_font_size(self.fonttitle_size, *args)) self._validate_title_family = self.register( lambda *args: self.validate_font_family(self.fonttitle_family, * args)) self.fonttitle_family.configure( validatecommand=(self._validate_title_family, "%d", "%S", "%i", "%s", "%V")) self.fonttitle_family.current(self.fonts.index(title_family)) self.fonttitle_family.grid(row=0, column=0, padx=4, pady=4) self.fonttitle_size = Combobox( fonttitle_frame, values=self.sizes, width=5, exportselection=False, validate="key", validatecommand=(self._validate_title_size, "%d", "%P", "%V")) self.fonttitle_size.current(self.sizes.index(title_size)) self.fonttitle_size.grid(row=0, column=1, padx=4, pady=4) frame_title_style = Frame(fonttitle_frame) frame_title_style.grid(row=1, columnspan=2, padx=4, pady=6) self.is_bold = Checkbutton(frame_title_style, text=_("Bold"), command=self.update_preview_title) self.is_italic = Checkbutton(frame_title_style, text=_("Italic"), command=self.update_preview_title) self.is_underlined = Checkbutton(frame_title_style, text=_("Underline"), command=self.update_preview_title) style = CONFIG.get("Font", "title_style") if "bold" in style: self.is_bold.state(("selected", )) if "italic" in style: self.is_italic.state(("selected", )) if "underline" in style: self.is_underlined.state(("selected", )) self.is_bold.pack(side="left") self.is_italic.pack(side="left") self.is_underlined.pack(side="left") self.update_preview_title() # --- *-- text size = CONFIG.get("Font", "text_size") family = CONFIG.get("Font", "text_family") font_frame = Frame(font_settings) self.sample = Label(font_frame, text=_("Sample text"), anchor="center", style="prev.TLabel", relief="groove") self.sample.grid(row=1, columnspan=2, padx=4, pady=6, ipadx=4, ipady=4, sticky="eswn") self.font_family = Combobox(font_frame, values=self.fonts, width=(w * 2) // 3, exportselection=False, validate="key") self._validate_family = self.register( lambda *args: self.validate_font_family(self.font_family, *args)) self._validate_size = self.register( lambda *args: self.validate_font_size(self.font_size, *args)) self.font_family.configure(validatecommand=(self._validate_family, "%d", "%S", "%i", "%s", "%V")) self.font_family.current(self.fonts.index(family)) self.font_family.grid(row=0, column=0, padx=4, pady=4) self.font_size = Combobox(font_frame, values=self.sizes, width=5, exportselection=False, validate="key", validatecommand=(self._validate_size, "%d", "%P", "%V")) self.font_size.current(self.sizes.index(size)) self.font_size.grid(row=0, column=1, padx=4, pady=4) self.update_preview() # --- *-- placement Label(font_settings, text=_("Title")).grid(row=0, padx=4, pady=4, sticky="w") fonttitle_frame.grid(row=1) Separator(font_settings, orient="horizontal").grid(row=2, sticky="ew", pady=10) Label(font_settings, text=_("Text")).grid(row=3, padx=4, pady=4, sticky="w") font_frame.grid(row=4) # --- * Categories self.category_settings = CategoryManager(self.notebook, master) self.notebook.add(self.category_settings, text=_("Categories"), sticky="ewsn", padding=4) # --- * Symbols symbols_settings = Frame(self.notebook) self.notebook.add(symbols_settings, text=_("Symbols"), sticky="ewsn", padding=4) txt_frame = Frame(symbols_settings, relief="sunken", borderwidth=1, style="text.TFrame") self.symbols = Text(txt_frame, width=1, height=1, highlightthickness=0, spacing2=5, spacing1=5, relief="flat", padx=4, pady=4, font="%s %s" % (family.replace(" ", "\ "), size)) self.symbols.insert("1.0", CONFIG.get("General", "symbols")) Label(symbols_settings, text=_("Available symbols")).pack(padx=4, pady=4) txt_frame.pack(fill="both", expand=True, padx=4, pady=4) self.symbols.pack(fill="both", expand=True) Button(symbols_settings, text=_('Reset'), command=self.reset_symbols).pack(padx=4, pady=4) # --- Ok/Cancel buttons Button(okcancel_frame, text="Ok", command=self.ok).grid(row=1, column=0, padx=4, pady=10, sticky="e") Button(okcancel_frame, text=_("Cancel"), command=self.destroy).grid(row=1, column=1, padx=4, pady=10, sticky="w") # --- bindings self.font_family.bind('<<ComboboxSelected>>', self.update_preview) self.font_family.bind('<Return>', self.update_preview) self.font_size.bind('<<ComboboxSelected>>', self.update_preview, add=True) self.font_size.bind('<Return>', self.update_preview, add=True) self.fonttitle_family.bind('<<ComboboxSelected>>', self.update_preview_title) self.fonttitle_size.bind('<<ComboboxSelected>>', self.update_preview_title, add=True) self.fonttitle_family.bind('<Return>', self.update_preview_title) self.fonttitle_size.bind('<Return>', self.update_preview_title, add=True) def reset_symbols(self): self.symbols.delete('1.0', 'end') self.symbols.insert('1.0', SYMBOLS) def cleanup(self): ''' Remove unused latex images ''' self.master.cleanup() def validate_font_size(self, combo, d, ch, V): ''' Validation of the size entry content ''' if d == '1': l = [i for i in self.sizes if i[:len(ch)] == ch] if l: i = self.sizes.index(l[0]) combo.current(i) index = combo.index("insert") combo.selection_range(index + 1, "end") combo.icursor(index + 1) return ch.isdigit() else: return True def validate_font_family(self, combo, action, modif, pos, prev_txt, V): """ completion of the text in the path entry with existing folder/file names """ try: sel = combo.selection_get() txt = prev_txt.replace(sel, '') except TclError: txt = prev_txt if action == "0": txt = txt[:int(pos)] + txt[int(pos) + 1:] return True else: txt = txt[:int(pos)] + modif + txt[int(pos):] l = [i for i in self.fonts if i[:len(txt)] == txt] if l: i = self.fonts.index(l[0]) combo.current(i) index = combo.index("insert") combo.delete(0, "end") combo.insert(0, l[0].replace("\ ", " ")) combo.selection_range(index + 1, "end") combo.icursor(index + 1) return True else: return False def ok(self): family = self.font_family.get() if family not in self.fonts: l = [i for i in self.fonts if i[:len(family)] == family] if l: family = l[0] else: family = 'TkDefaultFont' size = self.font_size.get() familytitle = self.fonttitle_family.get() if familytitle not in self.fonts: l = [i for i in self.fonts if i[:len(familytitle)] == familytitle] if l: familytitle = l[0] else: familytitle = 'TkDefaultFont' sizetitle = self.fonttitle_size.get() opacity = "%i" % float(self.opacity_scale.get()) language = self.lang.get().lower()[:2] style = "" if self.is_bold.instate(("selected", )): style += "bold," if self.is_italic.instate(("selected", )): style += "italic," if self.is_underlined.instate(("selected", )): style += "underline," if style: style = style[:-1] symbols = [ l.strip() for l in self.symbols.get("1.0", "end").splitlines() ] CONFIG.set("General", "default_category", self.category_settings.default_category.get().lower()) CONFIG.set("General", "language", language) CONFIG.set("General", "opacity", opacity) CONFIG.set("General", "position", self.position.get()) CONFIG.set("General", "buttons_position", self.titlebar_disposition.get()) CONFIG.set("General", "symbols", "".join(symbols)) CONFIG.set("Font", "text_size", size) CONFIG.set("Font", "text_family", family) CONFIG.set("Font", "title_family", familytitle) CONFIG.set("Font", "title_size", sizetitle) CONFIG.set("Font", "title_style", style) col_changes = {} name_changes = {} for cat in self.category_settings.categories: new_name = self.category_settings.get_name(cat) if cat in CONFIG.options("Categories"): old_color = CONFIG.get("Categories", cat) new_color = COLORS[self.category_settings.get_color(cat)] if new_name != cat: name_changes[cat] = new_name CONFIG.remove_option("Categories", cat) CONFIG.set("Categories", new_name, new_color) if old_color != new_color: col_changes[new_name] = (old_color, new_color) CONFIG.set("Categories", new_name, new_color) else: CONFIG.set("Categories", new_name, COLORS[self.category_settings.get_color(cat)]) save_config() self.changes = col_changes, name_changes self.destroy() def get_changes(self): return self.changes def translate(self): showinfo( "Information", _("The language setting will take effect after restarting the application" ), parent=self) def update_preview(self, event=None): family = self.font_family.get() size = self.font_size.get() self.sample.configure(font="%s %s" % (family.replace(" ", "\ "), size)) def update_preview_title(self, event=None): family = self.fonttitle_family.get() size = self.fonttitle_size.get() config = "%s %s" % (family.replace(" ", "\ "), size) if self.is_bold.instate(("selected", )): config += " bold" if self.is_italic.instate(("selected", )): config += " italic" if self.is_underlined.instate(("selected", )): config += " underline" self.sampletitle.configure(font=config) def display_label(self, value): self.opacity_label.configure(text=" {val} %".format( val=int(float(value)))) def quit(self): self.destroy()
class LabeledScale(SmartWidget): def __init__(self, master, **kw): self.__multiplyValue = kw.pop("multiplyValue", False) twoRows = kw.pop("twoRows", False) kw["columns"] = 1 if twoRows else 3 kw["rows"] = 1 valueIsNone = "value" not in kw SmartWidget._setVariable(kw, "IntVar") self.__frame = Frame(master) if twoRows else None super().__init__(master, **kw) if self.__frame: master = self.__frame # = Step = # self.__step = kw.get("step", 1) # = Caption = # self.__caption = Label(master, text=kw["text"]) self.__valueLabel = Label(master, anchor=E) # = Scale = # self.getRawValue().trace_add("write", self.onChanged) storage = self._getValueStorage() for index, key in enumerate(("from_", "to")): if key in storage: kw["range"][index] = storage[key] self.getRawValue().set( StaticUtils.setIfAbsentAndGet( storage, "value", (kw["range"][0] if valueIsNone else self.getValue()) // self.__step)) from_, to = tuple(v // self.__step for v in kw["range"]) self.__scale = Scale(master, from_=from_, length=400, to=to, variable=self.getRawValue()) if "state" in kw: self.__scale["state"] = kw["state"] self.__setValueWidth() def __getitem__(self, key): return self.__scale[key] def __setitem__(self, key, value): self.__scale[key] = value def bindScale(self, event, handler): self.__scale.bind(event, handler) def getRelativeValue(self): return (super().getValue() - self.__scale["from"]) * ( self.__step if self.__multiplyValue else 1) def getValue(self): return super().getValue() * (self.__step if self.__multiplyValue else 1) def grid(self, **kw): kw = StaticUtils.mergeJson(kw, self._smartWidgetGrid, True) if self.__frame: self.__frame.columnconfigure(1, weight=1) self.__frame.grid(sticky=W + E, **kw) self.__caption.grid(column=0, row=0, sticky=W) self.__valueLabel.grid(column=1, padx=(20, 0), row=0, sticky=E) self.__scale.grid(column=0, columnspan=2, pady=(20, 0), row=1, sticky=W + E) else: padxRight = kw["padx"][1] # TODO It can also be a scalar! kw["padx"][1] = 0 # TODO It can also be a scalar! self.__caption.grid(sticky=E, **kw) kw["column"] += 1 kw["padx"] = [20, 0] self.__valueLabel.grid(sticky=W + E, **kw) kw["column"] += 1 kw["padx"][1] = padxRight self.__scale.grid(**kw) def onChanged(self, *_): value = self.getRawValue().get() self.__valueLabel["text"] = value * self.__step self._getValueStorage()["value"] = value def setFrom(self, from_, **args): self.__scale["from"] = from_ // self.__step self._getValueStorage()["from_"] = from_ self._defaultValue = self.__scale["from"] if args.get("validate", True) and self.getValue() < self._defaultValue: self.getRawValue().set(self._defaultValue) self.__setValueWidth() def setTo(self, to, **args): self.__scale["to"] = to // self.__step self._getValueStorage()["to"] = to if args.get("validate", True) and self.getValue() > self.__scale["to"]: self.getRawValue().set(self.__scale["to"]) self.__setValueWidth() def __setValueWidth(self): self.__valueLabel["width"] = max( StaticUtils.getPlaces([ x * self.__step for x in (self.__scale["from"], self.__scale["to"]) ]))
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.config(background='purple') self.root.resizable(0, 0) self.pen_color = "black" #adding frame self.color_frame = LabelFrame(self.root, text="Color", font=('arial', 15), bd=5, relief=RIDGE, bg='white') self.color_frame.place(x=0, y=0, width=70, height=205) colors = [ '#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#00FFFF', '#FF00FF', '#F1510B', '#CD9C10', '#513D53', '#4A7570' ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=3, command=None).grid(row=i, column=j) i += 1 if i == 6: i = 0 j += 1 self.eraser_button = Button(self.root, text="ERASER", bd=4, bg='white', command=None, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=205) self.eraser_button = Button(self.root, text="Clear", bd=4, bg='white', command=None, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=235) self.eraser_button = Button(self.root, text="Save", bd=4, bg='white', command=None, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=265) self.eraser_button = Button(self.root, text="Canvas", bd=4, bg='white', command=None, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=295) self.pen_size_scale_frame = LabelFrame(self.root, text="Size", bd=5, bg='white', font=('arial', 15, 'bold'), relief=RIDGE) self.pen_size_scale_frame.place(x=0, y=325, width=70, height=195) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length=150) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) self.canvas = Canvas(self.root, bg='white', bd=5, relief=GROOVE, height=505, width=715) self.canvas.place(x=70, y=0) self.canvas.bind("<B1-Motion>", self.paint) def paint(self, event): x1, y1 = (event.x - 2), (event.y - 2) x2, y2 = (event.x + 2), (event.y + 2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get())
class AppRow(MagicSession, Frame): """ Row for each app in mixer. handles refreshing the gui if session is changed external. handles user input and changing session volume/mute. """ def __init__(self, root_frame_instance): super().__init__(volume_callback=self.update_volume, mute_callback=self.update_mute, state_callback=self.update_state) self.root_frame_instance = root_frame_instance # ______________ DISPLAY NAME ______________ self.app_name = self.magic_root_session.app_exec print(f":: new session: {self.app_name}") # ______________ CREATE FRAME ______________ # super(MagicSession, self).__init__(root_frame_instance) Frame.__init__(self, root_frame_instance) # _______________ NAME LABEL _______________ self.name_label = Label(self, text=self.app_name, font=("Consolas", 12, "italic")) # _____________ VOLUME SLIDER _____________ self.volume_slider_state = DoubleVar() self.volume_slider = Scale(self, variable=self.volume_slider_state, command=self._slide_volume, from_=0, to=100, takefocus=False, orient=HORIZONTAL) # set initial: self.volume_slider_state.set(self.volume * 100) # ______________ MUTE BUTTON ______________ self.mute_button_state = StringVar() self.mute_button = Button(self, style="", textvariable=self.mute_button_state, command=self._toogle_mute, takefocus=False) # set initial: self.update_mute(self.mute) # _____________ SESSION STATUS _____________ self.status_line = Frame(self, style="", width=6) # set initial: self.update_state(self.state) # ________________ SEPARATE ________________ self.separate = Separator(self, orient=HORIZONTAL) # ____________ ARRANGE ELEMENTS ____________ # set column[1] to take the most space # and make all others as small as possible: self.columnconfigure(1, weight=1) # grid self.name_label.grid(row=0, column=0, columnspan=2, sticky="EW") self.mute_button.grid(row=1, column=0) self.volume_slider.grid(row=1, column=1, sticky="EW", pady=10, padx=20) self.separate.grid(row=2, column=0, columnspan=3, sticky="EW", pady=10) self.status_line.grid(row=0, rowspan=2, column=2, sticky="NS") # _____________ DISPLAY FRAME _____________ self.pack(pady=0, padx=15, fill='x') def update_volume(self, new_volume): """ when volume is changed externally (see callback -> AudioSessionEvents -> OnSimpleVolumeChanged ) """ # compare if the windows callback is because we set the slider: # if so drop update since we made the change # and all is already up to date - this will prevent lagg print(f"{self.app_name} volume: {new_volume}") self.volume_slider_state.set(new_volume * 100) def update_mute(self, new_mute): """ when mute state is changed by user or through other app """ if new_mute: icon = "🔈" self.mute_button.configure(style="Muted.TButton") else: icon = "🔊" self.mute_button.configure(style="Unmuted.TButton") # .set is a method of tkinters variables # it will change the button text print(f"{self.app_name} mute: {icon}") self.mute_button_state.set(icon) def update_state(self, new_state): """ when status changed (see callback -> AudioSessionEvents -> OnStateChanged) """ print(f"{self.app_name} state: {new_state}") if new_state == AudioSessionState.Inactive: # AudioSessionStateInactive self.status_line.configure(style="Inactive.TFrame") elif new_state == AudioSessionState.Active: # AudioSessionStateActive self.status_line.configure(style="Active.TFrame") elif new_state == AudioSessionState.Expired: # AudioSessionStateExpired self.status_line.configure(style="TFrame") """when session expires""" print(f":: closed session: {self.app_name}") self.destroy() def _slide_volume(self, value): """ when slider moved by user """ new_volume = float(value) / 100 # check if new user value really is new: (ttk bug) if self.volume != new_volume: # since self.volume is true data through windows # it will generally differ, but 1.0 == 1 print(f"with pycaw: {self.app_name} volume: {new_volume}") self.volume = new_volume def _toogle_mute(self): """ when mute button pressed """ new_mute = self.toggle_mute() self.update_mute(new_mute)
class Paint(object): def __init__(self, root): #Properties of the objects self.root = root self.root.title("Paint") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0, 0) # Important things self.pen_color = "black" self.eraser_color = "white" #Adding widgets to tkinter window self.color_frame = LabelFrame(self.root, text="color", font = ("arial", 15), bd=5, relief=RIDGE, bg="white") self.color_frame.place(x=0, y=0, width=70, height=185) colors = ["#000000","#FFFFFF" , "#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#00FFFF", "#FF00FF", "#C0C0C0", "#808080", "#800000", "#808000", "#008000", "#800080", "#008080", "#000080"] i=j=0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=3, command=lambda col =color:self.select_color(col)).grid(row=i, column=j) i+=1 if i==6: i=0 j=1 self.eraser_button = Button(self.root, text="ERASER", bg="white", bd=4, command=self.eraser, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=187) self.clear_button = Button(self.root, text="CLEAR", bg="white", bd=4, command=lambda : self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=217) self.save_button = Button(self.root, text="SAVE", bg="white", bd=4, command=self.save_paint, width=8, relief=RIDGE) self.save_button.place(x=0, y=247) self.canvas_color_button = Button(self.root, text="CANVAS", bg="white", bd=4, command=self.canvas, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=277) #Creating a scale for pen and eraser size self.pen_size_scale_frame = LabelFrame(self.root, text="size", bd=5, bg="white", font=("arial", 15, 'bold'), relief=RIDGE) self.pen_size_scale_frame.place(x=0, y=310, height=200, width=70) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to_=0, length=170) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) #Creating Canvas self.canvas = Canvas(self.root, bg="white", bd=5, relief=GROOVE, height=500, width=700) self.canvas.place(x=80, y=0) #Bind the canvas with mouse drag self.canvas.bind("<B1-Motion>", self.paint) #Functions are defined here def paint(self, event): x1, y1 = (event.x-2, event.y-2) x2, y2 = (event.x+2, event.y+2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): #Selects the color self.pen_color = col def eraser(self): # Select the eraser self.pen_color = self.eraser_color def canvas(self): #changes canvas colour color = colorchooser.askcolor() self.canvas.configure(background=color[1]) self.eraser_color = color[1] def save_paint(self): #Save the painting try: filename = filedialog.asksaveasfilename(defaultextension=".jpg") x = self.root.winfo_rootx() + self.canvas.winfo_x() y = self.root.winfo_rooty() + self.canvas.winfo_y() x1 = x + self.canvas.winfo_width() y1 = y + self.canvas.winfo_height() ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo("paint says", "image is saved as" + str(filename)) except: #Show error dialog is something went wrong while saving messagebox.showerror("paint says", "enable to save image,\n something went wrong" )
X = evt.x Y = evt.y comp = sc.identify(X,Y) print(X,Y, 'X,Y') print(sc.identify(X,Y)) # -->slider or trough if comp == 'slider': while str(comp) == 'slider': X -= 1 comp = sc.identify(X,Y) print(X, comp) print('X', X, 'comp', sc.identify(X,Y)) comp = 'slider' while str(comp) == 'slider': X += 1 comp = sc.identify(X,Y) print(X, comp) print('X', X, 'comp', sc.identify(X,Y), 'theme', theme) sc = Scale(root, from_=0, to =100, length = 200) sc.grid(padx=10, pady=10) sc.bind('<ButtonRelease-1>', start_s) root.mainloop()
class Paint(): def __init__(self, root): self.root = root self.root.title("Paint in Python") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0, 0) self.root.iconbitmap('icons/paint.ico') # imp thing self.pen_color = "black" self.eraser_color = "white" # adding widgeths to tkinter window self.color_frame = LabelFrame(self.root, text="color", font=('arial, 13'), bd=5, relief=RIDGE, bg="white") self.color_frame.place(x=0, y=0, width=70, height=185) colors = [ '#ff0000', '#ff4dd2', '#ffff33', '#000000', '#0066ff', '#660033', '#4dff4d', '#b300b3', '#00ffff', '#00ffff', '#808080', '#99ffcc' ] i = j = 0 for color in colors: Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=3, command=lambda col=color: self.select_color(col)).grid( row=i, column=j) i += 1 if i == 6: i = 0 j = 1 self.eraser_button = Button(self.root, text="Borrador", bd=4, bg="white", command=self.eraser, width=8, relief=RIDGE) self.eraser_button.place(x=0, y=187) self.clear_button = Button(self.root, text="Limpiar", bd=4, bg="white", command=lambda: self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=217) self.save_button = Button(self.root, text="Guardar", bd=4, bg="white", command=self.save_paint, width=8, relief=RIDGE) self.save_button.place(x=0, y=247) self.canvas_color_button = Button(self.root, text="Lienzo", bd=4, bg="white", command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=277) # creating a scale for pen and araser size.. self.pen_size_scale_frame = LabelFrame(self.root, text="size", bd=5, bg="white", font=('arial', 15, 'bold'), relief=RIDGE) self.pen_size_scale_frame.place(x=0, y=310, height=200, width=70) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length=170) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) # creating canvas self.canvas = Canvas(self.root, bg='white', bd=5, relief=GROOVE, height=500, width=700) self.canvas.place(x=80, y=0) # bind the canvas with mouse drag self.canvas.bind("<B1-Motion>", self.paint) # funtions are defined here def paint(self, event): #print("mouse es dragged") x1, y1 = (event.x - 2), (event.y - 2) x2, y2 = (event.x + 2), (event.y + 2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): self.pen_color = col def eraser(self): self.pen_color = self.eraser_color def canvas_color(self): color = colorchooser.askcolor() self.canvas.config(background=color[1]) self.eraser_color = color[1] def save_paint(self): try: filename = filedialog.asksaveasfilename(defaultextension=".jpg") print(filename) x = self.root.winfo_rootx() + self.canvas.winfo_x() print(x, self.canvas.winfo_x()) y = self.root.winfo_rooty() + self.canvas.winfo_y() print(y) x1 = x + self.canvas.winfo_width() print(x1) y1 = y + self.canvas.winfo_height() print(y1) ImageGrab.grab().crop((x, y, x1, y1)).save(filename) messagebox.showinfo('paint says', 'image is saved as' + str(filename)) except: print("Not saved somo thing want wrong")
('image', "slider-s-vert", ('background', "slider-s-vert-b"), ('invalid', "slider-s-vert-i"), ('selected', 'slider-s-vert-s'), { 'border': 3 }) } # end of theme extract - don't forget to add comma at end when inserting }) style.theme_use('yummy') # 'default' widg = Scale(fr, from_=0, to=100, length=200, orient='horizontal', command=slide_move) widg.grid(column=0, row=0, sticky='nsew', padx=5, pady=5) widg1 = Scale(fr, from_=100, to=0, length=200, orient='vertical', command=slide_vert) widg1.grid(column=0, row=2, padx=5, pady=5) root.mainloop() ''' , 'Vertical.Progressbar.trough': {"element create": ('image', "trough-pbar-vert", {'border':3})},
class Dialogue(Frame): def __init__(self): super().__init__() self.initUI() def initUI(self): self.style = Style() self.style.theme_use("default") self.master.title("LineChart") self.pack(fill=BOTH, expand=True) self.SSU = BooleanVar() self.SSU.set(1) self.COX1 = BooleanVar() self.COX1.set(1) self.EF1A = BooleanVar() self.EF1A.set(1) self.EF1A_variants = BooleanVar() self.EF1A_variants.set(1) self.filelabel = StringVar(self, "File not chosen") self.filename = "" self.var = IntVar() self.var.set(1) self.clades = IntVar() self.clades.set(0) # self.columnconfigure(2, weight=1) # self.rowconfigure(2, weight=1) cbSSU = Checkbutton(self, text="SSU", variable=self.SSU, state=DISABLED, onvalue=1, offvalue=0) cbSSU.select() cbSSU.grid(sticky=W, padx=5, pady=5) cbCOX1 = Checkbutton(self, text="COX1", variable=self.COX1, onvalue=1, offvalue=0) cbCOX1.select() cbCOX1.grid(sticky=W, row=1, padx=5, pady=5) cbEF1A = Checkbutton(self, text="EF1A", variable=self.EF1A, onvalue=1, offvalue=0) cbEF1A.select() cbEF1A.grid(sticky=W, row=2, padx=5, pady=5) cbEcomb = Checkbutton(self, text="EF1A combinations", variable=self.EF1A_variants, onvalue=1, offvalue=0) cbEcomb.select() cbEcomb.grid(sticky=W, row=3, padx=5, pady=5) openButton = Button(self, text="Choose file", command=self.onOpen) openButton.grid(sticky=W, row=0, column=1, padx=5, pady=5) labFile = Label(self, textvariable=self.filelabel) labFile.grid(sticky=W, row=0, column=2, columnspan=2, padx=5, pady=5) closeButton = Button(self, text="Exit", command=self.quit) closeButton.grid(sticky=E, row=4, column=3, padx=5, pady=5) okButton = Button(self, text="OK", command=self.onOK) okButton.grid(sticky=W, row=4, column=0, padx=5, pady=5) def onOpen(self): ftypes = [('Excel files', '*.xls, *.xlsx'), ('All files', '*')] dlg = filedialog.Open(self, filetypes=ftypes) file = dlg.show() if file != '': self.filelabel.set("Current file: " + file) self.filename = file self.readExcel(self.filename) self.columns = BooleanVar() self.columns.set(1) if self.filelabel.get() != "File not chosen": rboneColumn = Radiobutton(self, text="Arrange in 1 column", variable=self.columns, value=1, command=self.onClick) rboneColumn.grid(sticky=W, row=2, column=1, padx=5, pady=5) rb2Columns = Radiobutton(self, text="Arrange in 2 columns", variable=self.columns, value=0, command=self.onClick) rb2Columns.grid(sticky=W, row=3, column=1, padx=5, pady=5) def readExcel(self, filename): self.dataframe = read_excel(filename, index_col="Specimen") if self.clades.get() != 0: self.labClades.grid_remove() self.clades.set(len(set(self.dataframe.loc[:, "Clade"]))) self.labClades = Label(self, text="Number of clades: " + str(self.clades.get())) self.labClades.grid(sticky=W, row=1, column=1, padx=5, pady=5) def onClick(self): if self.columns.get() == 0: self.scale = Scale(self, from_=1, to=self.clades.get() - 1, command=self.onScale, orient=HORIZONTAL) self.scale.grid(sticky=W, row=3, column=2) self.labScale = Label( self, text="Number of clades in the first column: ") self.labScale.grid(sticky=W, row=2, column=2) self.ScaleVal = Label(self, textvariable=self.var) self.ScaleVal.grid(sticky=E, row=2, column=2) else: self.scale.grid_remove() self.labScale.grid_remove() self.ScaleVal.grid_remove() def onScale(self, val): v = int(float(val)) self.var.set(v) # print(self.var.get()) def onOK(self): dataframe = self.dataframe SSU = self.SSU.get() COX1 = self.COX1.get() EF1A = self.EF1A.get() EF1A_combinations = self.EF1A_variants.get() change = self.var.get() onecolumn = self.columns.get() # graphical parameters: distance between columns and lines of variants, total height etc. top = 200 # uppermost position xS = 1 # X position of SSU column on the graph xE = 2 # X position of EF1A column on the graph xC = 0 # X position of COX1 column on the graph cladeX = 3.3 # X position of clade names on the graph distance = 5 # distance between lines shift = 5 # distance between two columns vardict = {} ssu_set = set() ef1a_set = set() cox1_set = set() # Count the number of specimens for each clade that have a valid SSU and at least one other valid gene variant countdict = {} for specimen in dataframe.index.values: valid = 0 if findall("[A-Za-z]", str(dataframe.loc[specimen, "SSU"])) == []: if EF1A and COX1: if findall("[A-Za-z]", str( dataframe.loc[specimen, "EF1A"])) == [] or findall( "[A-Za-z]", str(dataframe.loc[specimen, "COX1"])) == []: valid = 1 elif EF1A: if findall("[A-Za-z]", str(dataframe.loc[specimen, "EF1A"])) == []: valid = 1 elif COX1: if findall("[A-Za-z]", str(dataframe.loc[specimen, "COX1"])) == []: valid = 1 if dataframe.loc[specimen, "Clade"] not in countdict: countdict[dataframe.loc[specimen, "Clade"]] = valid else: countdict[dataframe.loc[specimen, "Clade"]] += valid # build a dict of connections for every SSU variant, regardless of clades for i in dataframe.index.values: if findall("[A-Za-z]", str(dataframe.loc[ i, "SSU"])) == []: # choosing ony valid SSU variants if dataframe.loc[i, "SSU"] not in vardict: vardict[dataframe.loc[i, "SSU"]] = { "SSU_count": 1, "EF1A": {}, "COX1": {} } # adding new SSU variant into dictionary ssu_set.add(dataframe.loc[i, "SSU"]) else: vardict[dataframe.loc[i, "SSU"]][ "SSU_count"] += 1 # increasing SSU variant count if COX1: if findall("[A-Za-z]", str(dataframe.loc[i, "COX1"]) ) == []: # choosing ony valid COX1 variants if dataframe.loc[i, "COX1"] not in vardict[ dataframe.loc[i, "SSU"]]["COX1"]: vardict[dataframe.loc[i, "SSU"]]["COX1"][ dataframe.loc[ i, "COX1"]] = 1 # adding new COX1 variant cox1_set.add(dataframe.loc[i, "COX1"]) else: vardict[dataframe.loc[i, "SSU"]]["COX1"][ dataframe.loc[ i, "COX1"]] += 1 # increasing COX1 variant count if EF1A and EF1A_combinations: if "homozygous" in str(dataframe.loc[i, "EF1A_combinations"]) \ or "both" in str(dataframe.loc[i, "EF1A_combinations"]) \ and findall("[A-Za-z]", str(dataframe.loc[ i, "EF1A"])) == []: # choosing ony homozygous EF1A variants or unique unknown heterozygous if dataframe.loc[i, "EF1A"] not in vardict[ dataframe.loc[i, "SSU"]]["EF1A"]: vardict[dataframe.loc[i, "SSU"]]["EF1A"][ dataframe.loc[ i, "EF1A"]] = 1 # adding new EF1A variant ef1a_set.add(dataframe.loc[i, "EF1A"]) else: vardict[dataframe.loc[i, "SSU"]]["EF1A"][ dataframe.loc[ i, "EF1A"]] += 1 # increasing EF1A variant count elif "+" in str(dataframe.loc[i, "EF1A_combinations"] ): # choosing known heterozygous variants for var in findall( "[0-9]+", str(dataframe.loc[i, "EF1A_combinations"])): if var not in vardict[dataframe.loc[ i, "SSU"]]["EF1A"]: vardict[dataframe.loc[i, "SSU"]]["EF1A"][ var] = 1 # adding new EF1A variant ef1a_set.add(int(var)) else: vardict[dataframe.loc[i, "SSU"]]["EF1A"][ var] += 1 # increasing EF1A variant count elif EF1A and findall("[A-Za-z]", str( dataframe.loc[i, "EF1A"])) == []: if dataframe.loc[i, "EF1A"] not in vardict[dataframe.loc[ i, "SSU"]]["EF1A"]: vardict[dataframe.loc[i, "SSU"]]["EF1A"][dataframe.loc[ i, "EF1A"]] = 1 # adding new EF1A variant ef1a_set.add(dataframe.loc[i, "EF1A"]) else: vardict[dataframe.loc[i, "SSU"]]["EF1A"][dataframe.loc[ i, "EF1A"]] += 1 # increasing EF1A variant count # print(vardict) # # modify dataframe by adding known heterozygous variants into EF1A column. new_dataframe = dataframe if EF1A_combinations: for i in range(len(new_dataframe["EF1A_combinations"])): if "+" in str(new_dataframe["EF1A_combinations"][i]): if len( findall("[0-9]+", str(new_dataframe["EF1A_combinations"] [i]))) == 1: new_dataframe.loc[ new_dataframe.index.values[i], "EF1A"] = int( findall( "[0-9]+", str(new_dataframe["EF1A_combinations"][i])) [0]) elif len( findall("[0-9]+", str(new_dataframe["EF1A_combinations"] [i]))) == 2: new_dataframe.loc[ new_dataframe.index.values[i], "EF1A"] = int( findall( "[0-9]+", str(new_dataframe["EF1A_combinations"][i])) [0]) new_dataframe = new_dataframe.append( new_dataframe.iloc[i], ignore_index=True) new_dataframe.loc[ new_dataframe.index.values[-1], "EF1A"] = int( findall( "[0-9]+", str(new_dataframe["EF1A_combinations"][i])) [1]) new_dataframe.loc[new_dataframe.index.values[-1], "COX1"] = "" grouping_columns = ["Clade", "SSU"] if COX1: grouping_columns.append("COX1") if EF1A: grouping_columns.append("EF1A") grouped = new_dataframe.groupby(grouping_columns).aggregate( {"SSU": "count"}) # print(grouped) # starting Y coordinates yS = top yE = top yC = top # dictionaries with pairs of coordinates for every variant of every gene ssu_coo = {} cox1_coo = {} ef1a_coo = {} clade_coo = {} # sets of clades and variants that were catalogued already to avoid duplicates clade_done = set() ssu_done = set() cox1_done = set() ef1a_done = set() # Gives XY coordinates to every genetic variant iterating through clades. # Variants are sorted acending; clades are sorted alphabetically counter = 0 # adjusting distance between columns by adding the size of the longest clade name length shift_adj = 0.1 * max( [len(i) for i in grouped.index.get_level_values("Clade")]) + 0.3 shift += shift_adj for clade in grouped.index.get_level_values("Clade"): if clade not in clade_done: if not onecolumn and counter == change: # if a specified change value is reached, starts the second column with a specified shift xS += shift yS = top if COX1: xC += shift yC = top if EF1A: xE += shift yE = top cladeX += shift counter += 1 yS -= distance if COX1: yC -= distance if EF1A: yE -= distance # add coordinates of the clade name and vertical line at the side ssuvalid = set([ i for i in grouped.loc[(clade)].index.get_level_values("SSU") if findall("[A-Za-z]", str(i)) == [] and str(i) != "" ]) if COX1: cox1valid = set([ i for i in grouped.loc[( clade)].index.get_level_values("COX1") if findall("[A-Za-z]", str(i)) == [] and str(i) != "" ]) if EF1A: ef1avalid = set([ i for i in grouped.loc[( clade)].index.get_level_values("EF1A") if findall("[A-Za-z]", str(i)) == [] and str(i) != "" ]) genelenlist = [len(ssuvalid)] if COX1: genelenlist.append(len(cox1valid)) if EF1A: genelenlist.append(len(ef1avalid)) cladeY = yS - (max(genelenlist) - 1) * distance * 0.5 linestart = yS + 0.5 * distance lineend = yS - (max(genelenlist) - 1) * distance - 0.5 * distance clade_coo[clade] = [ cladeX, cladeY, cladeX - 0.2, linestart, lineend, countdict[clade] ] # within-clade vertical position adjustments if COX1 and not EF1A: if len(ssuvalid) - len(cox1valid) >= 2: yC -= distance * (len(ssuvalid) - len(cox1valid)) // 2 elif len(cox1valid) - len(ssuvalid) >= 2: yS -= distance * (len(cox1valid) - len(ssuvalid)) // 2 elif EF1A and COX1: if len(ssuvalid) - len(cox1valid) >= 2: yC -= distance * (len(ssuvalid) - len(cox1valid)) // 2 if len(ssuvalid) - len(ef1avalid) >= 2: yE -= distance * (len(ssuvalid) - len(ef1avalid)) // 2 elif len(ef1avalid) - len(ssuvalid) >= 2: yS -= distance * (len(ef1avalid) - len(ssuvalid)) // 2 yC -= distance * (len(ef1avalid) - len(ssuvalid)) // 2 elif len(cox1valid) - len(ssuvalid) >= 2: yS -= distance * (len(cox1valid) - len(ssuvalid)) // 2 if len(cox1valid) - len(ef1avalid) >= 2: yE -= distance * (len(cox1valid) - len(ef1avalid)) // 2 elif len(ef1avalid) - len(cox1valid) >= 2: yC -= distance * (len(ef1avalid) - len(cox1valid)) // 2 yS -= distance * (len(ef1avalid) - len(cox1valid)) // 2 elif len(ef1avalid) - len(ssuvalid) >= 2: yS -= distance * (len(ef1avalid) - len(ssuvalid)) // 2 yC -= distance * (len(ef1avalid) - len(cox1valid)) // 2 elif len(ssuvalid) - len(ef1avalid) >= 2: yE -= distance * (len(ssuvalid) - len(ef1avalid)) // 2 elif EF1A: if len(ssuvalid) - len(ef1avalid) >= 2: yE -= distance * (len(ssuvalid) - len(ef1avalid)) // 2 elif len(ef1avalid) - len(ssuvalid) >= 2: yS -= distance * (len(ef1avalid) - len(ssuvalid)) // 2 # finally, assign coordinates for ssu in grouped.loc[(clade)].index.get_level_values("SSU"): if findall("[A-Za-z]", str(ssu)) == [] and str( ssu ) != "": # choose only valid genetic variants (no text, only numbers) if ssu not in ssu_done: ssu_coo[ssu] = [xS, yS] yS -= distance ssu_done.add(ssu) if COX1: for cox1 in grouped.loc[( clade)].index.get_level_values("COX1"): if findall("[A-Za-z]", str(cox1)) == [] and str( cox1 ) != "": # choose only valid genetic variants (no text, only numbers) if cox1 not in cox1_done: cox1_coo[cox1] = [xC, yC] yC -= distance cox1_done.add(cox1) if EF1A: for ef1a in grouped.loc[( clade)].index.get_level_values("EF1A"): if findall("[A-Za-z]", str(ef1a)) == [] and str( ef1a ) != "": # choose only valid genetic variants (no text, only numbers) if ef1a not in ef1a_done: ef1a_coo[ef1a] = [xE, yE] yE -= distance ef1a_done.add(ef1a) clade_done.add(clade) geneXlist = [xS] geneYlist = [yS] if COX1: geneXlist.append(xC) geneYlist.append(yC) if EF1A: geneXlist.append(xE) geneYlist.append(yE) lowest = min(geneYlist) yS = lowest yC = lowest yE = lowest # print(grouped) # Building a plot def choose_line(size): # a rule for choosing line width for the plot size = int(size) if size in (1, 2): width = 1 elif size == 3: width = 1.5 elif size < 6: width = 2 elif size < 11: width = 2.5 else: width = 3 return width # remove axes ax1 = axes(frameon=False) ax1.set_frame_on(False) ax1.get_xaxis().set_visible(False) ax1.get_yaxis().set_visible(False) # build the lines between genetic variants for ssu in vardict: if EF1A: for ef1a in vardict[ssu]["EF1A"]: if findall("[A-Za-z]", str(ef1a)) == []: size = vardict[ssu]["EF1A"][ef1a] plot([ ef1a_coo[int(ef1a)][0] + 0.4, ssu_coo[ssu][0] + 0.5 ], [ef1a_coo[int(ef1a)][1], ssu_coo[ssu][1]], linestyle="dashed" if size == 1 else "solid", linewidth=choose_line(size), color="black") text(ef1a_coo[int(ef1a)][0] + 0.7, ef1a_coo[int(ef1a)][1], ef1a, ha="center", va="center") if COX1: for cox1 in vardict[ssu]["COX1"]: if findall("[A-Za-z]", str(cox1)) == []: size = vardict[ssu]["COX1"][cox1] plot([cox1_coo[cox1][0], ssu_coo[ssu][0]], [cox1_coo[cox1][1], ssu_coo[ssu][1]], linestyle="dashed" if size == 1 else "solid", linewidth=choose_line(vardict[ssu]["COX1"][cox1]), color="black") text(cox1_coo[cox1][0] - 0.3, cox1_coo[cox1][1], cox1, ha="center", va="center") text(ssu_coo[ssu][0] + 0.25, ssu_coo[ssu][1], ssu, ha="center", va="center") # add gene names above the variants for the second column if not onecolumn: text(xS - shift + 0.25, top + distance + 0.2, "SSU", ha="center") text(xS + 0.25, top + distance + 0.2, "SSU", ha="center") if EF1A: text(xE - shift + 0.7, top + distance + 0.2, "EF1A", ha="center") text(xE + 0.7, top + distance + 0.2, "EF1A", ha="center") if COX1: text(xC - shift - 0.3, top + distance + 0.2, "COI", ha="center") text(xC - 0.3, top + distance + 0.2, "COI", ha="center") else: text(xS + 0.25, top + distance + 0.2, "SSU", ha="center") if EF1A: text(xE + 0.7, top + distance + 0.2, "EF1A", ha="center") if COX1: text(xC - 0.3, top + distance + 0.2, "COI", ha="center") # add clade names and vertical lines to the right of the column for clade in clade_coo: if EF1A: text(clade_coo[clade][0], clade_coo[clade][1], "%s (%d)" % (clade, clade_coo[clade][5]), ha="left", va="center") plot([clade_coo[clade][2], clade_coo[clade][2]], [clade_coo[clade][3], clade_coo[clade][4]], linewidth=2, color="black") else: text(clade_coo[clade][0] - shift * 0.5 + shift_adj + 0.65, clade_coo[clade][1], "%s (%d)" % (clade, clade_coo[clade][5]), ha="left", va="center") plot([ clade_coo[clade][2] - shift * 0.5 + shift_adj + 0.7, clade_coo[clade][2] - shift * 0.5 + shift_adj + 0.7 ], [clade_coo[clade][3], clade_coo[clade][4]], linewidth=2, color="black") # set limits for X axis to avoid overlapping with legend if not onecolumn and EF1A: xlim(0, 14) elif not onecolumn: xlim(0, 12) elif onecolumn and EF1A: xlim(0, 7) elif onecolumn: xlim(0, 5) # produce lines for a legend leg_lines = [ Line2D([0], [0], color="black", linestyle="dashed", linewidth=1), Line2D([0], [0], color="black", linewidth=1), Line2D([0], [0], color="black", linewidth=1.5), Line2D([0], [0], color="black", linewidth=2), Line2D([0], [0], color="black", linewidth=2.5), Line2D([0], [0], color="black", linewidth=3) ] # plot legend legend(leg_lines, ["1", "2", "3", "4-5", "6-10", "11-20"], loc="upper right") # show the plot show()
class Paint(): DEFAULT_PEN_SIZE = 5.0 DEFAULT_COLOR = 'black' def __init__(self): self.root = Tk() self.root.geometry('1000x800') #adding widgets self.color_frame = LabelFrame(self.root, text='Color', font=('arial', 15), bd=5, relief=RIDGE, bg="white") #bd is borderwidth self.color_frame.place(x = 0, y =0, width=82, height= 185) colors = ["white", "black", "red", "green", "blue", "cyan", "yellow", "magenta", 'pale violet red', 'maroon', 'turquoise1', 'purple2'] i = 0 j = 0 #i for row and j for column for color in colors: Button(self.color_frame, bg = color, bd=2, relief=RIDGE, width=1, command=lambda col=color:self.select_color(col)).grid(row = i, column = j) i = i + 1 if(i == 6): i = 0 j = 1 #eraser button image = Image.open("eraser.png") image = image.resize((40, 40)) self.photo_image_eraser = ImageTk.PhotoImage(image) self.eraser_button = Button(self.root, image = self.photo_image_eraser, command = self.use_eraser, relief= RIDGE) self.eraser_button.place(x = 0, y = 187) #pen button image = Image.open("pen.jpeg") image = image.resize((40, 40)) self.photo_image_pen = ImageTk.PhotoImage(image) self.pen_button = Button( self.root, image=self.photo_image_pen, command=self.use_pen, relief=RIDGE) self.pen_button.place(x = 43, y = 187) #clear button self.clear_button = Button(self.root, text="CLEAR", bd = 4, bg='white', command = lambda:self.c.delete("all"), width = 8, relief=RIDGE) self.clear_button.place(x = 0, y = 225) #save button self.save_button = Button( self.root, text="SAVE", bd=4, bg='white', command = self.save, width=8, relief=RIDGE) self.save_button.place(x=0, y= 255) self.canvas_color_button = Button( self.root, text="Canvas", bd=4, bg='white', command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=285) #creating a scale for pen and eraser size self.pen_size_scale_frame = LabelFrame(self.root, text="SIZE",bd = 5, bg="white", font=('arial', 15, 'bold'), relief=RIDGE) self.pen_size_scale_frame.place(x = 0, y = 318, height = 200, width = 85) self.pen_size = Scale(self.pen_size_scale_frame, orient=VERTICAL, from_=50, to=0, length = 170) #setting the default value self.pen_size.set(1) self.pen_size.grid(row = 0 , column = 1, padx = 15) #Circle button image = Image.open('circle.jpg') image = image.resize((40, 40)) self.photo_image_circle = ImageTk.PhotoImage(image) self.circle_button = Button( self.root, image=self.photo_image_circle, command=self.draw_circle, relief=RIDGE) self.circle_button.place(x = 0, y = 518) #FILLED_CIRCLE image = Image.open('filled_circle.png') image = image.resize((40, 40)) self.photo_image_circle_filled = ImageTk.PhotoImage(image) self.circle_filled_button = Button( self.root, image=self.photo_image_circle_filled, command=self.draw_circle_filled, relief=RIDGE) self.circle_filled_button.place(x = 43, y = 518) #Rectangle image = Image.open("rectangle.png") image = image.resize((40, 40)) self.photo_image_rectangle = ImageTk.PhotoImage(image) self.rectangle_button = Button( self.root, image=self.photo_image_rectangle, command=self.draw_rect, relief=RIDGE) self.rectangle_button.place(x = 0, y = 564) #Filled Rectangle image = Image.open("filled_rectangle.png") image = image.resize((40, 40)) self.photo_image_rectangle_filled = ImageTk.PhotoImage(image) self.rectangle_filled_button = Button( self.root, image=self.photo_image_rectangle_filled, command=self.draw_rect_filled, relief=RIDGE) self.rectangle_filled_button.place(x = 43, y = 564) #Arc image = Image.open("arc.png") image = image.resize((40, 40)) self.photo_image_arc = ImageTk.PhotoImage(image) self.arc_button = Button( self.root, image=self.photo_image_arc, command=self.draw_arc, relief=RIDGE) self.arc_button.place(x = 0 , y = 610) #Filled arc image = Image.open("filled_arc.png") image = image.resize((40, 40)) self.photo_arc_circle_filled = ImageTk.PhotoImage(image) self.arc_filled_button = Button( self.root, image=self.photo_arc_circle_filled, command=self.draw_arc_filled, relief=RIDGE) self.arc_filled_button.place(x = 43, y = 610) #line image = Image.open("line.png") image = image.resize((40, 40)) self.photo_image_line = ImageTk.PhotoImage(image) self.line_button = Button( self.root, image=self.photo_image_line, command=self.draw_line, relief=RIDGE) self.line_button.place(x = 0, y = 656) #dashed_line image = Image.open("dashed_line.png") image = image.resize((40, 40)) self.photo_image_dashed_line = ImageTk.PhotoImage(image) self.dashed_line_button = Button( self.root, image=self.photo_image_dashed_line, command=self.draw_dashed_line, relief=RIDGE) self.dashed_line_button.place(x = 43, y = 656) #creating canvas self.c = Canvas(self.root, bg = "white", bd = 5, height=500, width = 700) self.c.place(x = 90, y = 0) self.drawn = None self.kinds = [self.c.create_oval, self.c.create_rectangle, self.c.create_arc, self.c.create_line] self.setup() self.eraser_color = 'white' self.root.mainloop() def setup(self): self.old_x = None self.old_y = None self.line_width = self.pen_size.get() self.color = self.DEFAULT_COLOR self.eraser_on = False #self.active_button = self.pen_button def use_pen(self): self.activate_button(self.pen_button) self.c.bind('<B1-Motion>', self.paint) self.c.bind('<ButtonRelease-1>', self.reset) def use_eraser(self): self.activate_button(self.eraser_button, eraser_mode=True) self.c.bind('<B1-Motion>', self.paint) self.c.bind('<ButtonRelease-1>', self.reset) def activate_button(self, some_button, eraser_mode=False): #self.active_button.config(relief=RAISED) #some_button.config(relief=SUNKEN) self.active_button = some_button self.eraser_on = eraser_mode def draw_circle(self): self.activate_button(self.circle_button) self.c.bind('<ButtonPress-1>', self.on_start_circle) self.c.bind('<B1-Motion>', self.on_grow_shapes) def on_start_circle(self, event): self.shape = self.kinds[0] self.start = event self.drawn = None def draw_circle_filled(self): self.activate_button(self.circle_filled_button) self.c.bind('<ButtonPress-1>', self.on_start_circle_filled) self.c.bind('<B1-Motion>', self.on_grow_shapes_filled) def on_start_circle_filled(self, event): self.shape = self.kinds[0] self.start = event self.drawn = None def draw_rect(self): self.activate_button(self.rectangle_button) self.c.bind('<ButtonPress-1>', self.on_start_rect) self.c.bind('<B1-Motion>', self.on_grow_shapes) def on_start_rect(self, event): self.shape = self.kinds[1] self.start = event self.drawn = None def draw_rect_filled(self): self.activate_button(self.rectangle_filled_button) self.c.bind('<ButtonPress-1>', self.on_start_rect_filled) self.c.bind('<B1-Motion>', self.on_grow_shapes_filled) def on_start_rect_filled(self, event): self.shape = self.kinds[1] self.start = event self.drawn = None def draw_arc(self): self.activate_button(self.arc_button) self.c.bind('<ButtonPress-1>', self.on_start_arc) self.c.bind('<B1-Motion>', self.on_grow_shapes) def on_start_arc(self, event): self.shape = self.kinds[2] self.start = event self.drawn = None def draw_arc_filled(self): self.activate_button(self.arc_filled_button) self.c.bind('<ButtonPress-1>', self.on_start_arc_filled) self.c.bind('<B1-Motion>', self.on_grow_shapes_filled) def on_start_arc_filled(self, event): self.shape = self.kinds[2] self.start = event self.drawn = None def on_grow_shapes(self, event): self.line_width = self.pen_size.get() c = event.widget if self.drawn: c.delete(self.drawn) objectId = self.shape(self.start.x, self.start.y, event.x, event.y, outline=self.color, width=self.line_width) if trace: print(objectId) self.drawn = objectId def on_grow_shapes_filled(self, event): c = event.widget if self.drawn: c.delete(self.drawn) objectId = self.shape(self.start.x, self.start.y, event.x, event.y, outline=self.color, fill=self.color) if trace: print(objectId) self.drawn = objectId def draw_line(self): self.activate_button(self.line_button) self.c.bind('<ButtonPress-1>', self.on_start_line) self.c.bind('<B1-Motion>', self.on_grow_line) def on_start_line(self, event): self.shape = self.kinds[3] self.start = event self.drawn = None def on_grow_line(self, event): self.line_width = self.pen_size.get() c = event.widget if self.drawn: c.delete(self.drawn) objectId = self.shape(self.start.x, self.start.y, event.x, event.y, fill=self.color, width=self.line_width) if trace: print(objectId) self.drawn = objectId def draw_dashed_line(self): self.activate_button(self.dashed_line_button) self.c.bind('<ButtonPress-1>', self.on_start_dashed_line) self.c.bind('<B1-Motion>', self.on_grow_dashed_line) def on_start_dashed_line(self, event): self.shape = self.kinds[3] self.start = event self.drawn = None def on_grow_dashed_line(self, event): self.line_width = self.pen_size.get() c = event.widget if self.drawn: c.delete(self.drawn) objectId = self.shape(self.start.x, self.start.y, event.x, event.y, fill=self.color, dash=(4, 2), width=self.line_width) if trace: print(objectId) self.drawn = objectId def paint(self, event): self.line_width = self.pen_size.get() paint_color = self.eraser_color if self.eraser_on else self.color if self.old_x and self.old_y: self.c.create_line(self.old_x, self.old_y, event.x, event.y, width=self.line_width, fill=paint_color, capstyle=ROUND, smooth=TRUE, splinesteps=36) self.old_x = event.x self.old_y = event.y def reset(self, event): self.old_x, self.old_y = None, None def select_color(self, col): self.color = col def canvas_color(self): color = askcolor() #returns a tuple (rgbvalue, hexadecimal value) #we are using hexadecimal value self.c.configure(background = color[1]) self.eraser_color = color[1] def save(self): try: filename = filedialog.asksaveasfilename(defaultextension=".jpg") x = self.root.winfo_rootx() + self.c.winfo_x() y = self.root.winfo_rooty() + self.c.winfo_y() x1 = x + self.c.winfo_width() y1 = y + self.c.winfo_height() im = ImageGrab.grab(bbox = (x, y, x1, y1)) #print(str(filename)) im.save(str(filename)) #messagebox.showinfo("Image is saved as", str(filename)) except: pass
class paint(object): DEFAULT_PEN_SIZE = 10.0 def __init__(self): self.root= Tk() self.root.title("My Paint") self.root.geometry("800x500") self.size=Canvas(self.root, width=800, height=500) self.root.configure(bg="white") self.pen_color="black" self.eraser_color="white" self.color_frame=LabelFrame(self.root, text="Color", font=('arial', 15, 'bold'), bd=5, relief=RIDGE, bg="#6FA5F5") self.color_frame.place(x=10, y=400, width=240, height=90) colors=['white', 'black', 'brown','red', 'orange','yellow','green', 'blue', '#3E1C91', '#F20A85'] i=j=0 for color in colors: #col is value of color Button(self.color_frame, bg=color, bd=2, relief=RIDGE, width=5, command=lambda col= color: self.select_color(col)).grid(row=i, column=j) j+=1 if j==5: j=0 i=1 self.edit_color_button=Button(self.root, text="Edit Color",font=('arial', 11, 'bold'), bd=3, bg="#6FA5F5", command=self.edit_color, width=12,height=2, relief=RIDGE) self.edit_color_button.place(x=255, y=400) self.eraser_button=Button(self.root, text="Eraser",font=('arial', 11, 'bold'), bd=3, bg="#6FA5F5", command=self.eraser, width=12,height=2, relief=RIDGE) self.eraser_button.place(x=255, y=445) self.clear_button=Button(self.root, text="Clear",font=('arial', 11, 'bold'), bd=3, bg="#6FA5F5", command=lambda : self.canvas.delete("all"), width=12,height=2, relief=RIDGE) self.clear_button.place(x=355, y=400) self.save_button=Button(self.root, text="Save",font=('arial', 11, 'bold'), bd=3, bg="#6FA5F5", command=self.save_paint, width=12,height=2, relief=RIDGE) self.save_button.place(x=355, y=445) self.pen_size_scale_frame=LabelFrame(self.root, text="size", bd=5, bg="#6FA5F5", font=('areal',15,'bold'), relief=RIDGE) self.pen_size_scale_frame.place(x=480, y=400, height=70, width=250) self.pen_size=Scale(self.pen_size_scale_frame, orient=HORIZONTAL, from_=0, to=50, length=220) self.pen_size.set(1) self.pen_size.grid(row=0, column=1, padx=15) self.canvas=Canvas(self.root, bg='white', bd=5, relief=GROOVE, height=380, width=787) self.canvas.place(x=0, y=0) #self.setup() self.canvas.bind('<B1-Motion>', self.paint) self.root.mainloop() #dragging of mouse def paint(self, event): x1, y1=(event.x-2), (event.y-2) x2, y2=(event.x+2),(event.y+2) self.canvas.create_oval(x1, y1, x2, y2, fill=self.pen_color, outline=self.pen_color, width=self.pen_size.get()) def select_color(self, col): self.pen_color=col def eraser(self): self.pen_color=self.eraser_color def edit_color(self): color=colorchooser.askcolor() self.pen_color=color[1] def save_paint(self): try: #self.canvas.update() filename = filedialog.asksaveasfilename(defaultextension='.jpg') #print(filename) x = self.root.winfo_rootx() + self.canvas.winfo_x() #print(x, self.canvas.winfo_x()) y = self.root.winfo_rooty() + self.canvas.winfo_y() #print(y) x1 = x + self.canvas.winfo_width() #print(x1) y1 = y + self.canvas.winfo_height() #print(y1) ImageGrab.grab().crop(x, y, x1, y1).save(filename) messagebox.showinfo('paint says image is saved as ', + str(filename)) except: messagebox.showerror("paint says", "unable to save image, \n something went wrong")
class NotebookDemo: def __init__(self, fr): self.fr = fr self.style = Style() # ts.ThemedStyle() # Style() self._create_demo_panel() # run this before allBtns self.allBtns = self.ttkbut + self.cbs[1:] + self.rb try: piratz_theme.install('piratz') except Exception: import warnings warnings.warn("piratz theme being used without images") def _create_demo_panel(self): demoPanel = Frame(self.fr, name="demo") demoPanel.pack(side='top', fill='both', expand='y') # create the notebook self.nb = nb = Notebook(demoPanel, name="nb") nb.bind("<<NotebookTabChanged>>", self._on_tab_changed) # extend bindings to top level window allowing # CTRL+TAB - cycles thru tabs # SHIFT+CTRL+TAB - previous tab # ALT+K - select tab using mnemonic (K = underlined letter) nb.enable_traversal() nb.pack(fill='both', expand='y', padx=2, pady=3) self._create_descrip_tab(nb) self._create_treeview_tab(nb) self._create_text_tab(nb) def _create_descrip_tab(self, nb): # frame to hold contents frame = Frame(nb, name='descrip') # widgets to be displayed on 'Description' tab # position and set resize behaviour frame.rowconfigure(1, weight=1) frame.columnconfigure((0, 1), weight=1, uniform=1) lf = LabelFrame(frame, text='Animals') lf.pack(pady=5, padx=5, side='left', fill='y') themes = ['horse', 'elephant', 'crocodile', 'bat', 'grouse'] self.ttkbut = [] for t in themes: b = Button(lf, text=t) b.pack(pady=2) self.ttkbut.append(b) lF2 = LabelFrame(frame, text="Theme Combobox") lF2.pack(pady=5, padx=5) themes = list(sorted( self.style.theme_names())) # get_themes # used in ttkthemes themes.insert(0, "Pick a theme") self.cb = cb = Combobox(lF2, values=themes, state="readonly", height=10) cb.set(themes[0]) #cb.bind('<<ComboboxSelected>>', self.change_style) cb.grid(row=0, column=0, sticky='nw', pady=5) lf1 = LabelFrame(frame, text='Checkbuttons') lf1.pack(pady=5, padx=5, side='left', fill='y') # control variables self.enabled = IntVar() self.cheese = IntVar() self.tomato = IntVar() self.basil = IntVar() self.oregano = IntVar() # checkbuttons self.cbOpt = Checkbutton(lf1, text='Enabled', variable=self.enabled, command=self._toggle_opt) cbCheese = Checkbutton(text='Cheese', variable=self.cheese, command=self._show_vars) cbTomato = Checkbutton(text='Tomato', variable=self.tomato, command=self._show_vars) sep1 = Separator(orient='h') cbBasil = Checkbutton(text='Basil', variable=self.basil, command=self._show_vars) cbOregano = Checkbutton(text='Oregano', variable=self.oregano, command=self._show_vars) sep2 = Separator(orient='h') self.cbs = [ self.cbOpt, sep1, cbCheese, cbTomato, sep2, cbBasil, cbOregano ] for opt in self.cbs: if opt.winfo_class() == 'TCheckbutton': opt.configure(onvalue=1, offvalue=0) opt.setvar(opt.cget('variable'), 0) opt.pack(in_=lf1, side='top', fill='x', pady=2, padx=5, anchor='nw') lf2 = LabelFrame(frame, text='Radiobuttons', labelanchor='n') lf2.pack(pady=5, padx=5, side='left', fill='y') self.rb = [] self.happiness = StringVar() for s in ['Great', 'Good', 'OK', 'Poor', 'Awful']: b = Radiobutton(lf2, text=s, value=s, variable=self.happiness, command=lambda s=s: self._show_vars()) b.pack(anchor='nw', side='top', fill='x', pady=5, padx=5) self.rb.append(b) right = LabelFrame(frame, text='Control Variables') right.pack(pady=5, padx=5, side='left', fill='y') self.vb0 = Label(right, font=('Courier', 10)) self.vb1 = Label(right, font=('Courier', 10)) self.vb2 = Label(right, font=('Courier', 10)) self.vb3 = Label(right, font=('Courier', 10)) self.vb4 = Label(right, font=('Courier', 10)) self.vb5 = Label(right, font=('Courier', 10)) self.vb0.pack(anchor='nw', pady=5, padx=5) self.vb1.pack(anchor='nw', pady=5, padx=5) self.vb2.pack(anchor='nw', pady=5, padx=5) self.vb3.pack(anchor='nw', pady=5, padx=5) self.vb4.pack(anchor='nw', pady=5, padx=5) self.vb5.pack(anchor='nw', pady=5, padx=5) self._show_vars() # add to notebook (underline = index for short-cut character) nb.add(frame, text='Description', underline=0, padding=2) # ============================================================================= def _create_treeview_tab(self, nb): # Populate the second pane. Note that the content doesn't really matter tree = None self.backg = ["white", '#f0f0ff'] tree_columns = ("country", "capital", "currency") tree_data = [("Argentina", "Buenos Aires", "ARS"), ("Australia", "Canberra", "AUD"), ("Brazil", "Brazilia", "BRL"), ("Canada", "Ottawa", "CAD"), ("China", "Beijing", "CNY"), ("France", "Paris", "EUR"), ("Germany", "Berlin", "EUR"), ("India", "New Delhi", "INR"), ("Italy", "Rome", "EUR"), ("Japan", "Tokyo", "JPY"), ("Mexico", "Mexico City", "MXN"), ("Russia", "Moscow", "RUB"), ("South Africa", "Pretoria", "ZAR"), ("United Kingdom", "London", "GBP"), ("United States", "Washington, D.C.", "USD")] container = Frame(nb) container.pack(fill='both', expand=False) self.tree = Treeview(container, columns=tree_columns, show="headings") vsb = Scrollbar(container, orient="vertical", command=self.tree.yview) hsb = Scrollbar(container, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) self.tree.grid(column=0, row=0, sticky='ns', in_=container) vsb.grid(column=1, row=0, sticky='ns', in_=container) hsb.grid(column=0, row=1, sticky='ew', in_=container) container.grid_columnconfigure(0, weight=1) container.grid_rowconfigure(0, weight=1) for col in tree_columns: self.tree.heading( col, text=col.title(), command=lambda c=col: self.sortby(self.tree, c, 0)) # XXX tkFont.Font().measure expected args are incorrect according # to the Tk docs self.tree.column(col, width=Font().measure(col.title()), stretch=False) for ix, item in enumerate(tree_data): itemID = self.tree.insert('', 'end', values=item) self.tree.item(itemID, tags=itemID) self.tree.tag_configure(itemID, background=self.backg[ix % 2]) # adjust columns lengths if necessary for indx, val in enumerate(item): ilen = Font().measure(val) if self.tree.column(tree_columns[indx], width=None) < ilen: self.tree.column(tree_columns[indx], width=ilen) sg = Sizegrip(container) sg.grid(sticky='e') nb.add(container, text='Treeview', underline=0, padding=2) # ============================================================================= def _create_text_tab(self, nb): self.dir0 = 1 self.dir1 = 1 # populate the third frame with other widgets fr = Frame(nb, name='fr') lF = LabelFrame(fr, text="Slider") fr1 = Frame(lF) fr1.grid(row=0, column=0, sticky='nsew') from_ = 100 to = 0 value = 0 step = 10 fontSize = 9 self.scvar = IntVar() scRange = self.any_number_range(from_, to, step) scLen = len(scRange[1]) * (fontSize + 10) self.sc = Scale(fr1, from_=from_, to=to, variable=self.scvar, orient='vertical', length=scLen, command=self.v_scale) self.sc.set(value) l1 = Label(fr1, textvariable=self.scvar, width=5) l1.grid(row=0, column=0, padx=5, pady=5) self.sc.grid(row=0, column=1, padx=5, pady=5) fr4 = Frame(fr1) fr4.grid(row=0, column=2) sc_split = '\n'.join(scRange[0].split()) lb = Label(fr1, text=sc_split, font=('Courier New', str(fontSize))) lb.grid(row=0, column=2, padx=5, pady=5) fr2 = Frame(lF, name='fr2') fr2.grid(row=0, column=1, sticky='nsew') self.schvar = IntVar() a = 0 b = 100 schRange = self.any_number_range(a, b, s=10) schLen = Font().measure(schRange[0]) self.sch = Scale(fr2, from_=a, to=b, length=schLen, variable=self.schvar, orient='horizontal', command=self.h_scale) self.sch.set(0) l2 = Label(fr2, textvariable=self.schvar) l2.grid(row=1, column=1, pady=2) self.sch.grid(row=2, column=1, padx=5, pady=5, sticky='nsew') l3 = Label(fr2, text=schRange[0], font=('Courier New', str(fontSize))) l3.grid(row=3, column=1, padx=5, pady=5) lF.grid(row=0, column=0, sticky='nesw', pady=5, padx=5) lF1 = LabelFrame(fr, text="Progress", name='lf') pb1var = IntVar() pb2var = IntVar() self.pbar = Progressbar(lF1, variable=pb1var, length=150, mode="indeterminate", name='pb1', orient='horizontal') self.pb2 = Progressbar(lF1, variable=pb2var, length=150, mode='indeterminate', name='pb2', orient='vertical') self.pbar["value"] = 25 self.h_progress() self.v_progress() self.pbar.grid(row=1, column=0, padx=5, pady=5, sticky='nw') self.pb2.grid(row=1, column=1, padx=5, pady=5, sticky='nw') l3 = Label(lF1, textvariable=pb1var) l3.grid(row=0, column=0, pady=2, sticky='nw') l4 = Label(lF1, textvariable=pb2var) l4.grid(row=0, column=1, pady=2, sticky='nw') sg1 = Sizegrip(fr) sg1.grid(row=2, column=2, sticky='e') lF1.grid(row=1, column=0, sticky='nesw', pady=5, padx=5) # add to notebook (underline = index for short-cut character) nb.add(fr, text='Sliders & Others', underline=0) #========================================================================= def _toggle_opt(self): # state of the option buttons controlled # by the state of the Option frame label widget for opt in self.allBtns: if opt.winfo_class() != 'TSeparator': if self.cbOpt.instate(('selected', )): opt['state'] = '!disabled' # enable option self.nb.tab(1, state='normal') else: opt['state'] = 'disabled' self.nb.tab(1, state='disabled') self._show_vars() def _show_vars(self): # set text for labels in var_panel to include the control # variable name and current variable value self.vb0['text'] = '{:<11} {:<8}'.format('enabled:', self.enabled.get()) self.vb1['text'] = '{:<11} {:<8}'.format('cheese:', self.cheese.get()) self.vb2['text'] = '{:<11} {:<8}'.format('tomato:', self.tomato.get()) self.vb3['text'] = '{:<11} {:<8}'.format('basil:', self.basil.get()) self.vb4['text'] = '{:<11} {:<8}'.format('oregano:', self.oregano.get()) self.vb5['text'] = '{:<11} {:<8}'.format('happiness:', self.happiness.get()) def sortby(self, tree, col, descending): """Sort tree contents when a column is clicked on.""" # grab values to sort data = [(tree.set(child, col), child) for child in tree.get_children('')] # reorder data data.sort(reverse=descending) for indx, item in enumerate(data): tree.move(item[1], '', indx) # switch the heading so that it will sort in the opposite direction tree.heading(col, command=lambda col=col: self.sortby( tree, col, int(not descending))) # reconfigure tags after ordering list_of_items = tree.get_children('') for i in range(len(list_of_items)): tree.tag_configure(list_of_items[i], background=self.backg[i % 2]) def any_number_range(self, a, b, s=1): """ Generate consecutive values list between two numbers with optional step (default=1).""" if (a == b): return a else: mx = max(a, b) mn = min(a, b) result = [] output = '' # inclusive upper limit. If not needed, delete '+1' in the line below while (mn < mx + 1): # if step is positive we go from min to max if s > 0: result.append(mn) mn += s # if step is negative we go from max to min if s < 0: result.append(mx) mx += s # val maxLen = 0 output = "" for ix, res in enumerate(result[:-1]): # last value ignored if len(str(res)) > maxLen: maxLen = len(str(res)) if maxLen == 1: output = ' '.join(str(i) for i in result) # converts list to string else: for ix, res in enumerate(result): if maxLen == 2: if len(str(res)) == 1: output = output + str(res) + " " * maxLen elif len(str(res)) == 2: output = output + str(res) + " " else: output = output + str(res) #print(output) return output, result def change_style(self, event=None): """set the Style to the content of the Combobox""" content = self.cb.get() try: self.style.theme_use(content) except TclError as err: messagebox.showerror('Error', err) else: root.title(content) def change_theme(self, theme): window = ttktheme.ThemedTk() window.set_theme(theme) root.title(theme) def _on_tab_changed(self, event): event.widget.update_idletasks() tab = event.widget.nametowidget(event.widget.select()) event.widget.configure(height=tab.winfo_reqheight(), width=tab.winfo_reqwidth()) def h_progress(self): widg = self.pbar widg['value'] += 1 * self.dir0 if widg['value'] == 100: widg.state(['background', '!active']) self.dir0 = -1 widg.after(50, self.h_progress) elif widg['value'] == 0: widg.state(['active', '!background']) self.dir0 = 1 widg.after(50, self.h_progress) else: widg.after(50, self.h_progress) def v_progress(self): widg1 = self.pb2 widg1['value'] += 1 * self.dir1 if widg1['value'] == 0: # (dir1-1)*100+16 widg1.state(['active', '!invalid', '!background']) self.dir1 = 1 widg1.after(40, self.v_progress) elif widg1['value'] == 16: # (dir1-1)*100+16 widg1.state(['background', '!invalid', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 33: widg1.state(['invalid', '!background', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 50: widg1.state(['active', '!invalid', '!background']) widg1.after(40, self.v_progress) elif widg1['value'] == 66: widg1.state(['background', '!invalid', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 83: widg1.state(['invalid', '!background', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 100: widg1.state(['active', '!invalid', '!background']) self.dir1 = -1 widg1.after(40, self.v_progress) else: widg1.after(40, self.v_progress) def h_scale(self, schvar): v = int(float(schvar)) widg = self.sch imgw = { 0: ['readonly', '!selected', '!background', '!focus', '!active'], 1: ['selected', '!readonly', '!background', '!focus', '!active'] } if v >= 0 and v < 10: widg.state(['active', '!readonly', '!selected']) elif v > 80 and v < 91: widg.state(['focus', '!background', '!readonly', '!selected']) elif v > 90 and v < 100: widg.state(['background', '!invalid', '!focus']) elif v == 100: widg.state(['invalid', '!background']) else: widg.state(imgw[v % 2]) def v_scale(self, scvar): v = int(float(scvar)) widg1 = self.sc imgw = { 0: ['background', '!selected', '!invalid', '!active'], 1: ['selected', '!invalid', '!background', '!active'] } if v >= 0 and v < 5: widg1.state(['active', '!background', '!selected']) elif v > 90: widg1.state(['invalid', '!selected', '!background']) else: widg1.state(imgw[v % 2])
class Paint(): def __init__(self, root): self.root = root self.root.title("paint") self.root.geometry("800x520") self.root.configure(background="white") self.root.resizable(0,0) self.pen_color = "black" self.eraser_color = "white" #adding widges to paint self.color_frame = LabelFrame(self.root,text='Color',font = ('Times New Roman',15),bd=5,relief=RIDGE,bg="white") self.color_frame.place(x=0,y=0,width=70,height=195) colors = ['red','black','pink','blue','grey','cyan','brown','yellow','purple','hotpink','green','olive','plum','indigo'] i=j=0 for color in colors: Button(self.color_frame,bg=color,bd=1,relief=RIDGE,width=3,command=lambda col =color:self.select_color(col)).grid(row=i,column=j) i+=1 if i==7: i=0 j+=1 self.eraser_button = Button(self.root,text="ERASER",bd=4,bg="white",command=self.eraser,width=8,relief=RIDGE) self.eraser_button.place(x=0,y=192) self.clear_button = Button(self.root, text="CLEAR", bd=4, bg="white", command=lambda : self.canvas.delete("all"), width=8, relief=RIDGE) self.clear_button.place(x=0, y=222) self.save_button = Button(self.root, text="SAVE", bd=4, bg="white", command=None, width=8, relief=RIDGE) self.save_button.place(x=0, y=252) self.canvas_color_button = Button(self.root, text="FILL", bd=4, bg="white", command=self.canvas_color, width=8, relief=RIDGE) self.canvas_color_button.place(x=0, y=282) #creating a Scale for pen and Eraser Size self.pen_size_scale_frame = LabelFrame(self.root,text="size",bd=5,bg="white",font=('Times New Roman',15,'bold'),relief=RIDGE) self.pen_size_scale_frame.place(x=0,y=313,height=200,width=70) self.pen_size = Scale(self.pen_size_scale_frame,orient=VERTICAL,from_=50,to=0,length=170) self.pen_size.set(1) self.pen_size.grid(row=0,column=1,padx=15) #creating canvas self.canvas = Canvas(self.root,bg="white",bd=5,relief=GROOVE,height=500,width=700) self.canvas.place(x=80,y=0) #bind canvas with mouse drag self.canvas.bind("<B1-Motion>",self.paint) #functions def paint(self,event): x1,y1 = (event.x-2),(event.y-2) x2, y2 = (event.x + 2), (event.y + 2) self.canvas.create_oval(x1,y1,x2,y2,fill=self.pen_color,outline=self.pen_color,width=self.pen_size.get()) def select_color(self, col): self.pen_color = col def eraser(self): self.pen_color = self.eraser_color def canvas_color(self): color = colorchooser.askcolor() self.canvas.configure(background=color[1]) self.eraser_color = color[1]
class Mplay(Frame): """Music player made with tkinter and pygame / mutagen Usage: app = Mplay(master: tk.Tk, *, title: str=, width: int=, height=)""" master: Frame # shut up mypy def __init__(self, parent: Union[Tk, tk.ThemedTk] = None, *, title: str = "Music Player", width: int = 600, height: int = 400, ) -> None: super().__init__(parent) # call ttk.Frame constructor mixer.init() # initializethe pygame mixer self.assets_path: str = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets') if parent is not None: self.parent = parent else: self.parent = self.master self.parent.geometry(f'{width}x{height}') self.parent.title(title) self.parent.minsize(width // 2, height // 2) self.parent.iconbitmap(self.assets_path + '/icons/melody.ico') self.parent.protocol("WM_DELETE_WINDOW", self.on_closing) self.init_vol: int = 70 self.paused: bool = False self.muted: bool = False self.playing: bool = False self.current_song: Opt[str] = None self.selected_song_num: Opt[int] = None self.playlist: List[str] = [] self._init_ui() def _init_ui(self) -> None: self._menubar() self._statusbar() self._create_leftframe() self._create_rightframe() self._create_middleframe() self._create_bottomframe() def about_us(self) -> None: messagebox.showinfo('About Melody', 'This is a music player built using Python Tkinter by @meee') def browse_file(self) -> None: filename_path = filedialog.askopenfilename() if filename_path: self.add_to_playlist(filename_path) mixer.music.queue(filename_path) def add_to_playlist(self, filepath: str) -> None: filename = os.path.basename(filepath) index = 0 self.playlistbox.insert(index, filename) self.playlist.insert(index, filepath) index += 1 def _create_leftframe(self) -> None: self.leftframe = Frame(self.parent) self.leftframe.pack(side=LEFT, padx=30) self.playlistbox = Listbox(self.leftframe) self.playlistbox.pack() addBtn = Button(self.leftframe, text="+ Add", command=self.browse_file) addBtn.pack(side=LEFT) delBtn = Button(self.leftframe, text="- Del", command=self.del_song) delBtn.pack(side=LEFT) def _statusbar(self) -> None: self.statusbar = Label(self.parent, text="Welcome to Melody", relief=SUNKEN, anchor=W) self.statusbar.pack(side=BOTTOM, fill=X) def _menubar(self) -> None: menubar = Menu(self.parent) root.config(menu=menubar) # Create the submenu1 subMenu1 = Menu(menubar, tearoff=0) menubar.add_cascade(label="File", menu=subMenu1) subMenu1.add_command(label="Open", command=self.browse_file) subMenu1.add_command(label="Exit", command=root.destroy) # Create the submenu2 subMenu2 = Menu(menubar, tearoff=0) menubar.add_cascade(label="Help", menu=subMenu2) subMenu2.add_command(label="About Us", command=self.about_us) def del_song(self) -> None: self.get_selected_song_num() # update self.selected_song_num if self.selected_song_num is not None: # if a song is selected if self.playlist[self.selected_song_num] == self.current_song: # if song is currently playing self.stop_music() # stop it self.playlistbox.delete(self.selected_song_num) # delete the song from the box self.playlist.pop(self.selected_song_num) # and playlist # self.selected_song_num remains same, so will play/del next song? self.reset_song() self.selected_song_num = None # reset self.selected_song_num def _create_rightframe(self) -> None: self.rightframe = Frame(self.parent) self.rightframe.pack() self.filelabel = Label(self.rightframe, text='Lets make some noise!') self.filelabel.pack(pady=10) self.lengthlabel = Label(self.rightframe, text='Total Length : --:--') self.lengthlabel.pack() self.currenttimelabel = Label(self.rightframe, text='Current Time : --:--', relief=GROOVE) self.currenttimelabel.pack() def start_count(self, total_time: int) -> None: """.""" current_time = 0 while current_time <= total_time and mixer.music.get_busy(): # music.get_busy() -> Returns False when stopped if self.paused: continue # if paused, infinite loop (don't count) else: mins, secs = divmod(current_time, 60) mins = round(mins) secs = round(secs) timeformat = '{:02d}:{:02d}'.format(mins, secs) self.currenttimelabel['text'] = "Current Time" + ' - ' + timeformat time.sleep(1) current_time += 1 def reset_song(self) -> None: self.current_song = None self.filelabel['text'] = "" self.lengthlabel['text'] = 'Total Length : --:--' self.currenttimelabel['text'] = "Current Time : --:--" self.statusbar['text'] = "" def show_details(self, play_song: str) -> None: self.filelabel['text'] = "Playing" + ' - ' + os.path.basename(play_song) file_data = os.path.splitext(play_song) if file_data[1] == '.mp3': audio = MP3(play_song) total_length = audio.info.length elif file_data[1] == '.wav': a = mixer.Sound(play_song) total_length = a.get_length() else: try: a = mixer.Sound(play_song) total_length = a.get_length() except Exception as e: print(e, "not a supported file type? e.g. .wav, .mp3") mins, secs = divmod(total_length, 60) # returns (time//60, remainder) mins = round(mins) secs = round(secs) timeformat = '{:02d}:{:02d}'.format(mins, secs) self.lengthlabel['text'] = "Total Length" + ' - ' + timeformat t1 = threading.Thread(target=self.start_count, args=(total_length, )) t1.start() def pause_music(self) -> None: if self.playing: self.paused = True mixer.music.pause() self.statusbar['text'] = "Music Paused" def get_selected_song_num(self) -> None: try: selected_song_from_box: Tuple[int] = self.playlistbox.curselection() self.selected_song_num = int(selected_song_from_box[0]) except IndexError as e: # no files in the playlistbox tuple self.statusbar['text'] = "Choose a file from the playlist" if DEBUG: print(e) except Exception as e: messagebox.showerror('File not found, or unknown file type. Please check again.') if DEBUG: print(e) def play_music(self) -> None: """if not playing: play, if playing and paused, unpause""" self.get_selected_song_num() # update self.selected_song_num if self.selected_song_num is not None and self.playlist: play_it: Opt[str] = self.playlist[self.selected_song_num] else: play_it = None if not self.playing and play_it: # if not yet playing, play selected song try: self.stop_music() time.sleep(0.5) mixer.music.load(play_it) mixer.music.play() except Exception as e: messagebox.showerror('File not found, or unknown file type. Please check again.') if DEBUG: print(e) else: self.playing = True self.current_song = play_it self.show_details(play_it) self.statusbar['text'] = "Playing music" + ' - ' + os.path.basename(play_it) elif self.playing and self.paused: # if paused, resume mixer.music.unpause() self.statusbar['text'] = "Music Resumed" self.paused = False elif self.playing and not self.paused: if play_it == self.current_song and play_it is not None: # if already playing song, do nothing self.statusbar['text'] = "Playing music" + ' - ' + os.path.basename(play_it) else: # if different song selected, retry self.playing = False self.play_music() def stop_music(self) -> None: if self.playing: self.playing = False self.current_song = None mixer.music.stop() self.statusbar['text'] = "Music Stopped" def rewind_music(self) -> None: if self.playing: self.stop_music() time.sleep(0.5) self.play_music() self.statusbar['text'] = "Music Rewound to start" def set_vol(self, val: str) -> None: vol_float = float(val) volume = int(vol_float) / 100 mixer.music.set_volume(volume) # set_volume of mixer takes value only from 0 to 1 def mute_music(self) -> None: if self.muted: # Unmute the music mixer.music.set_volume(0.7) self.volumeBtn.configure(image=self.volumePhoto) self.scale.set(70) self.muted = False else: # mute the music mixer.music.set_volume(0) self.volumeBtn.configure(image=self.mutePhoto) self.scale.set(0) self.muted = True def _create_middleframe(self) -> None: self.middleframe = Frame(self.rightframe) self.middleframe.pack(pady=30, padx=30) self.playPhoto = PhotoImage(file=self.assets_path + '/icons/play.png') playBtn = Button(self.middleframe, image=self.playPhoto, command=self.play_music) playBtn.grid(row=0, column=1, padx=10) self.stopPhoto = PhotoImage(file=self.assets_path + '/icons/stop.png') stopBtn = Button(self.middleframe, image=self.stopPhoto, command=self.stop_music) stopBtn.grid(row=0, column=2, padx=10) self.pausePhoto = PhotoImage(file=self.assets_path + '/icons/pause.png') pauseBtn = Button(self.middleframe, image=self.pausePhoto, command=self.pause_music) pauseBtn.grid(row=0, column=3, padx=10) def _create_bottomframe(self) -> None: self.bottomframe = Frame(self.rightframe) self.bottomframe.pack() self.mutePhoto = PhotoImage(file=self.assets_path + '/icons/mute.png') self.volumePhoto = PhotoImage(file=self.assets_path + '/icons/volume.png') self.volumeBtn = Button(self.bottomframe, image=self.volumePhoto, command=self.mute_music) self.volumeBtn.grid(row=0, column=1) self.rewindPhoto = PhotoImage(file=self.assets_path + '/icons/rewind.png') rewindBtn = Button(self.bottomframe, image=self.rewindPhoto, command=self.rewind_music) rewindBtn.grid(row=0, column=0) self.scale = Scale(self.bottomframe, from_=0, to=100, orient=HORIZONTAL, command=self.set_vol) self.scale.set(self.init_vol) mixer.music.set_volume(self.init_vol / 100) self.scale.grid(row=0, column=2, pady=15, padx=30) def on_closing(self) -> None: try: self.stop_music() self.parent.destroy() except Exception as e: if DEBUG: print(e) else: print('App closed')