Having problems with wxPython - HELP!!!

I’m desperately spending too much time trying to understand wxPython and it’s leading me nowhere.

I’m
trying to make a script that will create a window, and then immediately
fill this window with a background color. I also want to be able to
fill this window with a background color anytime I need to, therefore I
put it in a function called “InitBuffer()”.

Problem 1: Python doesn’t clear the window with “Grey” (my background color) when it is initially created. Why?
Problem
2: OnPaint() seems to always get called for whatever reason. Fine.
But I only want it to refresh the contents of the window. So, if I
draw to the Client window a series of rectangles, the ONLY thing I want
OnPaint() to do is refresh what has already been draw to the screen.
The ONLY time it should clear the screen is when I call InitBuffer().
How do I do this?

Here’s my code:

Mental Ray Thread

class runMentalRayThread(threading.Thread):
def init(self,sFile,renderWindow):
threading.Thread.init(self)
self.filename = sFile
self.threadID = os.getpid()
self.renderBuffer = renderWindow

# poll the file using yet another thread.  When that returns,
# capture the mental ray stream and render to the canvas.
def run(self):
    self.portInfo = queryMentalRay(self.filename)
    self.renderBuffer.InitBuffer()                     
    scanMR(self.portInfo[0], self.portInfo[1], self)   

Render Window

class RenderWindow(wx.Window):
def init(self,parent,ID,pos,size):
wx.Window.init(self,parent,ID,pos,size)
self.renderThread = runMentalRayThread(filename,self)
self.SetBackgroundColour(“Grey”)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.InitBuffer()

# Our initial buffer must be set and background cleared.  
def InitBuffer(self):
    print 'InitBuffer() called...'
    self.ClearBackground()
  
# Idle function.  Wait for a render
def OnIdle(self,event):
    if not self.renderThread.isAlive():
        print 'Starting thread to poll Mental Ray...'
        self.renderThread = runMentalRayThread(filename,self)
        self.renderThread.start()
  
# Refreshes the window.    
def OnPaint(self,event):
    print 'OnPaint() called...'
    dc = wx.PaintDC(self)
   

# Closing the render window, we need to
# kill the thread attached to Mental Ray.    
def OnClose(self,event):
    if self.renderThread.isAlive():
        # kill the thread
        os.popen("kill -9 "+str(self.renderThread.threadID))
···

Back to work after baby– how do you know when you’re ready?

This Wiki page should help clear things up for you:

http://wiki.wxpython.org/DoubleBufferedDrawing

There are other good ones in the Wiki -- poke around.

-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

I'm desperately spending too much time trying to understand wxPython
and it's leading me nowhere.

I'm trying to make a script that will create a window, and then
immediately fill this window with a background color. I also want to
be able to fill this window with a background color anytime I need to,
therefore I put it in a function called "InitBuffer()".

Problem 1: Python doesn't clear the window with "Grey" (my background
color) when it is initially created. Why?

Try subclassing a wx.Panel rather than wx.Window. I suspect that the
bare wx.Window doesn't support background colour on win32.

Problem 2: OnPaint() seems to always get called for whatever reason.
Fine. But I only want it to refresh the contents of the window. So,
if I draw to the Client window a series of rectangles, the ONLY thing
I want OnPaint() to do is refresh what has already been draw to the
screen. The ONLY time it should clear the screen is when I call
InitBuffer(). How do I do this?

You want to do double-buffered drawing. There are tutorials on this as
Chris pointed out. Try creating a wx.Bitmap the same size as your panel
client size. Draw stuff to this bitmap as you like, then copy the bitmap
onto the PaintDC within the OnPaint method of the panel. To force the
panel to get repainted ASAP, you can call .Refresh() on the panel (this
triggers a Paint event).

You should not make GUI calls directly from any other thread but the
main one. The correct way to communicate from threads to the mainloop of
a wx.App is to use (wx)Events. You *can* safely call wx.PostEvent from
other threads. One really useful function is wx.CallAfter(func). This
calls func in the main GUI thread, once control returns to the mainloop
(i.e. it's asynchonous). It uses Events internally. You can define your
own custom Events by subclassing wx.PyEvent.

···

On Fri, 2008-04-25 at 10:51 -0500, Marlin Rowley wrote:

Here's my code:

# Mental Ray Thread
class runMentalRayThread(threading.Thread):
    def __init__(self,sFile,renderWindow):
        threading.Thread.__init__(self)
        self.filename = sFile
        self.threadID = os.getpid()
        self.renderBuffer = renderWindow
        
    # poll the file using yet another thread. When that returns,
    # capture the mental ray stream and render to the canvas.
    def run(self):
        self.portInfo = queryMentalRay(self.filename)
        self.renderBuffer.InitBuffer()
        scanMR(self.portInfo[0], self.portInfo[1], self)
        
# Render Window
class RenderWindow(wx.Window):
    def __init__(self,parent,ID,pos,size):
        wx.Window.__init__(self,parent,ID,pos,size)
        self.renderThread = runMentalRayThread(filename,self)
        self.SetBackgroundColour("Grey")
        self.Bind(wx.EVT_IDLE, self.OnIdle)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.InitBuffer()
     
    # Our initial buffer must be set and background cleared.
    def InitBuffer(self):
        print 'InitBuffer() called...'
        self.ClearBackground()
       
    # Idle function. Wait for a render
    def OnIdle(self,event):
        if not self.renderThread.isAlive():
            print 'Starting thread to poll Mental Ray...'
            self.renderThread = runMentalRayThread(filename,self)
            self.renderThread.start()
       
    # Refreshes the window.
    def OnPaint(self,event):
        print 'OnPaint() called...'
        dc = wx.PaintDC(self)
        
    # Closing the render window, we need to
    # kill the thread attached to Mental Ray.
    def OnClose(self,event):
        if self.renderThread.isAlive():
            # kill the thread
            os.popen("kill -9 "+str(self.renderThread.threadID))

______________________________________________________________________
Back to work after baby– how do you know when you’re ready?
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users