I'm making a firework simulation in pygame, and I want to be able to run the program, and have it open up in full screen. Not the pygame.FULLSCREEN, I still want to be able to use pygame.QUIT.
I don't know if this is possible, but if anyone could help, please share your ideas!
Here's my code for the screen:
import pygame
screen = pygame.display.set_mode((0, 0), pygame.RESIZABLE)
You could use the width and height of the screen to setup the resolution, like in this post, by using the VideoInfo object provided by pygame:
import pygame
pygame.init()
video_infos = pygame.display.Info()
width, height = video_infos.current_w, video_infos.current_h
screen = pygame.display.set_mode((width, height), pygame.RESIZABLE)
# [...]
Related
I need the window position right after I created a pygame window:
window = pygame.display.set_mode((width, height), 0, 32)
pygame.init()
By default, the window starts at 0,0 - but I also need x,y if the user changes the window position. Any ideas?
I need x,y coords of the pygame window - either at start or on window move. The last one is nice to have.
I figured out how to center the pygame window at the bottom of the screen:
pos_x = screen_width / 2 - window_width / 2
pos_y = screen_height - window_height
os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (pos_x,pos_y)
os.environ['SDL_VIDEO_CENTERED'] = '0'
Background: I have x,y coords which are screen related and I must convert the screen coords into window-local coords so that I can use them e.g. to display coords inside the pygame window or to discard coords which are outside the pygame window.
With my approach above, I knwo the initial position. But I can only use a single pygame window (because it's always at the same position) and things go wrong if the user moves the window.
It have worked for me :
import os
import pygame
x = 100
y = 45
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
pygame.init()
screen = pygame.display.set_mode((100,100))
Taken from https://www.pygame.org/wiki/SettingWindowPosition
Here is an example code that return all four corner positions:
from ctypes import POINTER, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, RECT
# get our window ID:
hwnd = pygame.display.get_wm_info()["window"]
# Jump through all the ctypes hoops:
prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
paramflags = (1, "hwnd"), (2, "lprect")
GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
# finally get our data!
rect = GetWindowRect(hwnd)
print "top, left, bottom, right: ", rect.top, rect.left, rect.bottom, rect.right
# bottom, top, left, right: 644 98 124 644
There is a pygame.display.get_wm_info() call that gets you the Window handler -- from then on, it is using either X11 or Windows API32 to get information from the window through this handler. I didn't find any readily available information on how to do that.
So, just to be clear: there is no ordinary way to do that from within pygame. You have to proceed with another library, possibly using ctypes, after you get the window handler.
On the other hand, if you have to manipulate the window itself, maybe pygame is not the most suitable library for you to use -- you could try PyQt or even GTK+ - they also provide multmedia facilites while being more proper to operate on the level of GUI Windows and other controls
update There are ways to setup an OpenGL backend for pygame graphics, that will allow complete control of the display - including embedding it in another window, as part of a tkinter or Qt application. People that are interested can search a little deeper along those lines.
In Pygame 2, you can alternatively import the _sdl2.video to set the window position. Note that this module is experimental and could be changed in future versions.
import pygame
from pygame._sdl2.video import Window
pygame.init()
window = Window.from_display_module()
window.position = your_position_tuple
Using environment variables as mentioned in other answers is sufficient for most cases, but the downside is that once you have change the window position it will not work a second time (at least in Pygame 2).
Pygame is based on Simple DirectMedia Layer (SDL). Hence you can set SDL environment variables.
See pygame wiki - SettingWindowPosition:
You can set the position of the window by using SDL environment variables before you initialise pygame. Environment variables can be set with the os.environ dict in python.
x = 100
y = 0
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
import pygame
pygame.init()
screen = pygame.display.set_mode((100,100))
(0,0) remains the upper left corner whether the window is moved or not. If you're trying to make (0,0) stay physically where it was on the screen when the window initialized, I don't think pygame can do that. Try to make your question clearer if you want clearer answers.
To accomplish this where you don't know the monitor size of the user, use screeninfo in addition to the pygame and os packages. Screeninfo is OS-agnostic, meaning you can get the resolution of all monitors regardless of a users operating system.
import pygame
from screeninfo import get_monitors
import os
# Set the size of the pygame window
window_width = 512
window_height = 288
window_size = (window_width, window_height)
# Get the bounds of the users monitors, and select the first one
monitors = get_monitors() # Get the resolution of all of the users monitors
screen_width = monitors[0].width # Get width of first monitor found
screen_height = monitors[0].height # Get height of first monitor found
# Set the x and y coordinates of the pygame window in relation to the monitor's resolution
# (I wanted my pygame window to be located in the bottom-right of the monitor)
pos_x = screen_width - window_width # Calculate the x-location
pos_y = screen_height - window_height # Calculate the y-location
os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (pos_x,pos_y) # Set pygame window location
pygame.init() # Initialize the pygame window
self.screen = pygame.display.set_mode(size) # Set the location of the pygame window
Is it possible to get a fully transparent window in Pygame (see the desktop through it)? I've found how to create a window without a frame, but there doesn't seem to be any obvious way to make it transparent.
I'd be willing to tie into system-specific technology/frameworks as long as there are solutions for both Windows and Mac OS X, but I'm not sure which direction to be looking.
The only topic I was able to find recommended using wxPython, which isn't something I can do for this particular project (needs to be Pygame).
On Windows, you can create a solid background color then set the window's transparency color with the Win32 API function SetLayeredWindowAttributes(). (Called with pywin32)
Code:
import pygame
import win32api
import win32con
import win32gui
pygame.init()
screen = pygame.display.set_mode((800, 600)) # For borderless, use pygame.NOFRAME
done = False
fuchsia = (255, 0, 128) # Transparency color
dark_red = (139, 0, 0)
# Create layered window
hwnd = pygame.display.get_wm_info()["window"]
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE,
win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) | win32con.WS_EX_LAYERED)
# Set window transparency color
win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*fuchsia), 0, win32con.LWA_COLORKEY)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(fuchsia) # Transparent background
pygame.draw.rect(screen, dark_red, pygame.Rect(30, 30, 60, 60))
pygame.display.update()
Result:
Explanation:
Any part of the window using your transparency color will be fully transparent. You can view and interact with any desktop icons or programs located behind your game window.
To remove the window border, you can set Pygame's display mode to NOFRAME.
screen = pygame.display.set_mode((800, 600), pygame.NOFRAME)
See Also:
Stack Overflow: Make a window transparent using Win32?
Stack Overflow: Transparent hwnd window
Microsoft: Layered Windows
Microsoft: SetLayeredWindowAttributes function
PyGame uses SDL, which does not support transparent windows. Although at least on Linux making it transparent is done by the window manager, not the application.
I need the window position right after I created a pygame window:
window = pygame.display.set_mode((width, height), 0, 32)
pygame.init()
By default, the window starts at 0,0 - but I also need x,y if the user changes the window position. Any ideas?
I need x,y coords of the pygame window - either at start or on window move. The last one is nice to have.
I figured out how to center the pygame window at the bottom of the screen:
pos_x = screen_width / 2 - window_width / 2
pos_y = screen_height - window_height
os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (pos_x,pos_y)
os.environ['SDL_VIDEO_CENTERED'] = '0'
Background: I have x,y coords which are screen related and I must convert the screen coords into window-local coords so that I can use them e.g. to display coords inside the pygame window or to discard coords which are outside the pygame window.
With my approach above, I knwo the initial position. But I can only use a single pygame window (because it's always at the same position) and things go wrong if the user moves the window.
It have worked for me :
import os
import pygame
x = 100
y = 45
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
pygame.init()
screen = pygame.display.set_mode((100,100))
Taken from https://www.pygame.org/wiki/SettingWindowPosition
Here is an example code that return all four corner positions:
from ctypes import POINTER, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, RECT
# get our window ID:
hwnd = pygame.display.get_wm_info()["window"]
# Jump through all the ctypes hoops:
prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
paramflags = (1, "hwnd"), (2, "lprect")
GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
# finally get our data!
rect = GetWindowRect(hwnd)
print "top, left, bottom, right: ", rect.top, rect.left, rect.bottom, rect.right
# bottom, top, left, right: 644 98 124 644
There is a pygame.display.get_wm_info() call that gets you the Window handler -- from then on, it is using either X11 or Windows API32 to get information from the window through this handler. I didn't find any readily available information on how to do that.
So, just to be clear: there is no ordinary way to do that from within pygame. You have to proceed with another library, possibly using ctypes, after you get the window handler.
On the other hand, if you have to manipulate the window itself, maybe pygame is not the most suitable library for you to use -- you could try PyQt or even GTK+ - they also provide multmedia facilites while being more proper to operate on the level of GUI Windows and other controls
update There are ways to setup an OpenGL backend for pygame graphics, that will allow complete control of the display - including embedding it in another window, as part of a tkinter or Qt application. People that are interested can search a little deeper along those lines.
In Pygame 2, you can alternatively import the _sdl2.video to set the window position. Note that this module is experimental and could be changed in future versions.
import pygame
from pygame._sdl2.video import Window
pygame.init()
window = Window.from_display_module()
window.position = your_position_tuple
Using environment variables as mentioned in other answers is sufficient for most cases, but the downside is that once you have change the window position it will not work a second time (at least in Pygame 2).
Pygame is based on Simple DirectMedia Layer (SDL). Hence you can set SDL environment variables.
See pygame wiki - SettingWindowPosition:
You can set the position of the window by using SDL environment variables before you initialise pygame. Environment variables can be set with the os.environ dict in python.
x = 100
y = 0
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
import pygame
pygame.init()
screen = pygame.display.set_mode((100,100))
(0,0) remains the upper left corner whether the window is moved or not. If you're trying to make (0,0) stay physically where it was on the screen when the window initialized, I don't think pygame can do that. Try to make your question clearer if you want clearer answers.
To accomplish this where you don't know the monitor size of the user, use screeninfo in addition to the pygame and os packages. Screeninfo is OS-agnostic, meaning you can get the resolution of all monitors regardless of a users operating system.
import pygame
from screeninfo import get_monitors
import os
# Set the size of the pygame window
window_width = 512
window_height = 288
window_size = (window_width, window_height)
# Get the bounds of the users monitors, and select the first one
monitors = get_monitors() # Get the resolution of all of the users monitors
screen_width = monitors[0].width # Get width of first monitor found
screen_height = monitors[0].height # Get height of first monitor found
# Set the x and y coordinates of the pygame window in relation to the monitor's resolution
# (I wanted my pygame window to be located in the bottom-right of the monitor)
pos_x = screen_width - window_width # Calculate the x-location
pos_y = screen_height - window_height # Calculate the y-location
os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (pos_x,pos_y) # Set pygame window location
pygame.init() # Initialize the pygame window
self.screen = pygame.display.set_mode(size) # Set the location of the pygame window
I am trying to make a 700x700 fullscreen game in pygame, but whenever I get out of the game and get back in, the screen breaks, showing what was opened before reopening the game. How do I fix it without changing the width and height of the screen?
Width, Height = 700, 700
win = pygame.display.set_mode((Width, Height), pygame.FULLSCREEN)
You will have to reset the fullscreen modifier whenever your window gets activated again. This might be a bug in a new version of pygame.
You can detect when the game gets maximized with pygame.ACTIVEEVENT. You can put something like this in your event loop:
if event.type == pygame.ACTIVEEVENT:
if event.gain == 1:
win = pygame.display.set_mode((Width, Height), pygame.FULLSCREEN)
I'm using pygame on a raspberry pi.
This same code used to cover the full screen at 800x600, now, at 1280x720 it doesn't, and it's not over/underscan:
Pygame example output:
Video playback via omxplayer:
All the code in the pygame example image is just a demo for the problem:
import pygame
import time
pygame.display.init()
pygame.font.init()
screen = pygame.display.set_mode((1280, 720)) #, pygame.FULLSCREEN)
screen.fill((255, 0, 0))
pygame.display.flip()
time.sleep(45)
You can use the list_modes function which returns a list of available full screen resolutions:
modes = pygame.display.list_modes()
if modes: # check if the list is not empty
screen = pygame.display.set_mode(modes[0], pygame.FULLSCREEN) # use the first one
else:
screen = pygame.display.set_mode((800, 600)) # use a default resolution
Note: if you have problems with high DPI scaling on Windows (e. g. a part of your display is not visible), you can use this code to fix them:
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(1)