Using Pyglet in a rich GUI

630 views
Skip to first unread message

Dave

unread,
Feb 8, 2009, 3:48:54 PM2/8/09
to pyglet-users
This has been discussed before

http://groups.google.com/group/pyglet-users/browse_thread/thread/9ef5daa879fabe51/d29a88ff72509f5c?lnk=gst&q=gui#d29a88ff72509f5c

http://groups.google.com/group/pyglet-users/browse_thread/thread/8251625af4a9db0f/fdd3a742ed6e88e7?lnk=gst&q=gui#fdd3a742ed6e88e7

http://groups.google.com/group/pyglet-users/browse_thread/thread/4265d4e6cb18e341/f6c264c5d0523e5e?lnk=gst&q=gui#f6c264c5d0523e5e

But the most recent such discussion was a year ago. In the intervening
year, has there evolved a canonical pattern for using Pyglet to do
drawing as one part of a richer GUI application that includes nice-
looking buttons/menus/etc? For example, integrating with wx, or qt, or
tkinter, or using some other gui classes in conjunction with pyglet?

Or is it suggested not to use Pyglet if one requires more advanced ui
controls than keyboard and mouse clicks on a canvas? I saw a design
document that appeared to indicate there are plans for building richer
widgets directly into Pyglet:

http://code.google.com/p/pyglet/source/browse/branches/holkner_1/DESIGN

Is this still a long ways off?

Dave

__doc__

unread,
Feb 9, 2009, 5:57:30 AM2/9/09
to pyglet-users
I rolled my own GUI library that's specific to some needs I have for a
device configuration frontend. It is part of deviceconf, see
http://codeflow.org/projects/deviceconf/ for screenies.

Laurens Simonis

unread,
Feb 9, 2009, 6:18:39 AM2/9/09
to pyglet...@googlegroups.com
Hi!

I too am interested in this. I'd love a how-to for wxpython, personally.

Cheers!

Laurens

Simon Veith Reinholt

unread,
Feb 9, 2009, 1:51:28 PM2/9/09
to pyglet-users
If you get the source (eg. from SVN) there's a very simple example of
a pyglet/wxPython integration in the source/experimental/ folder.

I've successfully used this example as a base for an editor, even
using XRC. I was using Windows, so I don't know about performance on
other os'.

If you already have a working wxPython application, or have previous
experience with it, you can simply consider it a custom widget and
drop it in your existing codebase. In the example, the TestFrame is
your main application window, and the TestCanvas is where you do your
OpenGL/pyglet magic.

However, I don't know how this integrates with a game loop, meaning
that in the example there is no update function scheduled, so you will
only get to redraw your opengl context when the operating system finds
it is time to redraw your window. I'm sure this can be worked around
somehow, but for an editor it is not necessary, and actually a
blessing. :)

The example from the pyglet sourc is called wxtest.py but the current
SVN version is a little out of date. You'll have to change this line:

label = pyglet.text.Label('Hello, world', font_size=48,
valign='center', halign='center')

into this:

label = pyglet.text.Label('Hello, world', font_size=48,
anchor_x='center', anchor_y='center')


I guess I never got at chance to say thank you to whoever created this
excellent wxpython example in the experimental folder. So, thanks!
Great work! :)


-Simon

Alex Holkner

unread,
Feb 9, 2009, 4:21:17 PM2/9/09
to pyglet...@googlegroups.com

Thanks, fixed in r2438.

> I guess I never got at chance to say thank you to whoever created this
> excellent wxpython example in the experimental folder. So, thanks!
> Great work! :)

No problem. Note that the integration only works on Windows/Linux (not OS X).

Alex.

Dave

unread,
Feb 9, 2009, 8:40:43 PM2/9/09
to pyglet-users
Thanks. I ran that file earlier but I figured the error meant that it
was an abandoned project.

Dave

Rayene Ben Rayana

unread,
Feb 10, 2009, 3:08:59 PM2/10/09
to pyglet...@googlegroups.com
Hi __doc__,

Your GUI works like a charm. Great job!

I extracted the GUI code from your deviceconf project and I am using it as a standalone library.
I added drag&drop support for the dialog. Now it is possible to move it all around the window.

I also added a small grip in the bottom right of the dialog to be able to resize it.
It does not work yet, I did not figure out what widget have to be resized to get
the dialog box resized. I'm also going to add a 2D plot widget on the basis of the Graph class,
a display picture on the basis of the Close class and and maybe a python console dialog.

I was wondering if it is possible to store the code somewhere in pyglet's contrib or in your
repository and develop it ? And, yes, what name would you give it ? :)

Rayene,

