[wxPython] Reinserting Image to Sizer

Hi!

I can display an jpeg-files with wxStaticBitmap an wxBoxSizer. But
what do I need to do if I want to display an different Image? I want
to create a slide show where you have a "prev" and "next" button. The
images have different sizes.

self.bitmap=wxStaticBitmap(self, ID_NULL, jpg, wxPoint(0, 0),
           wxSize(jpg.GetWidth(), jpg.GetHeight()))
#The first time it works
sizer_image_buttons.Add(self.bitmap, 1, wxEXPAND)

#The second time the sizer puts the image at the left buttom
self.bitmap=wxStaticBitmap(self, ID_NULL, jpg, wxPoint(0, 0),
       wxSize(jpg.GetWidth(), jpg.GetHeight()))
#This does not help
self.sizer.Fit(self)

I tried a lot of combinations of Layout() and Refresh() but the all
failed. The old image is still there behind the new.

I tried Clear(), but Frame doesn't know this method.

thomas

···

--
Thomas Guettler <guettli@thomas-guettler.de>
http://www.thomas-guettler.de

Thomas Guettler wrote:

#This does not help
self.sizer.Fit(self)

I tried a lot of combinations of Layout() and Refresh() but the all
failed. The old image is still there behind the new.

I'm not sure that this is the most effective way to deal withthis, but I've had luck
using sizer.RecalcSizes(), possibly followed with a Refresh().

Jeff Shannon
Technician/Programmer
Credit International

I can display an jpeg-files with wxStaticBitmap an wxBoxSizer. But
what do I need to do if I want to display an different Image? I want
to create a slide show where you have a "prev" and "next" button. The
images have different sizes.

You'll probably be better off just creating your own window that can display
a bitmap in its EVT_PAINT handler.

self.bitmap=wxStaticBitmap(self, ID_NULL, jpg, wxPoint(0, 0),
wxSize(jpg.GetWidth(), jpg.GetHeight()))
#The first time it works
sizer_image_buttons.Add(self.bitmap, 1, wxEXPAND)

#The second time the sizer puts the image at the left buttom
self.bitmap=wxStaticBitmap(self, ID_NULL, jpg, wxPoint(0, 0),
wxSize(jpg.GetWidth(), jpg.GetHeight()))
#This does not help
self.sizer.Fit(self)

I tried a lot of combinations of Layout() and Refresh() but the all
failed. The old image is still there behind the new.

Because you are just creating a new wxStaticBitmap the original
wxStaticBitmap window still exists and so it still displays the original
image. It is not displayed where you expect because the new window is not
added to the sizer...

If you don't want to attempt using your own window then you can use the
static bitmap but only create one of them and just reset it's image when
needed. Someting like this:

    self.bitmap.SetBitmap(new_image)
    self.bitmap.SetSize(wxSize(new_image.GetWidth(), new_image.GetHeight()))
    self.sizer.SetItemMinSize(self.bitmap.GetSize())
    self.Layout()

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Hi all,

I am developing a data-acquisition application in Python/wxPython, where
I use two threads; The main thread handles the GUI and a second
worker-thread handles the data-acquisition in a separate loop.

My problem is that the wxPython event-handler functions seem to hold a
global lock which prevents the second worker thread from processing
until the event-handler function returns control to the wxPython
Mainloop. Thus, if my event-handler function (e.g. to update a graph)
takes too long, the data-acquisition is interupted for an unacceptably
long time.

I don't see a fundamental reason why the event-handlers MUST retain a
lock. Provided secondary threads don't interfere with the main thread,
things ought to be able to process in parallel just fine.

Is the lock part of the wxPython bindings, or is it something more
funcdamental to wxWindows?

Is it possible to override this behaviour, such that secondary threads
continue to execute **during** the execution of the event-handler /
callback functions?

I'd be grateful for any help/advice on this.
thanks,

Bryan

···

--
Bryan Cole
Teraview Ltd., 302-304 Cambridge Science Park, Milton Road, Cambridge
CB4 0WG, United Kingdom.
tel: +44 (1223) 435380 / 435386 (direct-dial) fax: +44 (1223) 435382

I have a clearer picture of what's going on here:

