Having problems with wxPython - HELP!!!

Marlin Rowley wrote:

class runMentalRayThread(threading.Thread):

...

        self.renderBuffer.InitBuffer() <<<<<<<<<<< Function call

you cant call wx calls directly from the thread. this needs to be something like:

    wx.CallAfter(self.renderBuffer.InitBuffer)

Though that's pretty coupled, I'd pass in a reference to the method you need called, instead of the Window.

I want to clear the window of all bitmaps at this point so I call the renderWindow.InitBuffer():

class RenderWindow(wx.Window):
    def __init__(self,parent,ID,pos,size):
        wx.Window.__init__(self,parent,ID,pos,size)

    # Our initial buffer must be set and background cleared. def InitBuffer(self):
        print 'InitBuffer() called...'
        size = self.GetClientSize()
        self.buffer = wx.EmptyBitmap(size.width,size.height)
        self.dc = wx.BufferedDC(None,self.buffer)

Here's your problem -- you've passed in None for the underlying DC, so you haven't connected to the Window at all. You need something like:

     dc = wx.BufferedDC(wx.CientDC(self), self.buffer)

        self.dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        self.dc.Clear()

You could also put a self.Refresh(); self.Update() in here -- that will force a paint event. In that case, you're Paint handler needs to look something like:

def OnPaint(self, evt):
     dc = wx.BufferedPaintDC(self, self.buffer)

Do read the DoubleBuffered page in teh Wiki.. Also look for "long running tasks"

I can access the device context that was created in the InitBuffer() function.

In general, you don't want to keep DCs around -- you keep the beffer around, then create an appropriate DC when you need to draw.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hello wxPython users!

I’ve written a red square in a pure RGB array (singular):

tileheight = 5
tilewidth = 5
rgb =
for h in range(tileheight):
for w in range(tilewidth):
for color in range(3):
if color == 0:
rgb.append(int(255))
else:
rgb.append(int(0))

          print rgb[len(rgb)-1]

when I try to call wx.BitmapFromBuffer(tilewidth,tileheight,rgb), I get this error:

File “C:\Python25\myTest.py”, line 11, in writeTile
tile = wx.BitmapFromBuffer( width,height,rgb )
File “C:\Python25\lib\site-packages\wx-2.8-msw-unicode\wx_gdi.py”, line 828, in BitmapFromBuffer
return gdi._BitmapFromBuffer(width, height, dataBuffer)
TypeError: expected a readable buffer object

What could be wrong?

-M

···

Date: Fri, 25 Apr 2008 15:04:57 -0700
From: Chris.Barker@noaa.gov
Subject: Re: [wxpython-users] Having problems with wxPython - HELP!!!
To: wxpython-users@lists.wxwidgets.org

Marlin Rowley wrote:

class runMentalRayThread(threading.Thread):

self.renderBuffer.InitBuffer() <<<<<<<<<<< Function call

you cant call wx calls directly from the thread. this needs to be
something like:

wx.CallAfter(self.renderBuffer.InitBuffer)

Though that’s pretty coupled, I’d pass in a reference to the method you
need called, instead of the Window.

I want to clear the window of all bitmaps at this point so I call the
renderWindow.InitBuffer():

class RenderWindow(wx.Window):
def init(self,parent,ID,pos,size):
wx.Window.init(self,parent,ID,pos,size)

Our initial buffer must be set and background cleared.

def InitBuffer(self):
print ‘InitBuffer() called…’
size = self.GetClientSize()
self.buffer = wx.EmptyBitmap(size.width,size.height)
self.dc = wx.BufferedDC(None,self.buffer)

Here’s your problem – you’ve passed in None for the underlying DC, so
you haven’t connected to the Window at all. You need something like:

dc = wx.BufferedDC(wx.CientDC(self), self.buffer)

self.dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
self.dc.Clear()

You could also put a self.Refresh(); self.Update() in here – that will
force a paint event. In that case, you’re Paint handler needs to look
something like:

def OnPaint(self, evt):
dc = wx.BufferedPaintDC(self, self.buffer)

Do read the DoubleBuffered page in teh Wiki… Also look for “long
running tasks”

I can access the device context that was created in the
InitBuffer() function.

In general, you don’t want to keep DCs around – you keep the beffer
around, then create an appropriate DC when you need to draw.

-Chris


Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov


wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users


Spell a grand slam in this game where word skill meets World Series. Get in the game.

Marlin Rowley wrote:

I've initialized an array like so:

rgba = zeros(tileWidth*tileHeight*4, Int)

Question: I've allocated space for storing a 32-bit integer for each index of the array even though my values have a limited range of (0-255). But wx.BitmapFromBufferRGBA() wants a stream of bytes (0-255). Should I make the array hold bytes instead of ints??

yes, exactly:

import numpy as np
rgba = np.zeros((tileWidth,tileHeight,4), np.uint8)

you could get an array the same size with:

np.zeros(tileWidth*tileHeight, np.int32)

but I like the above, because you can index into it like so:

red = rgba[:,:,0]
blue = rgba[:,:,1]

The top row of pixels: rbga[0,:,:]

etc, etc, etc.

Note that another poster here is doing something similar, but he built his array like so:

rgba = numpy.empty(shape, (numpy.uint32, {'r':(numpy.uint8,0), \
                                                'g':(numpy.uint8,1), \
                                                'b':(numpy.uint8,2), \
                                                'a':(numpy.uint8,3)}))

which is a bit of "record array" magic that I don't quite get, but it lets you do:

red = rgba['r']

etc... Kind of cool. I'm not totally sure if the bytes are arranged the right way though.

See the other thread for more...

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov