Passing a tkinter canvas between classes without calling the child from within the parent Passing a tkinter canvas between classes without calling the child from within the parent tkinter tkinter

Passing a tkinter canvas between classes without calling the child from within the parent


You're passing it ok, but you're throwing the value away. Also, Hero shouldn’t inherit from mainWindow.

You need to save world as an attribute so that you can reference it later.

class Hero():    def __init__(self,world):        self.world = world        ...

Then, you can use self.world to reference the canvas:

def moveHeroBody():    print("moveHeroBody")    self.world.delete(heroBody)

Though, the above code will fail because heroBody is a variable local to the __init__ - you need to do the same with it:

class Hero():    def __init__(self,world):        self.world = world        ...        self.heroBody = world.create_oval(...)    #Move the hero    def moveHeroBody():        print("moveHeroBody")        self.world.delete(self.heroBody)


I think you need to initialize the class Hero in your mainWindow class. The modifications needed to do in the code are:

classes.py

from tkinter import *from time import sleepclass mainWindow():    def __init__(self):            #Setup the GUI            self.jump_gap = 25            root = Tk()            root.geometry('800x600')            # Setup the canvas within the GUI (master)            self.world = Canvas(root, height = 600, width = 800, bg = "#FFFFFF")            self.world.place(relx = 0.5, rely = 0.5, anchor = CENTER)            self.hero = Hero(self.world)            self.world.pack()            root.bind("<space>",self.jump) # -> [1] Binds the SPACE BAR Key to the function jump             root.mainloop()    def jump(self,event):        gaps = list(range(self.jump_gap))        for i in gaps:            self.world.after(1,self.hero.moveHeroJump(h=i))  # [2] -> Binds the moveHeroJump method with the window action to a queue of updates            self.world.update() #[2] updates the canvas            sleep(0.01*i) # Added some linear wait time to add some look to it        gaps.reverse()        for i in gaps:            self.world.after(1,self.hero.moveHeroJump(h=-i))            self.world.update()            sleep(0.01*i)class Hero():    def __init__(self,world):        #Initial creation of hero at coordinates        self.world = world        self.x1 = 10        self.y1 = 410        self.x2 = 70        self.y2 = 470        self.heroBody = self.world.create_oval(self.x1,self.y1,self.x2,self.y2, fill = "#FF0000", outline = "#FF0000")    #Move the hero    def moveHeroJump(self,h):        print("moveHeroBody")        self.y1 -= h        self.y2 -= h        self.world.delete(self.heroBody)        self.heroBody = self.world.create_oval(self.x1,self.y1,self.x2,self.y2, fill = "#FF0000", outline = "#FF0000")

physics.py

from tkinter import *from classes import *mainWindow1 = mainWindow()

Please let me know if this worked! :D

Edit

So this got me playing some minutes ago, and I researched some sources from stack in order to complete this question. Here are the sources (referenced in the code as well):

  1. How to bind spacebar key to a certain method in tkinter python
  2. Moving Tkinter Canvas

The solution edited above is capable to perform a simple animation of a ball jumping. self.jump_gap is a fixed quantity that tells the ball how much does it needs to jump. The jump parses a certain height h to the moveHeroJump method to make the ball change its position, after the change of position is queued into the Canvas an update is called to see the changes on the ball.

Please let me know if this helped, I had a lot of fun playing with this!