Results 1 to 6 of 6

Thread: Graphics/classes in Tkinter

  1. #1
    Join Date
    Sep 2008
    Beans
    51

    Graphics/classes in Tkinter

    Hi guys,

    After a long day of much frustration teaching myself Tkinter in Python, I am here with a few questions I have been unable to resolve/understand. I appreciate any help or advice.

    First question: This is the stripped down code for a Tkinter GUI which isolates my problem:
    Code:
    from Tkinter import *
    
    WINDOWWIDTH=500
    WINDOWHEIGHT=500
    
    
    class App:    
         def __init__ (self,master):
            self.x=10
            self.y=10
            self.display = Frame(master, width=WINDOWWIDTH, 
    height=WINDOWHEIGHT)
            self.canvas=Canvas(self.display, bg='blue')
                   #Draw boxes, set up screen layout
    
            self.box1=self.canvas.drawBox()
            self.display.pack()
            self.canvas.pack()
    
        def drawBox(self):
            newbox=self.create_rectangle(self.x, self.y, self.x+70, 
    self.y+70, width=5, fill='red')
       self.tag_bind(newbox, '<B1-Motion>', self.onDrag)
        return newbox
    
    root= Tk()
    app=App(root)
    root.mainloop()
    This should create a new box (self.box1) with parent self.canvas. It is bound to function self.onDrag, which I deleted from this code. However, when I try to run I keep getting the error "AttributeError: Canvas instance has no attribute 'drawBox'".I've tried deleting the return statement and just calling "self.canvas.drawBox(), with the same result. If I delete the drawBox function and just put the statements in "init", with no function call, it works correctly. I thought that by calling "self.canvas.drawBox()", I pass "self.canvas"
    to the function, so that in effect I am calling
    "newbox=self.canvas.create_rectangle(self.x, self.y, self.x+70,
    self.y+70, width=5, fill='red')". Clearly this is inaccurate because if I write "newbox=self.create_rectangle(self.x, self.y, self.x+70, self.y+70, width=5, fill='red')" in the constructor, it works correctly. Where am I thinking about this incorrectly?


    Next, I am trying to bind an object or objects on the screen so that the user can click a button and set the latest object clicked (a ball, square, triangle, whatever) in motion. To do this I need to identify the latest object clicked on the canvas. Ive written the following function:

    Code:
        def onClick(self,event):
            self.currx = event.x
            self.curry = event.y
            self.latest= event.widget
            
            self.move(self.latest, 10, 10)
    For now, I've just set it up so that when a user clicks on the object it moves 10X10 pixels. Here is the function for adding a
    ball with this binding:
    Code:
    def drawBall(self,x=WINDOWWIDTH/4, y=WINDOWWIDTH/4, size=40, **kw):
            newball=self.create_oval(x-30, y-30, x+30, y+30, width=5, fill='black')
            self.tag_bind(newball, '<B1-Motion>', self.onDrag)
            self.tag_bind(newball, '<ButtonPress-1>', self.onClick)
    I create the ball by calling:

    Code:
    app.drawBall(70,70,70,width=5, fill='black')
    So when I click on an object, the object should be set as "self.latest", and then moved 10X10 pixels in the next line. When I run this, though, there is no movement. If I leave the rest of the code the same and change the move code to:

    Code:
    self.move(ALL, 10, 10)
    all the objects are moved. So it seems that the problem has to do with setting self.latest as the current object. When I insert a print statement to output "self.latest", it prints an object ID of a bunch of numbers, so I'm at a loss as to why the object does not move.

    Again, thanks for any help.

    Luke

  2. #2
    Join Date
    Sep 2008
    Beans
    51

    Re: Graphics/classes in Tkinter

    Bump?

  3. #3
    Join Date
    Jan 2008
    Location
    Raytown, MO
    Beans
    460
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Graphics/classes in Tkinter

    The Tcler's Wiki http://wiki.tcl.tk Tcl Developer Exchange http://www.tcl.tk SQLite http://www.sqlite.org

  4. #4
    Join Date
    Mar 2005
    Beans
    947
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Graphics/classes in Tkinter

    drawBox() is not a method of self.canvas, and it doesn't become one just by trying to call it as "self.canvas.drawBox()". You could either refer to self.canvas within drawBox(), or pass it as a parameter.

  5. #5
    Join Date
    Jan 2008
    Location
    Raytown, MO
    Beans
    460
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Graphics/classes in Tkinter

    After finding a little time, a "brain-dead" simple script to move items on a canvas :

    Code:
    #!/usr/bin/python
    
    from Tkinter import *
    
    root = Tk()
    
    root.title("Move it!")
    
    root.resizable(0,0)
    
    def callback(event):
    	c.move(CURRENT, 10, 10)
    	
    
    c = Canvas(root, bg="white", width=200, height=200)
    
    ball = c.create_oval(10, 10, 50, 50, fill="blue", tags="movable")
    
    box = c.create_rectangle(50, 50, 75, 75, fill="red", tags="movable")
    
    c.bind("<Button-1>", callback)
    
    c.pack()
    
    print c.gettags(ALL)
    
    print c.coords(ball)
    
    print c.coords(box)
    
    root.mainloop()
    Note the use of CURRENT.

    Hope this helps.

    Steve
    The Tcler's Wiki http://wiki.tcl.tk Tcl Developer Exchange http://www.tcl.tk SQLite http://www.sqlite.org

  6. #6
    Join Date
    Sep 2008
    Beans
    51

    Re: Graphics/classes in Tkinter

    Thanks guys, this is very helpful.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •