Change display orientation with pygame

Viewed 201
import sys
import pygame
import pygame.locals as pgl


class Test:
    def __init__(self):
        pygame.init()
        self.flags = pygame.FULLSCREEN | pygame.NOFRAME | pygame.VIDEORESIZE
        self.surface = pygame.display.set_mode((0, 0), self.flags, 0, 0)
        self.width, self.height = self.surface.get_size()
        self.bgcolor = (255, 255, 255)
        print(f'INIT => VIDEO SIZE: {self.width}, {self.height}')

    def __del__(self):
        pygame.display.quit()

    def process_events(self):
        for event in pygame.event.get():
            self.handle_event(event)

    def handle_event(self, event):
        if event.type == pgl.KEYDOWN:
            if event.key == pgl.K_ESCAPE:
                self.running = False
                pygame.quit()
                sys.exit(0)
        elif (event.type == pgl.VIDEORESIZE):
            print(f'HANDLE EVENT => VIDEO RESIZE: {event.w}, {event.h}')
            self.width, self.height = self.height, self.width
            #self.surface = pygame.display.set_mode((self.width, self.height), self.flags, 0, 0)
            self.surface = pygame.display.set_mode((0, 0), self.flags, 0, 0)
            self.width, self.height = self.surface.get_size()
            print(f'HANDLE EVENT => NEW SIZE: {self.width}, {self.height}')
            self.orientation_changed()

    def orientation_changed(self):
        # do something here
        pass

    def draw(self):
        r = pygame.Rect(0, 0, self.width, self.height)
        pygame.draw.rect(self.surface, self.bgcolor, r)
        pygame.display.update()

    def run(self):
        self.running = True

        while self.running:

            self.process_events()
            self.draw()


test = Test()
test.run()

Running this code I have:

INIT => VIDEO SIZE: 1366, 768
HANDLE EVENT => VIDEO RESIZE: 768, 1332
HANDLE EVENT => NEW SIZE: 1366, 768
HANDLE EVENT => VIDEO RESIZE: 1366, 734
HANDLE EVENT => NEW SIZE: 1366, 768

This show the display height with a wrong size.

And the white background do not cover all the screen size when I rotate the device.

Now, when I uncomment the line 31 and comment line 32, I get an error:

INIT => VIDEO SIZE: 1366, 768
HANDLE EVENT => VIDEO RESIZE: 768, 1332
Traceback (most recent call last):
  File "/home/dev/test/python/test.py", line 56, in <module>
    test.run()
  File "/home/dev/test/python/test.py", line 51, in run
    self.process_events()
  File "/home/dev/test/python/test.py", line 20, in process_events
    self.handle_event(event)
  File "/home/dev/test/python/test.py", line 31, in handle_event
    self.surface = pygame.display.set_mode((self.width, self.height), self.flags, 0, 0)
pygame.error: No video mode large enough for 768x1366

Someone has an idea why the display is not changing its orientation and why create another with the right size gives an error.

Thanks for your help.

1 Answers

I think because pygame already has a window initialized it will not be able to resize the window.

pygame wiki about this: https://www.pygame.org/wiki/WindowResizing

In Pygame 2 In pygame 2 the display surface is automatically resized when the window is - set_mode() should not be called. The VIDEORESIZE event instead lets us handle any other surfaces, or anything else, we might want to resize. Example:

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((500, 500), RESIZABLE)
pic = pygame.image.load("example.png")  # You need an example picture in the same folder as this file!
running = True
while running:
    pygame.event.pump()
    event = pygame.event.wait()
    if event.type == QUIT:
        running = False
    elif event.type == VIDEORESIZE:
        screen.blit(pygame.transform.scale(pic, event.dict['size']), (0, 0))
        pygame.display.update()
    elif event.type == VIDEOEXPOSE:  # handles window minimising/maximising
        screen.fill((0, 0, 0))
        screen.blit(pygame.transform.scale(pic, screen.get_size()), (0, 0))
        pygame.display.update()

So I think the only way of getting around this, is by closing and re-opening the window, or by using a different surface which will not help as well.

Or if I didnt understand your question or my answer is wrong: I think it may be this in your code:

self.width, self.height = self.height, self.width

I think you want this to be:

self.width, self.height = event.w, event.h
Related