Normally, wxPython event processing does **not** interupt other threads.
However, in my secondary thread, I'm issuing events using the
wxPostEvent() function. It appears that the wxPostEvent() function
cannot return while wxPython is in the middle of executing an Event
Handler function. wxPostEvent() returns once the mainloop continues
processing

Anyone got any ideas for getting round this? Maybe it's a wxWindows
issue. I can try to remove all wxPostEvent calls, but this means I've
got to implement my own method of communication between threads.

Interestingly, the only reason this doesnot cause problems for the
wxPython Threads Demo, is that the wxPostEvent call is place right at
the start of the CalcBarThread::Run() function; with a fairly "slow"
thread loop, this means that when OnCloseWindow is called, it is
statistically most likely that wxPostEvent has already finished and
execution can proceed uninterupted to the end of the loop. However,
there are no guarantees that OnCloseWindow will not be called just prior
to executing the wxPostEvent function and hence "hang" on quitting the
window.

Bryan

···

On Sun, 2002-04-21 at 12:29, bryan cole wrote:

Hi all,

I am developing a data-acquisition application in Python/wxPython, where
I use two threads; The main thread handles the GUI and a second
worker-thread handles the data-acquisition in a separate loop.

My problem is that the wxPython event-handler functions seem to hold a
global lock which prevents the second worker thread from processing
until the event-handler function returns control to the wxPython
Mainloop. Thus, if my event-handler function (e.g. to update a graph)
takes too long, the data-acquisition is interupted for an unacceptably
long time.

I don't see a fundamental reason why the event-handlers MUST retain a
lock. Provided secondary threads don't interfere with the main thread,
things ought to be able to process in parallel just fine.

Is the lock part of the wxPython bindings, or is it something more
funcdamental to wxWindows?

Is it possible to override this behaviour, such that secondary threads
continue to execute **during** the execution of the event-handler /
callback functions?

I'd be grateful for any help/advice on this.
thanks,

Bryan

--
Bryan Cole
Teraview Ltd., 302-304 Cambridge Science Park, Milton Road, Cambridge
CB4 0WG, United Kingdom.
tel: +44 (1223) 435380 / 435386 (direct-dial) fax: +44 (1223) 435382

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

--
Bryan Cole
Teraview Ltd., 302-304 Cambridge Science Park, Milton Road, Cambridge
CB4 0WG, United Kingdom.
tel: +44 (1223) 435380 / 435386 (direct-dial) fax: +44 (1223) 435382

Normally, wxPython event processing does **not** interupt other threads.
However, in my secondary thread, I'm issuing events using the
wxPostEvent() function. It appears that the wxPostEvent() function
cannot return while wxPython is in the middle of executing an Event
Handler function. wxPostEvent() returns once the mainloop continues
processing

Anyone got any ideas for getting round this? Maybe it's a wxWindows
issue.

Could be... wxPostEvent calls AddPendingEvent on the evtHandler object you
give it, and it does this (in pseudo code):

    enter critical section(self.eventsLocker)
    append event to pending event list
    leave critical section

    enter critical section(global eventsLocker)
    append self to objects with pending events list
    leave critical section

Later on in idle time ProcessPendingEvents will be called, and it does this:

    enter critical section(self.eventsLocker)
    while items in pending event list
        node = first pending event list item
        delete node
        leave critical section
        call ProcessEvent
        enter critical section(self.eventsLocker)
    leave critical section

So while there are certainly locks happening that will block the threads it
looks like it is released while the event handler code is actually being
called.

The other possibility is Python's Global Interpreter Lock which allows only
one thread to be in the interpreter at a time. This lock is released every
time there is a Python --> wxWindows method call and it is aquired for
wxWindows --> Python calls such as event handlers and virtual callbacks.
While Python code is running it is supposed to periodically release and
reaquire the GIL to allow other python threads to run. I've gone over how
wxPython deals with the GIL several times and feel real confident that it is
done right, but I suppose the possibility of a problem is there.

If you want to want to dive into this further let me know and I can let you
know where in the C++ code to look.

I can try to remove all wxPostEvent calls, but this means I've
got to implement my own method of communication between threads.

You could use the Queue in the standard Python lib. It is thread safe so
you can add objects to it from multiple threads and then read items from it
in an idle handler in the GUI thread. Just call wxWakeUpIdle() each time
you add an item to ensure that the idle processor will run soon.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!