(If this is a double post I apologise, had some trouble getting it to
post
at all)
Hi,
I'm trying to create an onscreen keyboard to use with my multitouch
setup.
I want it to be rotatable, scalable and always on top. As far as i
could
see it's not possible to make pyglet applications that are transparent
against the background but it is in wxpy. So I looked around and I
found
wxtest.py in pyglet/experimental and I managed to create the effect I
wanted.
This isn't what I'm using but it's the same effect: (It's basicly
wxtest.py with some small modifactions to show the transparency effect
I
want)
#!/usr/bin/python
# $Id:$
# wxPython + pyglet integration, by subclassing wx.Window.
# Win32 works fine, though flickery resize.
# GDK sort of works, but keeps getting overdrawn by the window
background
# (resize to see).
import wx
import pyglet
from pyglet.gl import *
import sys
import math
if sys.platform == 'win32':
from pyglet.window.win32 import _user32
from pyglet.gl import wgl
elif sys.platform == 'linux2':
from pyglet.image.codecs.gdkpixbuf2 import gdk
from pyglet.gl import glx
class AbstractCanvas(pyglet.event.EventDispatcher):
def __init__(self, context, config):
# Create context (same as pyglet.window.Window.__init__)
if not config:
platform = pyglet.window.get_platform()
display = platform.get_default_display()
screen = display.get_screens()[0]
for template_config in [
pyglet.gl.Config(double_buffer=True, depth_size=24),
pyglet.gl.Config(double_buffer=True, depth_size=16)]:
try:
config = screen.get_best_config(template_config)
break
except pyglet.window.NoSuchConfigException:
pass
if not config:
raise pyglet.window.NoSuchConfigException(
'No standard config is available.')
if not config.is_complete():
config = screen.get_best_config(config)
if not context:
context = config.create_context(pyglet.gl.current_context)
self._display = display
self._screen = screen
self._config = config
self._context = context
def on_resize(self, width, height):
self.switch_to()
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
def switch_to(self):
self._switch_to_impl()
self._context.set_current()
pyglet.gl.gl_info.set_active_context()
pyglet.gl.glu_info.set_active_context()
def _switch_to_impl(self):
raise NotImplementedError('abstract')
def flip(self):
raise NotImplementedError('abstract')
AbstractCanvas.register_event_type('on_draw')
AbstractCanvas.register_event_type('on_resize')
class AbstractWxCanvas(wx.Panel, AbstractCanvas):
def __init__(self, parent, id=-1, config=None, context=None):
wx.Window.__init__(self, parent, id,
style=wx.FULL_REPAINT_ON_RESIZE)
AbstractCanvas.__init__(self, config, context)
#self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
self.Bind(wx.EVT_PAINT, self._OnPaint)
self.Bind(wx.EVT_SIZE, self._OnSize)
self.Bind(wx.EVT_ERASE_BACKGROUND, self._OnEraseBackground)
def _OnPaint(self, event):
# wx handler for EVT_PAINT
wx.PaintDC(self)
self.dispatch_event('on_draw')
self.flip()
def _OnEraseBackground(self, event):
pass
def _OnSize(self, event):
# wx handler for EVT_SIZE
width, height = self.GetClientSize()
self.dispatch_event('on_resize', width, height)
class Win32WxCanvas(AbstractWxCanvas):
def __init__(self, parent, id=-1, config=None, context=None):
super(Win32WxCanvas, self).__init__(parent, id, config,
context)
self._hwnd = self.GetHandle()
self._dc = _user32.GetDC(self._hwnd)
self._context._set_window(self)
self._wgl_context = self._context._context
self.switch_to()
#infile, socket = create_infile( 1, "alpha03", 2336, None )
#infile, socket = create_infile( 1, "localhost", 2337, None )
#self.tieg = TouchInterfaceEventGenerator(infile, self)
self.parent = parent
self.timer = wx.Timer(self, 1)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(10)
def OnTimer(self, event):
#self.tieg.dispatch_events(self.keyboard)
self.parent.rotate()
self.Refresh()
self.Update()
def _switch_to_impl(self):
wgl.wglMakeCurrent(self._dc, self._wgl_context)
def flip(self):
wgl.wglSwapLayerBuffers(self._dc, wgl.WGL_SWAP_MAIN_PLANE)
class GTKWxCanvas(AbstractWxCanvas):
_window = None
def __init__(self, parent, id=-1, config=None, context=None):
super(GTKWxCanvas, self).__init__(parent, id, config, context)
self._glx_context = self._context._context
self._x_display = self._config._display
self._x_screen_id = self._screen._x_screen_id
# GLX 1.3 doesn't work here (BadMatch error)
self._glx_1_3 = False # self._display.info.have_version(1, 3)
def _OnPaint(self, event):
if not self._window:
self._window = self.GetHandle()
# Can also get the GDK window... (not used yet)
gdk_window = gdk.gdk_window_lookup(self._window)
if self._glx_1_3:
self._glx_window = glx.glXCreateWindow
(self._x_display,
self._config._fbconfig, self._window, None)
self.switch_to()
super(GTKWxCanvas, self)._OnPaint(event)
def _switch_to_impl(self):
if not self._window:
return
if self._glx_1_3:
glx.glXMakeContextCurrent(self._x_display,
self._glx_window, self._glx_window, self._glx_context)
else:
glx.glXMakeCurrent(self._x_display, self._window,
self._glx_context)
def flip(self):
if not self._window:
return
if self._glx_1_3:
glx.glXSwapBuffers(self._x_display, self._glx_window)
else:
glx.glXSwapBuffers(self._x_display, self._window)
if sys.platform == 'win32':
WxCanvas = Win32WxCanvas
elif sys.platform == 'linux2':
WxCanvas = GTKWxCanvas
else:
assert False
class TestCanvas(WxCanvas):
label = pyglet.text.Label('Hello, world', font_size=48,
anchor_x='center', anchor_y='center')
def on_draw(self):
width, height = self.GetClientSize()
glClear(GL_COLOR_BUFFER_BIT)
self.label.text = 'OpenGL %s' % pyglet.gl.gl_info.get_version
()
self.label.x = width//2
self.label.y = height//2
self.label.draw()
class TestFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, None, -1, title, size=(640, 480),
style =
wx.FRAME_SHAPED)
self.canvas = TestCanvas(self)
self.SetDimensions(0, 0, 800 , 600)
self.parent = parent
self.angle = 0
self.updateDim()
def rotate(self):
self.angle += 0.01
self.updateDim()
def updateDim(self):
cos = math.cos(self.angle) * 100
p = [wx.Point(400, 300), wx.Point(400+cos, 100), wx.Point(100,
500)]
r = wx.RegionFromPoints(p)
self.hasShape = self.SetShape(r)
class TestApp(wx.App):
def OnInit(self):
frame = TestFrame(self, 'Test wxPython + pyglet')
self.SetTopWindow(frame)
frame.Show(True)
return True
if __name__ == '__main__':
TestApp(redirect=False).MainLoop()
So what's the problem then?
Well I want to launch this from my pyglet app and not as a
standalone ,
but since it uses "MainLoop()" to run i can't and when I try to have
it
run in another thread with: (called from within my pyglet loop)
class testit(Thread):
def __init__ (self):
Thread.__init__(self)
def run(self):
TestApp(redirect=False).MainLoop()
I get this error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python25\lib\threading.py", line 462, in __bootstrap
self.run()
File "C:\sandbox\demo_dev\game.py", line 191, in run
TestApp(redirect=False).MainLoop()
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\_core.py",
line 7978, in __init__
self._BootstrapApp()
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\_core.py",
line 7552, in _BootstrapApp
return _core_.PyApp__BootstrapApp(*args, **kwargs)
File "C:\sandbox\demo_dev\wxtest.py", line 216, in OnInit
frame = TestFrame(self, 'Test wxPython + pyglet')
File "C:\sandbox\demo_dev\wxtest.py", line 198, in __init__
self.canvas = TestCanvas(self)
File "C:\sandbox\demo_dev\wxtest.py", line 106, in __init__
self._context._set_window(self)
File "C:\Python25\lib\site-packages\pyglet\window
\win32\__init__.py",
line 364, in _set_window
raise gl.ContextException('Unable to share contexts')
ContextException: Unable to share contexts
(I managed to get my stuff working with a subprocess call but then I
can't
communicate with the things that are in the pyglet loop wich I want to
(there is a mouseemulator application running and I don't want it to
click
on my keyboard since it gets focus and takes all it's own keypresses
then))
.. all I need is a way to update something from my pyglet loop and
draw it
in with the wx.App.MainLoop, or just skip the wx.App.MainLoop and only
have the pyglet loop. I don't need my pyglet window when running the
keyboard but I wan to be able to return to it once I'm done with the
keyboard...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pyglet-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/pyglet-users?hl=en
-~----------~----~----~----~------~----~------~--~---