# Simple enough, just import everything from tkinter. from tkinter import * from tkinter import messagebox from tkinter import * import tkinter.simpledialog from tkinter.colorchooser import * ############ class GetPointsDialog(object): #constructor def __init__(self,parent): #self.parent = master self.top = Toplevel(parent) Label(self.top, text="X1:").grid(row=0) Label(self.top, text="X2:").grid(row=2) self.e1 = Entry(self.top) self.e2 = Entry(self.top) self.e1.grid(row=0, column=1) self.e2.grid(row=2, column=1) ############# Y cordinates ########## Label(self.top, text="Y1:").grid(row=0, column=3) Label(self.top, text="Y2:").grid(row=2, column=3) self.y1 = Entry(self.top) self.y2 = Entry(self.top) self.y1.grid(row=0, column=4) self.y2.grid(row=2, column=4) #radio buttons for dashing self.d_val = StringVar() #this collects the radio button values 1 for dashed self.dashed = Radiobutton(self.top, text="Dashed", variable = self.d_val, value="dashed" ) self.un_dashed = Radiobutton(self.top, text="Un Dashed", variable = self.d_val, value="undashed" ) #positioning the radio buttons self.dashed.grid(row= 4, column=0) self.un_dashed.grid(row=4,column=1 ) #color button Button(self.top, text="Color", command=self.choose_color).grid(row=4, column=3) #submit button Button(self.top, text="Submit", command=self.submit).grid(row=6, column=1) #cancel the dialog button Button(self.top, text="Cancel", command=self.close).grid(row=6, column=2) """ choose the color for the widget to be created on the canvas """ def choose_color(self): rgb_color, web_color = askcolor(master =self.top,initialcolor=(255, 0, 0)) #returns a turple rgb and web color, We cose to use web_color as hex self.w_color = web_color print(self.w_color) def close(self): self.top.destroy() """ Handle the events when a submit button on the custom dialog is created. It should be able to handle the events whenever the user inputs data for the required parameters for establishing the widgets. It also switches the frame input if it needed to create a Circle widget or Rectangle or a Line """ def submit(self): self.x1 = self.e1.get() self.x2 = self.e2.get() self.y1 = self.y1.get() self.y2 = self.y2.get() print("Value is ",self.e1.get()) self.top.destroy() # p = painter.Painter(self.top) #p.Create_Rectangle(self.x1, self.y1,self.x2,self.y2,self.w_color) """ reset all values collected """ def reset(self): self.x1 = 0 self.x2 = 0 self.y1 = 0 self.y2 = 0 # Here, we are creating our class, Window, and inheriting from the Frame # class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__) class Painter(Frame): # Define settings upon initialization. Here you can specify def __init__(self, master=None): # parameters that you want to send through the Frame class. Frame.__init__(self, master) #reference to the master widget, which is the tk window self.master = master #with that, we want to then run init_window, which doesn't yet exist self.init_widgets() #Creation of init_window def init_widgets(self): # changing the title of our master widget self.master.title("Python Paint") # allowing the widget to take the full space of the root window #self.pack(side=RIGHT, fill=BOTH, expand=1) # creating a menu instance self.menu = Menu(self.master) self.master.config(menu=self.menu) # create the file object) self.file = Menu(self.menu) # adds a command to the menu option, calling it exit, and the # command it runs on event is client_exit #add elements to the file self.file.add_command(label="New", command=self.create_New_Canvas) self.file.add_command(label="Save") self.file.add_separator() self.file.add_command(label="Exit", command=self.client_exit) #added "file" to our menu self.menu.add_cascade(label="File", menu=self.file) # create the file object) self.options = Menu(self.menu) # adds commands to the options menu self.options.add_command(label="Circle", command=self.get_Cordinate_Points) self.options.add_command(label="Line", command=self.get_Cordinate_Points) self.options.add_command(label="Rectangle", command=self.get_Cordinate_Points) self.options.add_separator() self.options.add_command(label="Clear All", command=self.clear) #added "options" to our menu self.menu.add_cascade(label="Options", menu=self.options) self.menu.entryconfig("Options", state="disabled") #create a new menu called Help help = Menu(self.menu) help.add_command(label="Help", command=self.help_callback) #add help to menu bar self.menu.add_cascade(label="Help", menu=help) #buttons self.pen = Button(self.master,text="Pen", state=DISABLED) self.pen.grid(row=0, column=1) #postioning self.line = Button(self.master,text="Line", state=DISABLED) self.line.grid(row=0, column=2) self.circle = Button(self.master,text="Circle", state=DISABLED) self.circle.grid(row=0, column=3) def clear(self): #clear all the cordinate values pass """ exit the program on confirmation """ def client_exit(self): #confirm if user wants to cancel the window if messagebox.askokcancel("Python","Would you like to save the data?"): self.master.destroy() """ Show help message =box when help is clicked """ def help_callback(self): messagebox.showinfo( "About my paint", "Created by: Me") """ create a new canvas and add the widgets onto the proper location and call the enable_menu () method """ def create_New_Canvas(self): #enable options menu self.enable_menu() self.activate_buttons() # create a new canvas self.new_canvas = Canvas(self.master, bg="grey", height=200, width=350) self.new_canvas.grid(row=4, column=2) #activate the buttons def activate_buttons(self): self.line.config(state="normal") self.circle.config(state="normal") self.pen.config(state="normal") """ This method should handle the state of “Option menu” in the menu bar and activate it into normal mode, also the dynamic buttons should be activated. """ def enable_menu(self): self.menu.entryconfig("Options", state="normal") """ this method calls the child window, gets the coordinates which are entered by the user by passing the appropriate widget to the child class, this method also takes the decision to the further methods by passing the variables returned from the user """ def get_Cordinate_Points(self): #initialize the child dialog here cd = GetPointsDialog(self.master) #if what_to_draw == 'circle': #call the create circle #pass #elif what_to_draw == 'line': #call the create_line #pass #elif what_to_draw == 'rect': #call the create_rectangle function #pass """ able to create Circle, with the dashed format or regular line format based on the input from the user; it also raises an error if the user has not checked any option. """ def Create_Circle (self, x1, y1, color_hex): #parameters are the bounding box coordinates of the circle self.new_canvas.create_oval(x1, y1, outline=color_hex,fill="gray", width=2) """ able to create Line, with the dashed format or regular line format based on the input from the user; it also raises an error if the user has not checked any option. """ def Create_Line(self, x1,y1,x2,y2, color_hex): #create a new line on the canvas x and y values are cordinates from top left as (0,0) self.new_canvas.create_line(x1,y1,x2,y2, fill=color_hex) """ able to create Rectangle, with the dashed format or regular line format based on the input from the user; it also raises an error if the user has not checked any option. """ def Create_Rectangle(self, x1,y1,x2,y2, color_hex): #same as create_line above #create_rectangle(50, 20, 150, 80, fill="#476042") self.new_canvas.create_rectangle(x1, y1, x2, y2, fill=color_hex) #we will work with colors after everything is okay # root window created. Here, that would be the only window, but # you can later have windows within windows. root = Tk() root.geometry("550x350") #creation of an instance app = Painter(root) #mainloop root.mainloop()