PySDL2 issue with SDL_Surface / LP_SDL_Surface - python

Im running win7 with python 3.3 and PySDL2 0.5. When creating surfaces (no matter what method) i get an LP_SDL_Surface instead of a SDL_Surface. The LP_SDL_Surface lacks any of the methods and attribute you would expect it to have. Here is the issue using example code 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 the traceback is:
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" brings 0 (!) results.

If you work with the lower level SDL methods (e.g. sdl2.SDL_LoadBMP) you will have to deal with ctypes conversions, referencing(byref) and dereferencing of pointers (.contents, .value).
So for the specific question, as you've already commented, using print(image.contents.h) would be enough.
There are some higher level classes and methods provided by pysdl2 (sdl2.ext), however, that could do most of those conversions for you, if desired. The code below achieves the same goal without having to touch 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 makes use of texture rendering, using hardware acceleration, instead of surface blitting (software based).
Finally, using the higher level sdl2.ext you could also instantiate classes (instead of having to write a whole new sprite class yourself) like sdl2.ext.sprite.TextureSprite, and implement a 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]

Related

Pyforms - Form appears always maximized

When I run my script, the main form pops-up maximized (i.e. taking all the space on my screen). I tried to set the height and width of the form using the CSS file but it did not work. I haven't seen anything about it elsewhere.
Here's my code:
import sys
import pyforms
from pyforms import BaseWidget
from pyforms.Controls import ControlText
from pyforms.Controls import ControlButton
from pyforms.Controls import ControlFile
class ImportIntoFile(BaseWidget):
def __init__(self):
super(ImportIntoFile,self).__init__('HTCondor & EnergyPlus')
self._Input = ControlFile('Input')
self._Output = ControlFile('Output')
self._Import = ControlButton('Import')
self._Close = ControlButton('Close')
self._formset = ['',(' ','_Input',' '),(' ','_Output',' '),('','_Close','','_Import',''),'']
self._Import.value = self.__ImportAction
self._Close.value = self.__CloseAction
def __ImportAction(self):
OutputFile = open(self._Output.value,'a')
InputFile = open(self._Input.value,'r')
OutputFile.close
InputFile.close
def __CloseAction(self):
sys.exit()
if __name__ == "__main__": pyforms.startApp( ImportIntoFile )`
You can pass a window geometry to the pyforms.start_app() call. So something like the code below should work.
if __name__ == "__main__":
pyforms.start_app( ImportIntoFile, geometry=(200, 200, 400, 400) )
I had the same problem. Pyforms uses Qt, so some of these modules will be familiar, and this css will modify them.
I used:
QMainWindow{
max-width:500px;
max-height:500px;
}
to successfully set the size of the main window, but you can't increase the size later, so if all you want is a fixed size window, it works.
I can't find a good solution too. For temporary workaround when I want to avoid maximized by default, what I did is modifying C:\Python27\Lib\site-packages\pyforms\gui\standaloneManager.py.
From
if geometry is not None:
w.show()
w.setGeometry(*geometry)
else:
w.showMaximized()
To
if geometry is not None:
w.show()
w.setGeometry(*geometry)
else:
w.showNormal()

glEnd error in PyOpenGL error = 1282

Hi i get a very strange problem when running this code. I don't see how it should conflict with the OpenGL Api either. Heres the code:
import sys
sys.path.append("..\Blocks")
print sys.path
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import random
try:
import BlockModel
except:
print "Cant Find Block Model"
def createBlock():
block = BlockModel.Block()
blockVertices = block.returnVertices()
blockEdges = block.returnEdges()
blockSurface = block.returnSurface()
glBegin(GL_QUADS)
for surface in blockSurface:
for faceVertex in surface:
glVertex3fv(blockVertices[faceVertex])
glEnd
glBegin(GL_LINES)
for edge in blockEdges:
for vertex in edge:
glVertex3fv(blockVertices[vertex])
glEnd()
def main():
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(15, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(random.randrange(-5,5),random.randrange(-5,5), -40)
exit = False
while not exit:
pygame.time.wait(10)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
createBlock()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
main()
I get this error when trying to run the program:
C:\Users\Haavard\Desktop\MinecraftPythonProject\framework>python main.py
['C:\\Users\\Haavard\\Desktop\\MinecraftPythonProject\\framework', 'C:\\Windows\
\system32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python
27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\
lib\\site-packages', 'C:\\Python27\\lib\\site-packages\\PIL', '..\\Blocks']
Traceback (most recent call last):
File "main.py", line 60, in <module>
main()
File "main.py", line 52, in main
createBlock()
File "main.py", line 37, in createBlock
glEnd()
File "latebind.pyx", line 44, in OpenGL_accelerate.latebind.Curry.__call__ (c:
\Users\mcfletch\OpenGL-dev\OpenGL-ctypes\OpenGL_accelerate\src\latebind.c:1201)
File "C:\Python27\lib\site-packages\OpenGL\GL\exceptional.py", line 46, in glE
nd
return baseFunction( )
File "C:\Python27\lib\site-packages\OpenGL\platform\baseplatform.py", line 402
, in __call__
return self( *args, **named )
File "errorchecker.pyx", line 53, in OpenGL_accelerate.errorchecker._ErrorChec
ker.glCheckError (c:\Users\mcfletch\OpenGL-dev\OpenGL-ctypes\OpenGL_accelerate\s
rc\errorchecker.c:1218)
OpenGL.error.GLError: GLError(
err = 1282,
description = 'invalid operation',
baseOperation = glEnd,
cArguments = ()
)
Im running on windows 7 on a hp machine.
Block Model Module looks like this:
class Block:
# initializing the basic functions of a block
def __init__(self, blockID = "0", blockType = "stone", verticesCords = ((1,-1,-1),(1,1,-1),(-1,1,-1),(-1,-1,-1),(1,-1,1),(1,1,1),(-1,-1,1),(-1,1,1)), edges = ((0,1),(0,3),(0,4),(2,1),(2,3),(2,7),(6,3),(6,4),(6,7),(5,1),(5,4),(5,7)), surfaces = (((0,1,2,3),(3,2,7,6),(6,7,5,4),(4,5,1,0),(1,5,7,2),(4,0,3,6)))):
# Block Placement
self.PLACEMENT = verticesCords
# Block identity in the world
self.EDGES = edges
self.SURFACE = surfaces
self.BLOCKID = blockID
# The block type
self.BLOCKTYPE = blockType
# A function letting the framework know its placement.
def returnVertices(self):
return self.PLACEMENT
def returnEdges(self):
return self.EDGES
def returnSurface(self):
return self.SURFACE
# A function to make the block fetch its own texture.
def defineTexture():
pass
Thank you for any answears! :)
You may have already solved this, but my guess is that you might have an odd-number of vertices in your edges. A 1282 error on the glEnd() just means there's something wrong with the whole operation. GL_LINES expects an even number of vertices to be given, as GL_LINES works in pairs of points to define each line segment, rather than an continuous string of points to make a big polyline. Double check that each edge has two points.
You should remove () from glEnd() line number 37 and code should work fine.
It looks like you aren't ending the GL_QUADS process properly. You're calling glEnd, rather than glEnd(). I don't know if that's the problem but that definitely is wrong. It may be that you need to specify which process you're ending if you have multiple going, e.g. glEnd(GL_LINES) or glEnd(GL_QUADS) when you have multiple currently prepared which is why the error is happening on the successful glEnd() call; you aren't telling it which should be ended.
Hope this helps

Python weird NameError

I have a NameError that I cannot seem to be able to find the reason for. The error trace ends like this.
Traceback (most recent call last):
File ".../new_main.py", line 61, in <module>
if __name__ == "__main__": main()
File ".../new_main.py", line 39, in main
mp = build()
File ".../common.py", line 54, in build
m = r.build_from_config(map_config, character_config)
File ".../config_reader.py", line 148, in build_from_config
item["squares"]
File ".../new_map.py", line 49, in build_map
self.view = MapView(self)
File ".../new_map.py", line 135, in __init__
self.screen = reset_screen()
NameError: name 'reset_screen' is not defined
The class MapView() is in the file new_map.py and that file has this line in the imports:
from common import *
And the file common.py has the following function in it.
def reset_screen():
# check if display has been initialized
if not pygame.display.get_init():
pygame.init()
# set screen
#flags = pygame.FULLSCREEN | pygame.DOUBLEBUF
screen = pygame.display.set_mode( options.window_size )
# fill with black
screen.fill(BLACK)
return screen
What am I missing?
E: here are my imports for each file.
new_main.py:
from common import *
from new_map import Map, MapView
import pygame, sys
common.py:
import pygame
import options
from config_reader import ConfigReader
from constants import *
from coordinates import Coordinates
config_reader.py:
from action import Action
from new_map import Map
from object_type import ObjectType
from squaretype import SquareType
from new_character import Character
from coordinates import Coordinates
import direction
new_map.py:
from square import Square
from common import *
from constants import *
from coordinates import Coordinates
from map_object import MapObject
from object_type import ObjectType
from new_character import Character
from turn import TurnController
import pygame, os
Looking at your trace i can also just figure that in your common.py your are including new_map.py which causes the import in new_map to fail. If i do that to my test files, i get the same error:
my main - which imports both but still won't cause circular reference:
if __name__ == "__main__":
from common import * # <-- this is ok
from new_map import * # <-- this is no problem
do_something()
test()
my commons:
from new_map import * # <--- this will cause the problem
def reset_screen():
return 1
def do_something():
return test()
my new_map:
from common import * # <--- this will fail then
def test():
return reset_screen()
So you will have to split you common.py to the parts using new_map and the other that don't, and in new_map then import the version that holds the functions without new_map inclusion.
common_map.py
from new_map import *
def do_something()
return test()
common_nomap.py
def reset_screen()
return 1
new_map.py:
from common_nomap import *
def test()
return reset_screen()
main.py
if __name__ == "__main__":
from common_map import * # <-- this is ok
from new_map import * # <-- this is no problem
do_something()
test()
2 possible scenarios I can think of:
Circular deps: it looks like common.py activates the function in new_map.py (via config_reader.py), which might cause new_map.py not to import common.py
Is there a common package you might be importing instead of common.py?

fhss project in python: Error 'fft_window' object has no attribute '_proxies'

this is what i am getting when i execute the following code.
Traceback (most recent call last):
File "usrp.py",line 100 in <module>
tb.set_freq(i)
File "usrp.py",line 77 in set_freq
self.wxgui_fftsink2_0.set_baseband_freq(self.freq)
File "usr/local/lib/python2.7/dist-packages/gnuradio/wxgui/common.py",line 131 in set
def set(value): controller[key]=value
File "usr/local/lib/python2.7/dist-packages/gnuradio/wxgui/pubsub.py",line 44 in _setitem_
elif self._proxies[key] is not None:
AttributeError: 'fft_window' object has no attribute '_proxies'
i have seen this kind of error in cyclic dependency.i have earlier solved cyclic dependency by just importing the package instead of using from keyword.i had tried import gnuradio in ths case but of no use.Following is the code on which i am working on.it would be great help if this could be resolved.i haven't come across this kind of an error.
#!/usr/bin/env python
##################################################
# Gnuradio Python Flow Graph
# Title: Usrp
# Generated: Sat Feb 21 11:26:17 2015
##################################################
#################################################
# Gnuradio Python Flow Graph
# Title: Usrp
# Generated: Sat Feb 21 11:26:17 2015
##################################################
from gnuradio import analog
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import wxgui
from gnuradio.eng_option import eng_option
from gnuradio.fft import window
from gnuradio.filter import firdes
from gnuradio.wxgui import fftsink2
from grc_gnuradio import wxgui as grc_wxgui
from optparse import OptionParser
import wx,time,random
class usrp(grc_wxgui.top_block_gui):
def __init__(self):
grc_wxgui.top_block_gui.__init__(self, title="Usrp")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 32000
self.freq = freq = 900e6
##################################################
# Blocks
##################################################
self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
self.GetWin(),
baseband_freq=freq,
y_per_div=10,
y_divs=10,
ref_level=0,
ref_scale=2.0,
sample_rate=samp_rate
fft_size=1024,
fft_rate=15,
average=False,
avg_alpha=None,
title="FFT Plot",
peak_hold=False,
)
self.Add(self.wxgui_fftsink2_0.win)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_SIN_WAVE, 100e3,1, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.blocks_throttle_0, 0), (self.wxgui_fftsink2_0, 0))
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.wxgui_fftsink2_0.set_sample_rate(self.samp_rate)
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate)
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
def get_freq(self):
return self.freq
def set_freq(self, freq):
self.freq = freq
self.wxgui_fftsink2_0.set_baseband_freq(self.freq)
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print "Warning: failed to XInitThreads()"
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
(options, args) = parser.parse_args()
tb = usrp()
def t_range(beg,end,incr):
while beg<=end:
yield beg
beg+=incr
j=2
for i in t_range(910e6,1010e6,10e6):
tb.set_freq(i)
#time.sleep(j)
tb.Start(True)
time.sleep(j)
tb.Wait()
This is most likely not a cyclic dependency issue.
I'm however a bit concerned about that error. You see, pubsub's __init__ generates a _proxies attribute, so if a class is a subclass of pubsub, it should have _proxies; if it's not, it shouldn't see that call.
class pubsub(dict):
def __init__(self):
self._publishers = { }
self._subscribers = { }
self._proxies = { }
....
So, interestingly, your script works for me (after fixing a missing , in line 45), which might indicate you're mixing sources of different GNU Radio versions:
As a solution, I recommend making sure you're really using one version of GNU Radio, preferably the latest, and installed from source (debian's packages are rather up-to-date, too, thanks to Maitland), which can happen automagically using PyBOMBS.

Cocos2d: AttributeError: 'Director' object has no attribute '_window_virtual_width'

We are using the cocos2d framework to create a game. We're completely new to this framework, so we cannot get the director object to work as we are expecting. Here is our code skeleton:
from cocos.director import director
from cocos.layer import base_layers
import sys
import math
import os
import pyglet
import cocos
world_width = 1000
world_height = 1000
class NetworkMap(cocos.layer.ScrollableLayer):
def __init__(self, world_width, world_height):
self.world_width = world_width
self.world_height = world_height
super(NetworkMap, self).__init__()
bg = ColorLayer(170,170,0,255,width=500,height=500)
self.px_width = world_width
self.px_height = world_height
self.add(bg,z=0)
class TestScene(cocos.scene.Scene):
def __init__(self):
super(TestScene,self).__init__()
def on_enter():
director.push_handlers(self.on_cocos_resize)
super(TestScene, self).on_enter()
def on_cocos_resize(self, usable_width, usable_height):
self.f_refresh_marks()
def main():
scene = TestScene()
director.init(world_width, world_height, do_not_scale=True)
world_map = NetworkMap(world_width, world_height)
scroller = cocos.layer.ScrollingManager()
scroller.add(world_map)
scene.add(scroller)
director.run(scene)
So for some reason the director doesn't have all the attributes we want.
Our stack trace is:
Traceback (most recent call last):
File "map.py", line 49, in <module>
main()
File "map.py", line 39, in main
scene = TestScene()
File "map.py", line 29, in __init__
super(TestScene,self).__init__()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/scene.py", line 95, in __init__
super(Scene,self).__init__()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/cocosnode.py", line 114, in __init__
self.camera = Camera()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/camera.py", line 56, in __init__
self.restore()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/camera.py", line 76, in restore
width, height = director.get_window_size()
File "/usr/local/lib/python2.7/dist-packages/cocos2d-0.5.5-py2.7.egg/cocos/director.py", line 522, in get_window_size
return ( self._window_virtual_width, self._window_virtual_height)
AttributeError: 'Director' object has no attribute '_window_virtual_width'
You need to initialise the director before you instantiate your first scene. The director is the global object that initialises your screen, sets up the Cocos2D framework, etc.
I found a few other errors:
You need to change ColorLayer to be fully qualified, e.g. cocos.layer.ColorLayer.
on_enter needs to have self as the first argument.
You need to define f_refresh_marks in your TestScene class.
Here's a working copy of the code. (Working, in the sense that it does not throw errors, not that it does any sort of scrolling.)
from cocos.director import director
from cocos.layer import base_layers
import sys
import math
import os
import pyglet
import cocos
world_width = 1000
world_height = 1000
class NetworkMap(cocos.layer.ScrollableLayer):
def __init__(self, world_width, world_height):
self.world_width = world_width
self.world_height = world_height
super(NetworkMap, self).__init__()
bg = cocos.layer.ColorLayer(170,170,0,255,width=500,height=500)
self.px_width = world_width
self.px_height = world_height
self.add(bg,z=0)
class TestScene(cocos.scene.Scene):
def __init__(self):
super(TestScene,self).__init__()
def on_enter(self):
director.push_handlers(self.on_cocos_resize)
super(TestScene, self).on_enter()
def on_cocos_resize(self, usable_width, usable_height):
self.f_refresh_marks()
def f_refresh_marks(self):
pass
def main():
director.init(world_width, world_height, do_not_scale=True)
scene = TestScene()
world_map = NetworkMap(world_width, world_height)
scroller = cocos.layer.ScrollingManager()
scroller.add(world_map)
scene.add(scroller)
director.run(scene)
if __name__ == '__main__': main()
I had the same issue (with a very similar stack trace) and it was because I was trying to create a layer before calling director.init(). Moving director.init() to earlier in the code fixed it for me.

Categories