When i try to open a borderless mode window it does start in the top right corner of the screen. It looks like this: http://puu.sh/ivB4y/304018da5e.jpg The code looks like this
if __name__ == "__main__":
import source.Game, pygame
pygame.mixer.pre_init(22050, 16, 2, 256)
pygame.font.init()
pygame.init()
screen = pygame.display.set_mode((1920, 1080), pygame.NOFRAME)
source.Game.Game().main(screen)
It might be worth noting that I'm running two monitors, but I've tried only running one and the problem still happens, and if I take the resolution down below native it still won't start in the top right of my screen.
Is there any way to fix such a problem?
EDIT:
I went this from the answers for anyone looking on this in the future.
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
screen = pygame.display.set_mode((1920, 1080), pygame.NOFRAME)
along with all the other .init() statements and whatnot.
Looks like you want fullscreen:
screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN)
You might also want to turn on hardware acceleration adn double buffering using pygame.HWSURFACE | pygame.DOUBLEBUF if you are running fullscreen.
display.set_mode docs: https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode
If you actually want to keep the OS's bar on screen, then instead of going fullscreen, then ideally you would just maximize the window after creating it. However, the version of the SDL lib that Pygame is built on does not support a maximize operation (SDL 2 does). Apparently, you can control the position of the window by setting an environment variable before initializing the window (yuck), but you would still need to figure out the usable area of the desktop. Example:
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
import pygame
pygame.init()
screen = pygame.display.set_mode((100,100))
Related
I'm making a pseudo transparent window in pygame with the intent of displaying varied info like a "HUD"
The script uses PIL to grab an image of the desktop and use it as the background of the window.
A simple version:
import pygame as py
from ctypes import windll
import ImageGrab, Image
SetWindowPos = windll.user32.SetWindowPos
py.init()
def get_image():
im = ImageGrab.grab((0,0,window_x,window_y))
mode = im.mode
size = im.size
data = im.tobytes()
im = py.image.fromstring(data,size,mode)
return im
window_x = 1920
window_y = 100
background = py.Surface((window_x,window_y))
background.blit(get_image(),(0,0))
window_pos = (0,0)
screen = py.display.set_mode((window_x,window_y),py.HWSURFACE|py.NOFRAME)
SetWindowPos(py.display.get_wm_info()['window'],-1,0,0,0,0,0x0001)
clock = py.time.Clock()
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
screen.blit(background,(0,0))
py.display.flip()
clock.tick(30)
py.quit()
This creates a Pygame window at the top of the screen.
My problem is that the Pygame window blocks any mouse interaction with anything beneath it.
Is there a way to allow mouse events to be ignored and go 'through' the window, like for example clicking on a desktop icon, underneath a Pygame window.
You will need to do a bit of an extra hacking which is outside what PyGame gives you. It should be possible to render the PyGame canvas into another windowing framework in Python and try to use advanced features of that library to achieve this.
In Windows
One example is wxWidgets. As described in this thread, which sounds quite similar to what you are trying to achieve, the user has setup a window which can be clicked through and is transparent.
Also see this another Stackoverflow Post which mentions how to handle the Hit Testing in C#. Posting code from that post here:
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WM_NCHITTEST)
m.Result = (IntPtr)HTTRANSPARENT;
else
base.WndProc(ref m);
}
It is possible to do similar testing in Python using win32 APIs. This is a piece of Python code that does exactly this. Locate the part where the programmer sets up the callback for the event (something like win32con.WM_NCHITTEST: self.onChi, where self.onChi is the callback).
I hope this gives you a starting point. I doubt there is anything readymade that you will find out of the box but these should give you some pointers on what to look for.
This is an old question, but I have ran into it quite a few times and only now got it to work right. Here is the relevant bit.
import win32api
import win32con
import win32gui
fuchsia = (255, 0, 128) # Transparency color
hwnd = pygame.display.get_wm_info()["window"] # Handle
styles = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
styles = win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, styles)
win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*fuchsia), 0, win32con.LWA_COLORKEY)
I am using pygame to program a simple behavioral test. I'm running it on my macbook pro and have almost all the functionality working. However, during testing I'll have a second, external monitor that the subject sees and the laptop monitor. I'd like to have the game so up fullscreen on the external monitor and not on the laptop's monitor so that I can monitor performance. Currently, the start of the file looks something like:
#! /usr/bin/env python2.6
import pygame
import sys
stdscr = curses.initscr()
pygame.init()
screen = pygame.display.set_mode((1900, 1100), pygame.RESIZABLE)
I was thinking of starting the game in a resizable screen, but that OS X has problems resizing the window.
Pygame doesn't support two displays in a single pygame process(yet). See the question here and developer answer immediately after, where he says
Once SDL 1.3 is finished then pygame will get support for using multiple windows in the same process.
So, your options are:
Use multiple processes. Two pygame instances, each maximized on its own screen, communicating back and forth (you could use any of: the very cool python multiprocessing module, local TCP, pipes, writing/reading files, etc)
Set the same resolution on both of your displays, and create a large (wide) window that spans them with your information on one half and the user display on the other. Then manually place the window so that the user side is on their screen and yours is on the laptop screen. It's hacky, but might a better use of your time than engineering a better solution ("If it's studpid and it works, it ain't stupid" ;).
Use pyglet, which is similar to pygame and supports full screen windows: pyglet.window.Window(fullscreen=True, screens[1])
Good luck.
I do not know if you can do this in OS X, but this is worth mentioning for the Windows users out there, if you just want to have your program to run full screen on the second screen and you are on windows, just set the other screen as the main one.
The setting can be found under Rearrange Your Displays in settings.
So far for me anything that I can run on my main display can run this way, no need to change your code.
I did something silly but it works.
i get the number of monitors with get_monitors()
than i use SDL to change the pygame window's display position by adding to it the width of the smallest screen, to be sure that the window will be positionned in the second monitor.
from screeninfo import get_monitors
numberOfmonitors = 0
smallScreenWidth = 9999
for monitor in get_monitors():
#getting the smallest screen width
smallScreenWidth = min(smallScreenWidth, monitor.width)
numberOfmonitors += 1
if numberOfmonitors > 1:
x = smallScreenWidth
y = 0
#this will position the pygame window in the second monitor
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
#you can check with a small window
#screen = pygame.display.set_mode((100,100))
#or go full screen in second monitor
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
#if you want to do other tasks on the laptop (first monitor) while the pygame window is being displayed on the second monitor, you shoudn't use fullscreen but instead get the second monitor's width and heigh using monitor.width and monitor.height, and set the display mode like
screen = pygame.display.set_mode((width,height))
display = pyglet.canvas.get_display()
display = display.get_screens()
win = pyglet.window.Window(screen=display[1])
------------------------------------------------------
screen=display[Номер монитора]
------------------------------------------------------
display = pyglet.canvas.get_display()
display = display.get_screens()
print(display) # Все мониторы которые есть
I'm learning to program, and figured out how to use the NOFRAME flag in pygame.display.set_mode() which I really like, but I can't drag the window now. I can't find any mention of window position in Pygame documentation or on this site.
I just checked my version of Pygame, it's 1.9.1 but my documentation is for 1.9.2 (strange, since I got them at the same time). Not sure if this matters, trying to be thorough. Thanks in advance.
pygame (which use SDL 1.2) doesn't have method to move window.
It has variable which you can use to set position before you use set_mode()
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = '50, 500'
but if you what change position then you have to use set it again and use set_mode() again.
import os
import pygame
import time
pygame.init()
print('pos: 50, 500')
os.environ['SDL_VIDEO_WINDOW_POS'] = '50, 500'
screen = pygame.display.set_mode((300,300), 32, pygame.NOFRAME)
time.sleep(2)
print('pos: 500, 50')
os.environ['SDL_VIDEO_WINDOW_POS'] = '500, 50'
screen = pygame.display.set_mode((300,300), 32, pygame.NOFRAME)
time.sleep(2)
pygame.quit()
BTW:
PySDL uses SDL 2.0 which has SetWindowPosition
pyglet has pyglet.window.Window.set_location
I'm making a pseudo transparent window in pygame with the intent of displaying varied info like a "HUD"
The script uses PIL to grab an image of the desktop and use it as the background of the window.
A simple version:
import pygame as py
from ctypes import windll
import ImageGrab, Image
SetWindowPos = windll.user32.SetWindowPos
py.init()
def get_image():
im = ImageGrab.grab((0,0,window_x,window_y))
mode = im.mode
size = im.size
data = im.tobytes()
im = py.image.fromstring(data,size,mode)
return im
window_x = 1920
window_y = 100
background = py.Surface((window_x,window_y))
background.blit(get_image(),(0,0))
window_pos = (0,0)
screen = py.display.set_mode((window_x,window_y),py.HWSURFACE|py.NOFRAME)
SetWindowPos(py.display.get_wm_info()['window'],-1,0,0,0,0,0x0001)
clock = py.time.Clock()
done = False
while not done:
for event in py.event.get():
if event.type == py.QUIT:
done = True
screen.blit(background,(0,0))
py.display.flip()
clock.tick(30)
py.quit()
This creates a Pygame window at the top of the screen.
My problem is that the Pygame window blocks any mouse interaction with anything beneath it.
Is there a way to allow mouse events to be ignored and go 'through' the window, like for example clicking on a desktop icon, underneath a Pygame window.
You will need to do a bit of an extra hacking which is outside what PyGame gives you. It should be possible to render the PyGame canvas into another windowing framework in Python and try to use advanced features of that library to achieve this.
In Windows
One example is wxWidgets. As described in this thread, which sounds quite similar to what you are trying to achieve, the user has setup a window which can be clicked through and is transparent.
Also see this another Stackoverflow Post which mentions how to handle the Hit Testing in C#. Posting code from that post here:
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)WM_NCHITTEST)
m.Result = (IntPtr)HTTRANSPARENT;
else
base.WndProc(ref m);
}
It is possible to do similar testing in Python using win32 APIs. This is a piece of Python code that does exactly this. Locate the part where the programmer sets up the callback for the event (something like win32con.WM_NCHITTEST: self.onChi, where self.onChi is the callback).
I hope this gives you a starting point. I doubt there is anything readymade that you will find out of the box but these should give you some pointers on what to look for.
This is an old question, but I have ran into it quite a few times and only now got it to work right. Here is the relevant bit.
import win32api
import win32con
import win32gui
fuchsia = (255, 0, 128) # Transparency color
hwnd = pygame.display.get_wm_info()["window"] # Handle
styles = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
styles = win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, styles)
win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(*fuchsia), 0, win32con.LWA_COLORKEY)
I'm building a small game with pygame. I want the window of the game to be size of the monitors resolution. My computers screen's resolution is 1920x1080 and display.info says the window size is also 1920x1080 but when I run it, it creates a window roughly one and half times the size of my screen.
import pygame, sys
def main():
#set up pygame, main clock
pygame.init()
clock = pygame.time.Clock()
#creates an object with the computers display information
#current_h, current_w gives the monitors height and width
displayInfo = pygame.display.Info()
#set up the window
windowWidth = displayInfo.current_w
windowHeight = displayInfo.current_h
window = pygame.display.set_mode ((windowWidth, windowHeight), 0, 32)
pygame.display.set_caption('game')
#gameLoop
while True:
window.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#draw the window onto the screen
pygame.display.flip()
clock.tick(60)
main()
I've been having the same problem, and I managed to find the answer and posted it here. The answer I found is as follows:
I managed to find a commit on the Pygame BitBucket page here that explains the issue and gives an example on how to fix it.
What is happening is that some display environments can be configured to stretch windows so they don't look small on high PPI (Pixels Per Inch) displays. This stretching is what causes displays on larger resolutions to display larger than they actually are.
They provide an example code on the page I linked to showing how to fix this issue.
They fix the issue by importing ctypes and calling this:
ctypes.windll.user32.SetProcessDPIAware()
They also express that this is a Windows only solution and is available within base Python since Python 2.4. Before that it will need to be installed.
With that said, to make this work, put this bit of code anywhere before pygame.display.set_mode()
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
#
# # # Anywhere Before
#
pygame.display.set_mode(resolution)
I hope this helps you and anyone else who finds they have this same issue.