TAGS :Viewed: 5 - Published at: a few seconds ago

[ trouble creating oval widgets in python tkinter ]

I am having issues creating oval shapes on a canvas widget, so i have declared a canvas widget on a frame in the constructor.

class Map(Frame):

    def __init__(self, master = none):
        Frame.__init__(self, master)
        .......  ##lines of code
        c = Canvas(master, width = 500,height = 500,relief = "groove")
        c.pack(side  = "right")

    def operation(self):
        .............. ##lines of code
        self.createoval()  ##call create oval method after loop code

    def createoval(self):
        x = 0
        y = 0
        c1 = canvas.create_oval(x-5, y-5, x+10, y+10, fill = "red")
        ##error map object has no create_oval.
        c1.coords(c1, x, y)  
        c1.move(c1, 500, 500)
        return c1

Ideally, what i would like is to create oval shapes after the loop has finished, so i would call the method that handles this, however i am having two issues.

1st. First issue i am having is creating oval on the canvas that has been established in the constructor. When i try to do this, i get message "canvas not defined" or when i use self.canvas.createoval, i get the message "map object has no attribute canvas"

So my question is how can i create a method that can create ovals on a canvas establsihed in the constructor?

2nd issue:

c1 = canvas.create_oval(x-5, y-5, x+10, y+10, fill = "red")

I get error that x is not defined, even though it is defined and i have used the coords() method but this has not fixed the problem.

Answer 1


You've got a number of issues with this code. Below is code that works for me in creating an oval on your canvas (although given your coordinates, it is partly off screen).

from tkinter import *

class Map(Frame):

    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.c = Canvas(master, width = 500,height = 500,relief = "groove")
        self.c.pack(side  = "right")

    def operation(self):
        self.createoval()  ##call create oval method after loop code

    def createoval(self):
        x = 0
        y = 0
        c1 = self.c.create_oval(x-5, y-5, x+10, y+10, fill = "red")
        return c1

m = Map(Tk())
m.createoval()

To address some of your problems:

  1. You used none when you should have used None. It is case sensitive!
  2. When you create an object, if you want a variable to be known to that instance of the object, you need to make it part of self. That means when you create your canvas with c = Canvas(... you need to actually have self.c = Canvas(.... Otherwise c will only exist within the scope of __init__ and will not exist anywhere else.
  3. You try to create your oval using the canvas variable but where did this variable come from? It was never defined previously. You specifically called your canvas variable c in the __init__ method so you need to call it the same thing in the createoval method. Note you still also need to use self.c.
  4. You used the line c1.coords(c1,x,y) presumably to set the position of the oval. However the creation of the oval will have already set the position, so if that was your intent, this is a redundant line. It is also not being used correctly. The variable c1 that was created is a simple integer which is an ID for the oval on the canvas. You need to call the coords method with the canvas object using self.c.coords(c1,x,y). This will reset the coordinates for the c1 oval on the canvas self.c to the position (x,y), however since you never changed x or y after creating the oval, it will set it to the same position and you won't notice any change.
  5. You'll see the same problem with your call to move as you do for coords.