title: How to get Pillow images into Tkinter dynamically
body: <p>From what I've read, <code>ImageTk</code> should convert a Pillow image into a format that Tkinter can display. (Indeed, when I don't, Tkinter fails with an error.) However, when I run this program on my Windows computer, the Tkinter box says it's not responding and does not display the images.</p>
  
  <pre><code>from PIL import Image, ImageDraw
  
  class Block:
      def __init__(self, x=30, y=10, speed=None, size=2.5):
          self.x = x
          self.y = y
          self.size = size # radius
  
          if speed is None:
              speed = self.size * 2
  
          self.speed = speed
  
      def draw(self, image):
          width, height = image.size
          drawer = ImageDraw.Draw(image)
          drawer.rectangle(((self.x - self.size, height - (self.y - self.size)), (self.x + self.size, height - (self.y + self.size))), fill="white")
  
  
  class BallDodge():
      def __init__(self):
          self.width = 400
          self.height = 300
          self.main_player = Block(self.width // 2)
          self.balls = []
          self.frame = 0
          self.frames_between_balls = 20
          self.frames_since_last_ball = self.frames_between_balls
          self.input_function = self.get_human_input
          self.states = []
  
  
      @property
      def state(self):
          ans = Image.new('RGBA', (self.width, self.height), "black")
          self.main_player.draw(ans)
  
          return ans
  
      def get_human_input(self, *args, **kwargs):
          try:
              ans = int(input("1, 2, 3, or 4:"))
              if ans &gt; 4:
                  raise ValueError("Can't be greater than 4")
              elif ans &lt; 1:
                  raise ValueError("Can't be less than 1")
              if ans == 1:
                  return [1, 0]
              elif ans == 2:
                  return [0, 0]
              elif ans == 3:
                  return [0, 1]
              elif ans == 4:
                  return [1, 1]
              else:
                  raise ValueError("Somehow it's not one of the specified numbers. You are magical.")
          except Exception as e:
              print("Invalid input")
              print(e)
              return self.get_human_input()
  
      def step(self):
          inpt = self.input_function(self.state)
          directions = [-1, 1]
          for i in range(2):
              self.main_player.x += directions[i] * inpt[i]
  
          self.states.append(self.state)
  
  if __name__ == "__main__":
      game = BallDodge()
      import tkinter as tk
      from PIL import ImageTk, Image
      root = tk.Tk()
      my_image = ImageTk.PhotoImage(game.state)
      game.state.show()
      while True:
          panel = tk.Label(image = ImageTk.PhotoImage(game.state), master = root)
          panel.pack()
          # panel = Label(root, image = ImageTk.PhotoImage(game.state))
          # panel.pack(side = "bottom", fill = "both", expand = "yes")
          root.update_idletasks()
          root.update()
          game.step()
  </code></pre>
  
  <p>Things I've noticed:
  If I do <code>game.state.show()</code> it will open up the image just fine, so there's definitely an image there.
  If I do hit one of the number keys to advance to the next frame, the Tkinter window gets twice as tall, but still displays nothing.</p>
  
  <p>How can I get a loop such that I can display a Pillow image in a Tkinter window, get user input, and then display a new image?</p>