PySDL2 issue with SDL_Surface / LP_SDL_Surface

Im running win7 with python 3.3 and PySDL2 0.5. When creating surfaces (regardless of the method), I get LP_SDL_Surface instead of SDL_Surface. LP_SDL_Surface does not have any methods and attributes that you expect from it. The following is an example code example from the documentation :

import os os.environ["PYSDL2_DLL_PATH"] = os.path.dirname(os.path.abspath(__file__)) import sys import ctypes from sdl2 import * def main(): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b"Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 592, 460, SDL_WINDOW_SHOWN) windowsurface = SDL_GetWindowSurface(window) image = SDL_LoadBMP(b"exampleimage.bmp") SDL_BlitSurface(image, None, windowsurface, None) print(image.h) SDL_UpdateWindowSurface(window) SDL_FreeSurface(image) running = True event = SDL_Event() while running: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT: running = False break SDL_DestroyWindow(window) SDL_Quit() return 0 if __name__ == "__main__": sys.exit(main()) 

and trace:

 Traceback (most recent call last): File "C:/.../test.py", line 35, in <module> sys.exit(main()) File "C:/.../test.py", line 17, in main print(image.h) AttributeError: 'LP_SDL_Surface' object has no attribute 'h' 

A google search for "LP_SDL_Surface" yields 0 (!) Results.

+4
source share
1 answer

If you work with lower-level SDL methods (for example, sdl2.SDL_LoadBMP ), you will have to deal with ctypes conversions, a reference ( byref ), and pointer dereferencing ( .contents , .value ).

So, for a specific question, as you already commented, using print(image.contents.h) will be enough.

However, there are higher-level classes and methods provided by pysdl2 ( sdl2.ext ) that could do most of these conversions for you, if necessary. The code below achieves the same goal without touching ctypes:

 import os os.environ["PYSDL2_DLL_PATH"] = os.path.dirname(os.path.abspath(__file__)) import sys import sdl2 import sdl2.ext def main(): sdl2.ext.init() window = sdl2.ext.Window( title="Hello World!", size=(592, 460), flags=sdl2.SDL_WINDOW_SHOWN, position=(sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED)) window.show() renderer = sdl2.ext.Renderer(window) factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer) spriterenderer = factory.create_sprite_render_system(window) image = factory.from_image("exampleimage.bmp") print(image.size[1]) # image.size = (w, h) running = True while running: for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_QUIT: running = False break spriterenderer.render(image) sdl2.ext.quit() return 0 if __name__ == '__main__': sys.exit(main()) 

It also uses texturing, using hardware acceleration, instead of surface blitting (software-based).

Finally, using the higher level sdl2.ext , you can also instantiate classes (instead of writing the new sprite class yourself), for example sdl2.ext.sprite.TextureSprite , and implement the h property:

 class TextureSprite(sdl2.ext.TextureSprite): @property def h(self): """The height of the TextureSprite.""" return self.size[1] @property def w(self): """The width of the TextureSprite.""" return self.size[0] 
+1
source

Source: https://habr.com/ru/post/1497880/


All Articles