title: pygame window won't close when clicking quitbuttons or the red X at top
body: <p>I use a system like this which should theoretically work to close the window:</p>
  <pre><code>while running:
      pygame.display.flip()
      for event in pygame.event.get():
          if event.type == pygame.QUIT:
              running = False
  </code></pre>
  <p>Here is the code:</p>
  <pre><code>import pygame
  
  import random
  import sys
  
  # Set width and height of window
  (width, height) = (400, 600)
  
  # Sets the colours
  background_colour = (0, 2, 20)
  white = (255, 255, 255)
  
  # creates window
  screen = pygame.display.set_mode((width, height))
  pygame.display.set_caption(&quot;Space Dodger&quot;)
  
  screen.fill(background_colour)
  
  
  def gameLoop():
      # sets sprite starting coordinates
      rocketX = 200
      rocketY = 450
  
      leftX = 0
      leftY = -25
      leftWidth = random.randint(0, 300)
  
      # sets obstacle start speed
      obstacleSpeed = 1
  
      # sets starting score
      score = 0
      pygame.init()
      font = pygame.font.Font(&quot;Pixeled.ttf&quot;, 32)
      fontSmall = pygame.font.Font(&quot;Pixeled.ttf&quot;, 25)
  
      scoreX = 10
      scoreY = 10
  
      # All images/sprites
      # rocket
      rocket = pygame.image.load(&quot;rocket.png&quot;)
      rocket = pygame.transform.smoothscale(rocket, (50, 100))
  
      # background image
      backgroundSpace = pygame.image.load(&quot;spacesky.png&quot;)
      backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
      backgroundColour = (10, 32, 61)
  
      running = True
      while running:
          pygame.display.flip()
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  running = False
  
          # sets rectangles for obstacles
          leftObstacle = pygame.draw.rect(screen, white, pygame.Rect(leftX, leftY, leftWidth, 25))
          rightObstacle = pygame.draw.rect(
              screen, white, pygame.Rect(leftWidth + 100, leftY, width, 25)
          )
          rocketRec = pygame.draw.rect(
              screen, backgroundColour, pygame.Rect(rocketX + 10, rocketY, 30, 75)
          )
  
          # sets score text
          displayScore = font.render(str(score), True, (105, 105, 105))
  
          # makes cursor invisible
          pygame.mouse.set_visible(False)
  
          # draws new layer over screen
          screen.blit(backgroundSpace, (0, 0))
  
          # tracks the mosue location
          mouseX, mouseY = pygame.mouse.get_pos()
  
          # draws rectangle behind rocket
          pygame.draw.rect(screen, backgroundColour, rocketRec)
  
          # displays the rocket
          screen.blit(rocket, (rocketX, rocketY))
  
          # sets rocket horizontal position
          if mouseX &gt; width - 50:
              rocketX = width - 50
          else:
              rocketX = mouseX
  
          # displays the score
          screen.blit(displayScore, (scoreX, scoreY))
  
          # creates the moving obstacles
          pygame.draw.rect(screen, white, leftObstacle)
          pygame.draw.rect(screen, white, rightObstacle)
  
          leftY = leftY + obstacleSpeed
  
          # brings obstacle back to top
          if leftY &gt; 600:
              leftY = -25
              leftWidth = random.randint(0, 300)
              score = score + 1
              if obstacleSpeed &gt;= 6:
                  obstacleSpeed = 6
              else:
                  obstacleSpeed = obstacleSpeed + 0.2
  
          if rocketRec.colliderect(leftObstacle) or rocketRec.colliderect(rightObstacle):
              collisionScreen()
  
  
  def startScreen():
      lightGrey = (200, 200, 200)
      darkGrey = (165, 165, 165)
      lightGrey2 = (200, 200, 200)
      darkGrey2 = (165, 165, 165)
  
      # background image
      backgroundSpace = pygame.image.load(&quot;spacesky.png&quot;)
      backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
      backgroundColour = (10, 32, 61)
  
      pygame.init()
      fontSmall = pygame.font.Font(&quot;Pixeled.ttf&quot;, 25)
  
      running = True
      while running:
          pygame.display.flip()
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  running = False
  
          # start screen
  
          # makes cursor visible
          pygame.mouse.set_visible(True)
  
          # tracks the mosue location
          mouseX, mouseY = pygame.mouse.get_pos()
  
          # draws new layer over screen
          screen.blit(backgroundSpace, (0, 0))
  
          # Puts on logo
          logo = pygame.image.load(&quot;name.png&quot;)
          logo = pygame.transform.smoothscale(logo, (500, 300))
          screen.blit(logo, (-40, 10))
  
          # creates start button
          startRecU = pygame.draw.rect(screen, darkGrey, pygame.Rect(120, 270, 160, 60))
          startRec = pygame.draw.rect(screen, lightGrey, pygame.Rect(125, 275, 150, 50))
          startText = fontSmall.render(&quot;START&quot;, True, (0, 0, 0))
          # displays the start text
          screen.blit(startText, (135, 262))
  
          # detects if mouse is hovering over button
          if 280 &gt; mouseX &gt; 120 and 330 &gt; mouseY &gt; 270:
              darkGrey = (200, 200, 200)
              lightGrey = (165, 165, 165)
          else:
              lightGrey = (200, 200, 200)
              darkGrey = (165, 165, 165)
  
          # detects if start button is clicked
          for event in pygame.event.get():
              if event.type == pygame.MOUSEBUTTONDOWN and 280 &gt; mouseX &gt; 120 and 330 &gt; mouseY &gt; 270:
                  gameLoop()
  
          # creates quit button
          quitRecU = pygame.draw.rect(screen, darkGrey2, pygame.Rect(120, 350, 160, 60))
          quitRec = pygame.draw.rect(screen, lightGrey2, pygame.Rect(125, 355, 150, 50))
          quitText = fontSmall.render(&quot;QUIT&quot;, True, (0, 0, 0))
          # displays the start text
          screen.blit(quitText, (156, 340))
  
          # detects if mouse is hovering over button
          if 280 &gt; mouseX &gt; 120 and 410 &gt; mouseY &gt; 350:
              darkGrey2 = (200, 200, 200)
              lightGrey2 = (165, 165, 165)
          else:
              lightGrey2 = (200, 200, 200)
              darkGrey2 = (165, 165, 165)
  
          # detects if quit button is clicked
          for event in pygame.event.get():
              if event.type == pygame.MOUSEBUTTONDOWN and 280 &gt; mouseX &gt; 120 and 410 &gt; mouseY &gt; 350:
                  running = False
  
  
  def collisionScreen():
      lightGrey = (200, 200, 200)
  
      darkGrey = (165, 165, 165)
      lightGrey2 = (200, 200, 200)
      darkGrey2 = (165, 165, 165)
  
      # background image
      backgroundSpace = pygame.image.load(&quot;spacesky.png&quot;)
      backgroundSpace = pygame.transform.rotate(backgroundSpace, 90)
      backgroundColour = (10, 32, 61)
  
      # explosion
      explosion = pygame.image.load(&quot;explosion.png&quot;)
      explosion = pygame.transform.smoothscale(explosion, (100, 100))
  
      pygame.init()
      fontSmall = pygame.font.Font(&quot;Pixeled.ttf&quot;, 25)
      fontMini = pygame.font.Font(&quot;Pixeled.ttf&quot;, 15)
  
      running = True
      while running:
          pygame.display.flip()
          for event in pygame.event.get():
              if event.type == pygame.QUIT:
                  running = False
  
          # draws new layer over screen
          screen.blit(backgroundSpace, (0, 0))
  
          # makes cursor visible
          pygame.mouse.set_visible(True)
  
          # tracks the mosue location
          mouseX, mouseY = pygame.mouse.get_pos()
  
          # displays the explosion
          screen.blit(explosion, (150, 400))
  
          # creates play again button
          playAgainRecU = pygame.draw.rect(screen, darkGrey, pygame.Rect(120, 270, 160, 60))
          playAgainRec = pygame.draw.rect(screen, lightGrey, pygame.Rect(125, 275, 150, 50))
          playAgainText = fontMini.render(&quot;PLAY AGAIN&quot;, True, (0, 0, 0))
          # displays the start text
          screen.blit(playAgainText, (135, 278))
  
          # detects if mouse is hovering over button
          if 280 &gt; mouseX &gt; 120 and 330 &gt; mouseY &gt; 270:
              darkGrey = (200, 200, 200)
              lightGrey = (165, 165, 165)
          else:
              lightGrey = (200, 200, 200)
              darkGrey = (165, 165, 165)
  
          # detects if play button is clicked
          for event in pygame.event.get():
              if event.type == pygame.MOUSEBUTTONDOWN and 280 &gt; mouseX &gt; 120 and 330 &gt; mouseY &gt; 270:
                  gameLoop()
  
          # creates quit button
          quit2RecU = pygame.draw.rect(screen, darkGrey2, pygame.Rect(120, 350, 160, 60))
          quit2Rec = pygame.draw.rect(screen, lightGrey2, pygame.Rect(125, 355, 150, 50))
          quit2Text = fontSmall.render(&quot;QUIT&quot;, True, (0, 0, 0))
          # displays the start text
          screen.blit(quit2Text, (156, 340))
  
          # detects if mouse is hovering over button
          if 280 &gt; mouseX &gt; 120 and 410 &gt; mouseY &gt; 350:
              darkGrey2 = (200, 200, 200)
              lightGrey2 = (165, 165, 165)
          else:
              lightGrey2 = (200, 200, 200)
              darkGrey2 = (165, 165, 165)
  
          # detects if quit button is clicked
          for event in pygame.event.get():
              if event.type == pygame.MOUSEBUTTONDOWN and 280 &gt; mouseX &gt; 120 and 410 &gt; mouseY &gt; 350:
                  for event in pygame.event.get():
                      if event.type == pygame.QUIT:
                          running = False
  
  
  startScreen()
  </code></pre>