__doc__

unread,
Feb 11, 2009, 5:44:14 AM2/11/09
to pyglet-users
On Feb 10, 9:08 pm, Rayene Ben Rayana <rayene.benray...@gmail.com>
wrote:
> Your GUI works<http://picasaweb.google.com/lh/photo/qcWBTUO-IywTVW-xOeqfHQ?feat=dire...>like
> a charm. Great job!
Thanks :)

> I extracted the GUI code from your deviceconf project and I am using it as a
> standalone library.
I didn't do it yet because its kind of in flux for me, and I think its
all a bit hacky.

> I also added a small grip in the bottom right of the dialog to be able to
> resize it.
> It does not work yet, I did not figure out what widget have to be resized to
> get the dialog box resized.
That'd probably be a bit of problem, because the layout is inside out.
It means that the children of a widget determine the widgets size, and
if the children resize, they trigger a relayout to the parent. However
there's no constraint system that applies layout constraints back to
children.

> I was wondering if it is possible to store the code somewhere in pyglet's
> contrib or in your
> repository and develop it ? And, yes, what name would you give it ? :)
I prefer mercurial repositories rather then svn ones. For sharing and
collaboration with mercurial
I could recommend http://bitbucket.org/ (I might clone/pull from there
to my own repo).

I haven't thought of a name really, maybe you could call it something
like pgwidgets, pgwk, glwidgety, etc.

Cheers, Florian

Python Nutter

unread,
Feb 12, 2009, 1:03:01 AM2/12/09
to pyglet...@googlegroups.com
heh. if the child control the parent why not call it

littlepiggies

import littlepiggies

littlepiggies.watchthemrun()

;-P


2009/2/11 __doc__ <pya...@gmail.com>:

Rayene Ben Rayana

unread,
Feb 12, 2009, 8:07:18 AM2/12/09
to pyglet...@googlegroups.com
Liltlle Piggies :) Although I like the beatles, I never heard that song before today. It can be a funny name !

I also thought of PyGloss (For Pyglet-Gloss). A google search for "pygloss" returned no more than 2 results. Some small modifications can add glossy effects to the widgets.

Naveen

unread,
Feb 23, 2009, 11:10:16 AM2/23/09
to pyglet-users

Hi Rayene,

Would you be willing to share the code you extracted from __doc__'s
program (with your drag and drop additions)? It looks like the start
of a nice UI to overlay on pyglet! Thanks

Naveen

On Feb 12, 8:07 am, Rayene Ben Rayana <rayene.benray...@gmail.com>
wrote:
> Liltlle Piggies :) Although I like the beatles, I never heard that song
> before today. It can be a funny name !
>
> I also thought of PyGloss (For Pyglet-Gloss). A google search for "pygloss"
> returned no more than 2 results. Some small modifications can add glossy
> effects to the widgets.
>
> > > I could recommendhttp://bitbucket.org/(I might clone/pull from there

Lynx

unread,
Feb 23, 2009, 6:12:13 PM2/23/09
to pyglet-users
On Feb 9, 10:51 am, Simon Veith Reinholt <reinh...@gmail.com> wrote:
> If you get the source (eg. from SVN) there's a very simple example of
> a pyglet/wxPython integration in the source/experimental/ folder.

I've been playing with wxPython/Pyglet but I've run into a problem, I
can't seem to make the wx.BoxSizers work in the WxCanvas it provides.
They never seem to want to expand to fill the available space in the
client. Has anyone else tried sizers or other layout tools for
wxPython/Pyglet?

Laurens Simonis

unread,
Feb 24, 2009, 6:37:21 AM2/24/09
to pyglet...@googlegroups.com
> I've been playing with wxPython/Pyglet but I've run into a problem, I
> can't seem to make the wx.BoxSizers work in the WxCanvas it provides.
> They never seem to want to expand to fill the available space in the
> client. Has anyone else tried sizers or other layout tools for
> wxPython/Pyglet?

Have you tried setting the sizer's proportion to (at least) 1 and set wx.EXPAND?
I use wxPython here at work, but not in combination with pyglet.

Cheers!

Laurens

Lynx

unread,
Feb 24, 2009, 10:45:57 AM2/24/09
to pyglet-users
On Feb 24, 3:37 am, Laurens Simonis <pyg...@laurenssimonis.com> wrote:
> Have you tried setting the sizer's proportion to (at least) 1 and set wx.EXPAND?
> I use wxPython here at work, but not in combination with pyglet.

Yup. EXPAND works as expected in a plain wxPython window, but not in
WxCanvas.

