0

I am trying to make a Python Tkinter program display a circle and move the circle right when I press Return/Enter. My code is currently:

from Tkinter import *
class GUI(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.setupStuff()
    def setupStuff(self):
        self.canvas = Canvas(self, height=500, width=600)
        self.canvas.pack()
        self.blueCircle = self.canvas.create_oval(10, 10, 40, 40, fill='dodger blue')
        self.canvas.bind('<Return>', self.moveRight)
    def moveRight(self):
        print 'Yo',
        self.canvas.move(self.blueCircle, 1, 0)
        print 'yo'
if __name__ == '__main__':
    window = GUI(Tk())
    window.mainloop()

My problem is that the ball doesn't move when I press Return/Enter.

  • Key events are only delivered to the widget that currently has the keyboard focus. You can call `.focus_set()` to give focus to your canvas, but it would probably be easier to do your event binding on the root window itself, instead of the canvas. – jasonharper Apr 20 '17 at 04:15

2 Answers2

0

You need to focus the tkinter canvas with the .focus_force() method if you want the widget to receive events, as only the focused widget can receive events. Also, when the your keypress handler is called, it passes an argument containing data about the event, so you need to add an argument to moveRight or you will get a TypeError.

from Tkinter import *
class GUI(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.setupStuff()
        self.canvas.focus_force()     #force the canvas to take focus

    def setupStuff(self):
        self.canvas = Canvas(self, height=500, width=600)
        self.canvas.pack()
        self.blueCircle = self.canvas.create_oval(10, 10, 40, 40, fill='dodger blue')
        self.canvas.bind('<Return>', self.moveRight)

    def moveRight(self, eventData):    #.bind passes an argument
        self.canvas.move(self.blueCircle, 1, 0)

if __name__ == '__main__':
    window = GUI(Tk())
    window.mainloop()
Alex Boxall
  • 541
  • 5
  • 13
  • 1
    The wording of this answer is a little off. You don't need focus in order to bind events to the canvas. You only need focus for the events to be passed to the bound function later. – Bryan Oakley Apr 20 '17 at 10:40
0

You may bind your keys to root which is self.master in your case instead of binding it to canvas. Please see the modified working code below.As @Alex has specified, bind returns an event

from Tkinter import *
class GUI(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.setupStuff()

   def setupStuff(self):
        self.canvas = Canvas(self, height=500, width=600)
        self.canvas.pack()
        self.blueCircle = self.canvas.create_oval(10, 10, 40, 40, fill='dodger blue')
        #self.canvas.bind('<Return>',self.moveRight)
        self.master.bind('<Return>', self.moveRight)

   def moveRight(self, event = None):
        print 'Yo',
        self.canvas.move(self.blueCircle, 200, 0)
        print 'yo'
if __name__ == '__main__':
   root = Tk()
   window = GUI(root)
   window.mainloop()
DineshKumar
  • 1,599
  • 2
  • 16
  • 30