12

I am working on a project in python, and I made a method to draw a specific thing in tkinter. I want it so that whenever I press the spacebar, the image will redraw itself (run the method again because I coded the method so that it could redraw over itself). How exactly would I bind the spacebar to the method so that the program would run, draw, and re-draw if I pressed the spacebar?

for example, i want it so that whenever I press space, the program draws in a random location on the canvas:

from Tkinter import *
from random import *

root=Tk()
canvas=Canvas(root,width=400,height=300,bg='white')
def draw():
    canvas.delete(ALL)# clear canvas first
    canvas.create_oval(randint(0,399),randint(0,299),15,15,fill='red')
draw()
canvas.pack()
root.mainloop()

how would i bind the spacebar to the method?

3 Answers3

21
from Tkinter import *
from random import *

root=Tk()
canvas=Canvas(root,width=400,height=300,bg='white')
def draw(event=None):
    canvas.delete(ALL)# clear canvas first
    canvas.create_oval(randint(0,399),randint(0,299),15,15,fill='red')
draw()
canvas.pack()

root.bind("<space>", draw)
root.mainloop()
twasbrillig
  • 17,084
  • 9
  • 43
  • 67
  • thank you so much! I looked at other questions but couldn't find something similar to what I needed. I guess adding the event=None was important. –  Apr 02 '13 at 00:14
  • glad to help. yeah, the callback function is called by Tkinter with a parameter, so it needs something to be passed in. And by setting it to None you can call it in line 9 without passing anything in. – twasbrillig Apr 02 '13 at 11:03
1

You could do something like this:

from Tkinter import *
from random import *

root=Tk()
canvas=Canvas(root,width=400,height=300,bg='white')

def draw(event):
    if event.char == ' ':
        canvas.delete(ALL)# clear canvas first
        canvas.create_oval(randint(0,399),randint(0,299),15,15,fill='red')

root.bind('<Key>', draw)

canvas.pack()
root.mainloop()

Basically, you bind your drawing function to some top-level element to the <Key> binding which is triggered whenever a key on the keyboard is pressed. Then, the event object that's passed in has a char member which contains a string representing the key that was pressed on the keyboard.

The event will only be triggered when the object it's bound to has focus, which is why I'm binding the draw method to the root object, since that'll always be in focus.

Michael0x2a
  • 58,192
  • 30
  • 175
  • 224
  • 1
    why would you choose to bind on `` rather than ``? It looks like you're making more work for yourself – Bryan Oakley Apr 02 '13 at 10:55
  • 1
    @BryanOakley Yeah, I didn't realize that `` existed until after I saw the other answer. I'm leaving my answer up in case it's useful, but I upvoted the other answer. – Michael0x2a Apr 02 '13 at 14:24
1

You can aslo use canvas.bind_all("<space>", yourFunction) That will listen for events in the whole application and not only on widget.

Alpacah
  • 39
  • 8