Pages

Se afișează postările cu eticheta sys. Afișați toate postările
Se afișează postările cu eticheta sys. Afișați toate postările

duminică, 17 mai 2026

PyGame : simple example python script to toggle fullscreen mode.

Simple example with pygame window to switch on fullscren.
The program starts by initializing Pygame and creating a 640×480 window. It also prepares a font and draws a button on the screen that will be used to toggle fullscreen mode. A variable keeps track of whether the program is currently in fullscreen or windowed mode.
Inside the main loop, the program listens for events. If the user clicks the button or presses the F12 key, the program switches between fullscreen and windowed display modes by recreating the Pygame window with the appropriate settings.
Every frame, the screen is cleared, the button is drawn, and the instruction text "use button or F12 key to switch on fullscreen" is displayed.
The window updates continuously at 60 FPS, so the fullscreen toggle feels instant and smooth.
Let's see the source code.
import pygame
import sys

pygame.init()

# Dimensiuni fereastră
WIDTH, HEIGHT = 640, 480
windowed_size = (WIDTH, HEIGHT)

# Moduri de afișare
screen = pygame.display.set_mode(windowed_size)
pygame.display.set_caption("Fullscreen Toggle Example")

# Font
font = pygame.font.SysFont("Arial", 22)

# Buton fullscreen
button_rect = pygame.Rect(20, 20, 200, 50)

# Stare fullscreen
is_fullscreen = False


def toggle_fullscreen():
    global screen, is_fullscreen

    is_fullscreen = not is_fullscreen

    if is_fullscreen:
        screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
    else:
        screen = pygame.display.set_mode(windowed_size)


# Loop principal
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # Click pe buton
        if event.type == pygame.MOUSEBUTTONDOWN:
            if button_rect.collidepoint(event.pos):
                toggle_fullscreen()

        # Tasta F12
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_F12:
                toggle_fullscreen()

    # Fundal
    screen.fill((30, 30, 30))

    # Desenare buton
    pygame.draw.rect(screen, (70, 130, 180), button_rect)
    btn_text = font.render("Toggle Fullscreen", True, (255, 255, 255))
    screen.blit(btn_text, (button_rect.x + 10, button_rect.y + 12))

    # Text instrucțiuni
    info_text = font.render("use button or F12 key to switch on fullscreen", True, (255, 255, 0))
    screen.blit(info_text, (20, HEIGHT - 40))

    pygame.display.flip()
    clock.tick(60)

luni, 13 aprilie 2026

Python-CE : How to fix DPI pygame‑ce on Python 3.13.0 and test your DPI monitors.

Today, I tried the high-DPI displays, and because I have Python 3.13.0, some features are not supported, but I fixed them.
This script is specifically designed for:
  • Python 3.13
  • pygame‑ce 2.5.7
  • SDL 2.32.x (bundled inside pygame‑ce)
These versions have incomplete DPI support in the Python bindings.
Many DPI‑related functions that exist in SDL2 are not exposed in pygame‑ce for Python 3.13.
Examples of missing functions in your build:
  • Window.drawable_size
  • Window.from_display_surface
  • Renderer.get_output_size
  • pygame.display.get_window()
Because these functions are missing, PyGame-CE cannot read DPI information directly.
I adopted the ctypes solution because ctypes allows Python to call native Windows API functions directly.
I used these native Windows API:
  • EnumDisplayMonitors → to list all monitors
  • GetDpiForMonitor → to read DPI for each monitor
  • SetProcessDpiAwareness → to enable DPI awareness
This bypasses pygame‑ce completely and talks directly to Windows, but pygame-ce can be used only for window creation and drawing.
ctypes is the only reliable way to get real DPI values on your current setup.
The script creates two independent SDL2 windows.
Drag each window to a different monitor.
Each window will show different DPI values.
You can compare scaling visually and numerically.
This script is designed for Python 3.13 + pygame‑ce 2.5.7, where DPI functions are missing.
I use ctypes to call Windows DPI APIs directly because pygame‑ce cannot access DPI.
The script creates two windows, each showing DPI and visual scaling tests.
With one monitor, both windows show the same DPI.
With multiple monitors, each window shows the DPI of its monitor.
This is the most advanced DPI test possible on your current setup.
I have only one monitor, and the result is the same.
Let's see the result:
Let's see the script:
import pygame
import pygame._sdl2 as sdl2
import ctypes
import sys

