2013-08-19 61 views
4

即時通訊運行win7 python 3.3和PySDL2 0.5。創建表面時(不管用什麼方法),我得到一個LP_SDL_Surface而不是SDL_Surface。 LP_SDL_Surface缺少您期望它具有的任何方法和屬性。下面是一個使用示例代碼從documentation問題:與SDL_Surface/LP_SDL_Surface PySDL2問題

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()) 

和回溯是:

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' 

谷歌搜索 「LP_SDL_Surface」 帶來的結果0(!)。

+3

我已經[發現] (http://stackoverflow.com/questions/1413851/expected-lp-c-double-instance-instead-of-c-double-array-python-ctypes-error)該LP_ *是ctypes的事情和手段(長)指向*的指針。 意識到這一點,我檢查了python ctypes文檔,現在使用content屬性去表面本身。所以我猜這個問題已經解決了,即時通訊仍然不確定這是否是有意的行爲。 – user2697966

+0

可否請您詳細說明您的解決方案?我也有這個問題。使用'surface.contents'給了我一個空指針訪問錯誤。 –

+0

當然,甚至更好,看到我從Marcus馮Appen得到的解釋我得到了sdl論壇:http://forums.libsdl.org/viewtopic.php?t=9419 – user2697966

回答

1

如果用較低的水平SDL方法的工作(例如sdl2.SDL_LoadBMP),你將不得不面對ctypes的轉換,引用(byref)和指針的提領(.contents.value)。

因此,對於具體問題,正如您已經評論過的那樣,使用print(image.contents.h)就足夠了。

但是,如果需要,pysdl2(sdl2.ext)提供了一些更高級的類和方法,但可以爲您完成大部分這些轉換。下面的代碼實現同樣的目標,而無需觸摸的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()) 

這也使得使用紋理渲染的,使用硬件加速,而不是表面阻擊器(基於軟件)。

最後,使用更高級別的sdl2.ext你也可以實例化類(而不必寫了一個全新的精靈類自己)就像sdl2.ext.sprite.TextureSprite,並實施h屬性:

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]