My impression is that it's paying attention to what elements have
already been created in the window, and WxCanvas is being counted as
an element, *not* as a panel in which things can be laid out.

-- Conrad

Simon Veith Reinholt

unread,
Feb 24, 2009, 12:46:04 PM2/24/09
to pyglet-users


> I've been playing with wxPython/Pyglet but I've run into a problem, I
> can't seem to make the wx.BoxSizers work in the WxCanvas it provides.
> They never seem to want to expand to fill the available space in the
> client.  Has anyone else tried sizers or other layout tools for
> wxPython/Pyglet?

I solved this by creating a Panel to which I only add 1 element, the
wxCanvas in a boxsizer. In a sense, you can hide the wxCanvas from the
wxPython by adding it to a Panel in this way. No other code needs to
know that the panel contains a pyglet window.

This was useful for other reasons, such as separating the canvas
drawing code from the editor input code: In MainEditorPanel.PostInit()
I bind events on the canvas to callbacks on the panel.

Here is a cut-down version of my code. It doesn't run or anything, but
you could probably compare it to your own. Note that I use XRC
resources for constructing the actual window layout, so just ignore
the PrePanel() and PostCreate() stuff if you are not.

class EditorCanvas(WxCanvas):
def __init__(self, parent, id=-1, config=None, context=None):
canvas.WxCanvas.__init__(self, parent, id, config, context)

def on_draw(self):
pass

def on_resize(self,w2,h2):
pass

def redraw(self):
self.Refresh(True)

class MainEditorPanel(wx.Panel):
def __init__(self):
pre = wx.PrePanel()
self.PostCreate(pre)
self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)

def OnCreate(self, event):
self.Unbind(wx.EVT_WINDOW_CREATE)
wx.CallAfter(self._PostInit)
event.Skip()
return True

def _PostInit(self):
# Do all init here
self._canvas = EditorCanvas(self)

self.sizer = wx.BoxSizer()
self.sizer.Add(self._canvas,1,wx.EXPAND)
self.SetSizer(self.sizer)
self.SetAutoLayout(1)
self.sizer.Fit(self)

self._canvas.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self._canvas.Bind(wx.EVT_MOTION, self.OnMouseMotion)
self._canvas.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

Lynx

unread,
Feb 24, 2009, 11:44:07 PM2/24/09
to pyglet-users
On Feb 24, 9:46 am, Simon Veith Reinholt <reinh...@gmail.com> wrote:
> I solved this by creating a Panel to which I only add 1 element, the
> wxCanvas in a boxsizer. In a sense, you can hide the wxCanvas from the
> wxPython by adding it to a Panel in this way. No other code needs to
> know that the panel contains a pyglet window.

I'm a little lost - how do you then add another sizer that lets you
overlay elements on top of the WxCanvas? I've tried a few variations
but it seems like wxBoxSizer always intends that controls be laid out
in separate boxes that may not overlap each other.

Rayene Ben Rayana

unread,
Feb 25, 2009, 6:23:03 AM2/25/09
to pyglet...@googlegroups.com
Hi Naveen,

I had too much work these last days !
I'll send the link with another mail subject since this one became a bit schizophrenic :)

Rayene,

Simon Veith Reinholt

unread,
Feb 25, 2009, 12:02:55 PM2/25/09
to pyglet-users
I think you should treat the MainEditorPanel as your pyglet window as
far as wxPython is concerned. That means keeping the canvas inside the
panel and not adding any more to that panel. If you want to have
additional, "regular", wxPython controls, they should be layed out in
another panel altogether.
If for example you need a tree control alongside the pyglet window,
you would add the tree control to your main frame, and the
MainEditorPanel also to the main frame, then use your favourite sizer
to position the tree control and the MainEditorPanel.

I hope that makes more sense. Or may be I've completely misunderstood
you?
In any case, choosing a sizer that lets controls be overlapped, is
probably a wxPython question which I'm not the right person to answer.

-Simon

Lynx

unread,
Feb 25, 2009, 6:57:59 PM2/25/09
to pyglet-users
On Feb 25, 9:02 am, Simon Veith Reinholt <reinh...@gmail.com> wrote:
> If for example you need a tree control alongside the pyglet window,
> you would add the tree control to your main frame, and the
> MainEditorPanel also to the main frame, then use your favourite sizer
> to position the tree control and the MainEditorPanel.
>
> I hope that makes more sense. Or may be I've completely misunderstood
> you?
> In any case, choosing a sizer that lets controls be overlapped, is
> probably a wxPython question which I'm not the right person to answer.

Okay - thanks, and yes, that's indeed the case, I'm looking to arrange
controls that sit on top of the WxCanvas. Evidently I'll have to look
for something other than the manual-recommended BoxSizers for the job!