pygame.init()

# Windows DPI API
user32 = ctypes.windll.user32
shcore = ctypes.windll.shcore

# Enable per-monitor DPI awareness
try:
    shcore.SetProcessDpiAwareness(2)
except:
    pass

# --- Monitor enumeration ---
MONITORS = []

def _monitor_enum_proc(hmonitor, hdc, lprcMonitor, lparam):
    MONITORS.append(hmonitor)
    return 1

MonitorEnumProc = ctypes.WINFUNCTYPE(
    ctypes.c_int,
    ctypes.c_ulong,
    ctypes.c_ulong,
    ctypes.POINTER(ctypes.c_int * 4),
    ctypes.c_double
)

user32.EnumDisplayMonitors(0, 0, MonitorEnumProc(_monitor_enum_proc), 0)

def get_monitor_dpi(index):
    if index >= len(MONITORS):
        index = 0  # fallback for single-monitor setups

    dpi_x = ctypes.c_uint()
    dpi_y = ctypes.c_uint()

    shcore.GetDpiForMonitor(MONITORS[index], 0, ctypes.byref(dpi_x), ctypes.byref(dpi_y))
    return dpi_x.value, dpi_y.value


# --- Create two SDL2 windows ---
window1 = sdl2.Window("Make test on first monitor", size=(600, 400), position=(100, 100))
window2 = sdl2.Window("Make test on second monitor", size=(600, 400), position=(800, 100))

surface1 = window1.get_surface()
surface2 = window2.get_surface()

font = pygame.font.SysFont("Arial", 22)
clock = pygame.time.Clock()

# --- Drawing helpers ---
def draw_grid(surface, spacing=20):
    w, h = surface.get_size()
    for x in range(0, w, spacing):
        pygame.draw.line(surface, (60, 60, 60), (x, 0), (x, h))
    for y in range(0, h, spacing):
        pygame.draw.line(surface, (60, 60, 60), (0, y), (w, y))

def draw_square_test(surface, dpi_scale):
    size = int(50 * dpi_scale)
    pygame.draw.rect(surface, (200, 50, 50), (20, 200, size, size), 2)

# --- Main loop ---
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    dpi0 = get_monitor_dpi(0)
    dpi1 = get_monitor_dpi(1)

    scale0 = dpi0[0] / 96
    scale1 = dpi1[0] / 96

    # --- Window 1 ---
    surface1.fill((25, 25, 25))
    draw_grid(surface1)
    draw_square_test(surface1, scale0)

    y = 20
    for line in [
        "Advanced DPI Test",
        f"Monitor index: 0",
        f"DPI X: {dpi0[0]}",
        f"DPI Y: {dpi0[1]}",
        f"Scale factor: {scale0:.2f}x",
        "Red square = 50px scaled",
        "Grid = 20px spacing"
    ]:
        surf = font.render(line, True, (255, 255, 255))
        surface1.blit(surf, (20, y))
        y += 28

    window1.flip()

    # --- Window 2 ---
    surface2.fill((25, 25, 25))
    draw_grid(surface2)
    draw_square_test(surface2, scale1)

    y = 20
    for line in [
        "Advanced DPI Test",
        f"Monitor index: 1",
        f"DPI X: {dpi1[0]}",
        f"DPI Y: {dpi1[1]}",
        f"Scale factor: {scale1:.2f}x",
        "Red square = 50px scaled",
        "Grid = 20px spacing"
    ]:
        surf = font.render(line, True, (255, 255, 255))
        surface2.blit(surf, (20, y))
        y += 28

    window2.flip()

    clock.tick(60)