Pygame won’t render rect at mouse position?

I wrote this simple code, to spawn a rect at the mouse position when the mouse button is clicked. But it wont render the rect for some reason. It prints “mouse” when clicked, but no rect!

import pygame
from pygame.locals import *


WHITE = (255,255,255)

while True:

    pygame.init()

    DISPLAY = pygame.display.set_mode((400,400))

    for event in pygame.event.get():

        if event.type == QUIT:
            pygame.quit()
        
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            pygame.quit()

        if event.type == MOUSEBUTTONDOWN:
            pygame.draw.rect(DISPLAY,WHITE,(pygame.mouse.get_pos()[0],pygame.mouse.get_pos()[1],20,20))
            print('mouse')

 

    pygame.display.update()

Any kind of help is much appreciated!

Answer

You must initialize pygame (pygame.init()) and create the display surface (pygame.display.set_mode()) before the application loop.

import pygame
from pygame.locals import *

pygame.init()
DISPLAY = pygame.display.set_mode((400,400))
WHITE = (255,255,255)

run = True
while run:
    for event in pygame.event.get():
        if event.type == QUIT:
            run = False
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            run = False

        if event.type == MOUSEBUTTONDOWN:
            print('mouse')
            pygame.draw.rect(DISPLAY, WHITE, (*event.pos, 20, 20))
        
    pygame.display.update()

pygame.quit()
exit()

However, the typical PyGame application loop has to:

Redraw the scene is every frame. The event occurs just once when the mouse button is clicked. Add the mouse click positions to a list and draw the rectangles in the application loop, at the positions stored in the list:

import pygame
from pygame.locals import *

pygame.init()
DISPLAY = pygame.display.set_mode((400,400))
WHITE = (255,255,255)
clock = pygame.time.Clock()
pos_list = []

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == QUIT:
            run = False
        if event.type == KEYDOWN and event.key == K_ESCAPE:
            run = False

        if event.type == MOUSEBUTTONDOWN:
            print('mouse')
            pos_list.append(event.pos)

    DISPLAY.fill(0)
    for pos in pos_list:
        pygame.draw.rect(DISPLAY, WHITE, (*pos, 20, 20))
    pygame.display.update()

pygame.quit()
exit()