Matthew Edwards

unread,
Feb 25, 2009, 9:42:18 PM2/25/09
to pyglet...@googlegroups.com
On Thu, Feb 26, 2009 at 12:57 PM, Lynx <cw....@gmail.com> wrote:

> Okay - thanks, and yes, that's indeed the case, I'm looking to arrange
> controls that sit on top of the WxCanvas.  Evidently I'll have to look
> for something other than the manual-recommended BoxSizers for the job!

I don't know if this makes sense for your situation, but could you
instead have multiple Canvases (in Panels) and use them as individual
controls, mixed in with standard controls and laid out by a standard
Sizer? What are you drawing in the Canvas?

Lynx

unread,
Feb 25, 2009, 9:46:04 PM2/25/09
to pyglet-users
On Feb 25, 6:42 pm, Matthew Edwards <cheeseboy...@gmail.com> wrote:
> I don't know if this makes sense for your situation, but could you
> instead have multiple Canvases (in Panels) and use them as individual
> controls, mixed in with standard controls and laid out by a standard
> Sizer? What are you drawing in the Canvas?

The game map, units moving around on the map. I'd hoped to use
wxPython for the in-game UI, since it does have bitmap buttons and
other customizable controls!

Matthew Edwards

unread,
Feb 25, 2009, 10:15:38 PM2/25/09
to pyglet...@googlegroups.com
On Thu, Feb 26, 2009 at 3:46 PM, Lynx <cw....@gmail.com> wrote:
> The game map, units moving around on the map.  I'd hoped to use
> wxPython for the in-game UI, since it does have bitmap buttons and
> other customizable controls!

Are you just talking about menus and dialogs and things, or are you
going to have controls scattered throughout the window instead of in
particular groups? Could you use a panel for a dialog and only use
sizers to lay out the controls for that dialog?

Lynx

unread,
Feb 26, 2009, 1:48:59 AM2/26/09
to pyglet-users
On Feb 25, 7:15 pm, Matthew Edwards <cheeseboy...@gmail.com> wrote:
> Are you just talking about menus and dialogs and things, or are you
> going to have controls scattered throughout the window instead of in
> particular groups? Could you use a panel for a dialog and only use
> sizers to lay out the controls for that dialog?

I intend to have controls actually on top of the game display.

Found a working method!

class TestPanel(wx.Panel):
def __init__(self, parent, id=-1):
wx.Panel.__init__(self, parent, id)
self.SetAutoLayout(True)

gamePanel = TestCanvas(self)
lc = wx.LayoutConstraints()
lc.left.SameAs(self, wx.Left, 0)
lc.right.SameAs(self, wx.Right, 0)
lc.top.SameAs(self, wx.Top, 0)
lc.bottom.SameAs(self, wx.Bottom, 0)
gamePanel.SetConstraints(lc)

ulPanel = wx.Window(self, -1)
ulText = wx.StaticText(ulPanel, -1, "Upper Left")
width, height = ulText.GetSize()
lc = wx.LayoutConstraints()
lc.top.SameAs(self, wx.Top, 10)
lc.left.SameAs(self, wx.Left, 10)
lc.width.Absolute(width)
lc.height.Absolute(height)
ulPanel.SetConstraints(lc)

lrPanel = wx.Window(self, -1)
lrText = wx.StaticText(lrPanel, -1, "Lower Right")
width, height = lrText.GetSize()
lc = wx.LayoutConstraints()
lc.bottom.SameAs(self, wx.Bottom, 10)
lc.right.SameAs(self, wx.Right, 10)
lc.width.Absolute(width)
lc.height.Absolute(height)
lrPanel.SetConstraints(lc)

As far as I can tell, LayoutConstraints won't poll their children to
find out the best size, so you have to give them enough information
that they can determine all 4 sides - hence, the code above that
checks the width of the text so that they can be positioned at the
extreme corners. This code gives them a 10 pixel margin.

Excellent! Now to re-factor my code. o_o

Lynx

unread,
Feb 26, 2009, 2:09:35 AM2/26/09
to pyglet-users
On Feb 25, 10:48 pm, Lynx <cw.l...@gmail.com> wrote:
>         ulPanel = wx.Window(self, -1)
>         lc.top.SameAs(self, wx.Top, 10)
>         lc.left.SameAs(self, wx.Left, 10)

Found a bug - these panels must be made children of the GamePanel, not
of TestPanel, so that they'll still be displayed properly when the
window gets resized, otherwise they vanish.
Reply all
Reply to author
Forward
0 new messages