Unhandled exception

Oh, another great tip! I didn't realise this at first - I thought you
were saying 'wx.CallAfter', till I realised that it was wx.CallLater,
which at first glance looks the same, but is different. Didn't know
about this. It will be another very useful method for me to use.

···

On Aug 8, 1:10 am, werner <wbru...@free.fr> wrote:

> was actually contemplating setting up timer

then you could use wx.CallLater :slight_smile:

By the way, I tried passing the evt object in CallAfter but it doesn't
work. The evt object seems to be gone by the time CallAfter's method
is executed... Have to use eventObject instead.

···

On Aug 8, 12:28 pm, Sam23 <qm0...@gmail.com> wrote:

On Aug 8, 1:10 am, werner <wbru...@free.fr> wrote:> > was actually contemplating setting up timer

> then you could use wx.CallLater :slight_smile:

Oh, another great tip! I didn't realise this at first - I thought you
were saying 'wx.CallAfter', till I realised that it was wx.CallLater,
which at first glance looks the same, but is different. Didn't know
about this. It will be another very useful method for me to use.

Sorry, I mean CallLater, and not CallAfter in the above message. evt
is still available if using CallAfter, but not when using CallLater.

···

On Aug 8, 1:37 pm, Sam23 <qm0...@gmail.com> wrote:

By the way, I tried passing the evt object in CallAfter but it doesn't
work. The evt object seems to be gone by the time CallAfter's method
is executed... Have to use eventObject instead.

I see that you've already solved this, but here is some more info for the record.

Sam23 wrote:

The problem seems to be that the window from which an event originates cannot be destroyed in the event handler for the event. This is a concern for me since my design involves the destruction the of the window in which the event originates.

Correct. The window is still used as control flows out of the event handler and back to the main loop. So if the window has been destroyed before that code tries to access it then it is using a bad pointer to access memory that no longer belongs to the program. Also, there are likely other pending events waiting for it which will have the same problem.

When you Destroy() top level windows they automatically delay the actual destruction until after the next idle event to be sure that there are no pending messages waiting for the window. For various reasons the Destroy() of non TLWs does not do that, but you can approximate the same thing using wx.CallAfter as Werner suggested.

···

--
Robin Dunn
Software Craftsman

Sam23 wrote:

I tested it and found that it works. Interestingly, I tried passing
the event itself (evt) instead of the eventObject, and it still worked
- i.e. the event was still available after event handling had ended.
Hopefully, this won't be a trip point somewhere else along the way!

It might be, depending on the kind of event and the situation and how long it is until you try to use it. You'll be better off to not use it this way.

···

--
Robin Dunn
Software Craftsman

Robin,
Thank for the clarification. I have a follow up question.

Will a wx.CallAfter called by the main thread always execute before
wx.CallAfter called by a parallel thread, regardless of whether the
wx.CallAfter was called by the parallel thread first?

The reason I am asking is because I intend to have an independent
thread monitoring database changes. This will use wx.CallAfter to call
a method in the main thread if there are database changes. I want to
know if I can count on a main thread wx.CallAfter to always run first,
finishing the 'event handling' sequence, or if I need to take care of
the priority for wx.CallAfter's to ensure this.

Cheers
Sam

···

On Aug 11, 2:25 am, Robin Dunn <ro...@alldunn.com> wrote:

When you Destroy() top level windows they automatically delay the actual
destruction until after the next idle event to be sure that there are no
pending messages waiting for the window. For various reasons the
Destroy() of non TLWs does not do that, but you can approximate the same
thing using wx.CallAfter as Werner suggested.

Sam23 wrote:

···

On Aug 11, 2:25 am, Robin Dunn <ro...@alldunn.com> wrote:

When you Destroy() top level windows they automatically delay the actual
destruction until after the next idle event to be sure that there are no
pending messages waiting for the window. For various reasons the
Destroy() of non TLWs does not do that, but you can approximate the same
thing using wx.CallAfter as Werner suggested.

Robin,
Thank for the clarification. I have a follow up question.

Will a wx.CallAfter called by the main thread always execute before
wx.CallAfter called by a parallel thread, regardless of whether the
wx.CallAfter was called by the parallel thread first?

No. wx.CallAfter results in an event being added to the pending event queue, and those events are processed in the order they were added to the queue.

--
Robin Dunn
Software Craftsman

OK thanks. I think this makes sense; wx cannot predict what the
application requirement is - in some scenarios, it might be good for
the queued event from a parallel thread to get processed first, e.g.
to set a flag to interrupt the further execution of event handling or
initiate a graceful stop for further event processing.

I have also thought about my concern further and realised there is a
simple solution.

My concern: was that by calling wx.CallAfter in the middle of my event
handling, I effectively split the event handling into 2 parts;
separated possibly by other intervening events in the queue; and that
this might have an 'interference' effect.

The solution: I can simply call wx.CallAfter at the beginning of the
event handler, rather than midway (after extracting the necessary
event info, e.g. eventObject); thus ensuring that all event handling
code that should be in a single execution sequence are run
contiguously (after wx.CallAfter).

···

On Aug 12, 3:36 am, Robin Dunn <ro...@alldunn.com> wrote:

> Will a wx.CallAfter called by the main thread always execute before
> wx.CallAfter called by a parallel thread

No. wx.CallAfter results in an event being added to the pending event
queue, and those events are processed in the order they were added to
the queue.

Sam23 wrote:

My concern: was that by calling wx.CallAfter in the middle of my event
handling, I effectively split the event handling into 2 parts;
separated possibly by other intervening events in the queue; and that
this might have an 'interference' effect.

No, absolutely not. Calling wx.CallAfter only posts an event to the app's pending event queue with the details about the callable and the parameters, it does not actually call the callable object at that point in time. That only happens "after" (hence the name) the current event handler or callback returns to the main loop, any pending system events have been dispatched and handled, and any other prior events in the app's pending event queue have been processed.

···

--
Robin Dunn
Software Craftsman

Yes, I did understand that aspect of wx.CallAfter. Based on your
explanation in the earlier mails regarding control returning back to
main loop and also the your explanation on the way Skip() works, I did
figure out that CallAfter only calls After the current event handler
ends. My 'concern' wasn't due to a misunderstanding of when
wx.CallAfter executes its callable.

I may have been too brief in describing the concern; and the proposed
solution. Let me explain with these scenarios based on my
application.

---- Scenario A : Intermittent Unhandled exception
OnLeftUp event triggers event handler: Method A which does the
following:
* Prelim checks on what was clicked and required response
* Performs database updates
* resetCalPanels(): Destroys panels: one of which is the source of the
event.
* redrawCalPanels(): Redraws panels (requires database reads); putting
them on a GridBagSizer.
* some finalising code

Scenario A crashes intermittently with 'unhandled exception' because
resetCalPanels destroy the panel which is the source of the event,
prior to the completion of event processing

---- Scenario B : python Add to GridBagSizer exception
OnLeftUp event triggers event handler: Method A which does the
following:
* Prelim checks on what was clicked and required response
* Performs database updates

* wx.CallAfter(resetCalPanels()..: Destroys panels: one of which is
the source of the event.

* redrawCalPanels(): Redraws panels (requires database reads);
putting them on a GridBagSizer
* some finalising code

Scenario B is coded based on misunderstanding of when wx.CallAfter
executes. It will always crash when redrawCalPanels creates the
panels and adds them to the GridBagSizer because at this time,
resetCalPanels hasn't run yet; i.e. the positions in the GridBagSizer
are still occupied by the panels which have yet to be destroyed.

---- Scenario C : * my concern * event handler split across time
OnLeftUp event triggers event handler: Method A which does the
following:
Method A
* Prelim checks on what was clicked and required response
* Performs database updates
* wx.CallAfter(Method_B)

Method_B
* resetCalPanels(): Destroys panels: one of which is the source of the
event.
* redrawCalPanels(): Redraws panels (requires database reads);
putting them on a GridBagSizer
* some finalising code

This example will work without crashing. It is what I have changed my
code to doing at the moment. It shows my concern: the event handler is
now split in time across 2 methods calls. In most cases, this is fine,
but in some cases, it is possible that an intervening event from
another event source has altered the database or some other resource
in a way that interferes with the expected state of resources (db,
screen, etc) during the code execution in Method_B

---- Scenario D : * my proposed solution * ensure event handler is not
split across time
OnLeftUp event triggers event handler: Method A which does the
following:
Method A
* get required event parameters e.g. eventObject: the event source
* wx.CallAfter(Method_B, eventSource)

Method_B
* Prelim checks on what was clicked and required response
* Performs database updates
* resetCalPanels(): Destroys panels: one of which is the source of the
event.
* redrawCalPanels(): Redraws panels; putting them on a GridBagSizer
* some finalising code

This ensures that the code for the event handler is part of a single
continguous execution, without any coding gymnastics required in
preempting interference. Method_A is simply a dummy method to defer
event processing by 'one step' to preempt any problems caused by
destruction of resources required in the 'original' event handler.

Just some thoughts on this issue. Let me know if I am still offtrack.
Will be good to be ontrack finally :slight_smile:

Thanks again.

···

On Aug 13, 2:47 pm, Robin Dunn <ro...@alldunn.com> wrote:

Sam23 wrote:

> My concern: was that by calling wx.CallAfter in the middle of my event
> handling, I effectively split the event handling into 2 parts;

No, absolutely not. Calling wx.CallAfter only posts an event to the
app's pending event queue with the details about the callable and the
parameters, it does not actually call the callable object at that point
in time.

Sam23 wrote:

This ensures that the code for the event handler is part of a single
continguous execution, without any coding gymnastics required in
preempting interference. Method_A is simply a dummy method to defer
event processing by 'one step' to preempt any problems caused by
destruction of resources required in the 'original' event handler.

Just some thoughts on this issue. Let me know if I am still offtrack.

IIUC, then yes, I think you are on the right track. With the additional suggestion that if there is anything that can still be destroyed before you use it then check if it's still alive first.

BTW, how many panels or other widgets will it be possible to have active at one time? If it's more than a few dozen then you'll probably be better off drawing the content of your schedule window rather than using actual windows for each rectangle. Not only would that avoid a lot of the problems you've been having it would have much less runtime overhead and would be more flexible for the visual appearance.

···

--
Robin Dunn
Software Craftsman

Actually quite a lot. A typical number would be 150+ wx.Panels that
can be active (waiting for clicks). These are the appointment and
bookable windows. I did feel uneasy about having so many wx.Panels
around in a screen. Including the other wx.Panels for the column and
row titles the total number of wx.Panels comes to almost 400. Also
using the GridBagSizer to position the elements means that I cannot
easily draw over different windows e.g. to draw a connecting line from
one window to another.

The reason I am doing this was because I started my wx coding based on
an example using wx.Panels in a GridBagSizer. I also needed to have
fixed column and row headers but didn't know how to do this easily
aside from the shuffling windows approach that I adopted with this
GridBagSizer-based approach. So I stuck with this approach even as
its shortcomings became apparent. At least it was 'working'.

My first post in this forum (27 Jun 2009: Scrolling while freezing
first column and first row) was actually asking how to do the fixed
row and columns titles while scrolling; and the answers included using
SetTargetWindows with 3 sub-windows and FloatCanvas. I am still not
sure how to do either of the 2; but maybe it is time to give it try.

If there are any sample code similar to what I am trying to achieve,
it would help!

···

On Aug 14, 8:50 am, Robin Dunn <ro...@alldunn.com> wrote:

BTW, how many panels or other widgets will it be possible to have active
at one time? If it's more than a few dozen then you'll probably be
better off drawing the content of your schedule window rather than using
actual windows for each rectangle. Not only would that avoid a lot of
the problems you've been having it would have much less runtime overhead
and would be more flexible for the visual appearance.

Sam23 wrote:

Including the other wx.Panels for the column and
row titles the total number of wx.Panels comes to almost 400.

That is a lot.

My first post in this forum (27 Jun 2009: Scrolling while freezing
first column and first row) was actually asking how to do the fixed
row and columns titles while scrolling; and the answers included using
SetTargetWindows with 3 sub-windows and FloatCanvas. I am still not
sure how to do either of the 2; but maybe it is time to give it try.

If there are any sample code similar to what I am trying to achieve,
it would help!

For those of us that haven't followed the whole thread, please post (or re-post) a description of what you are trying to achieve, and maybe we can offer something.

In particular, I was on vacation June 27, but may be able to offer FloatCanvas help now, or at least let you know if it's a good fit to your problem.

-Chris

···

On Aug 14, 8:50 am, Robin Dunn <ro...@alldunn.com> wrote:

--
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

Chris,
I have reposted the original discussion. I have also included a
summary of requirements and a sample code showing what could probably
be characterized as a good example of how not to do it :slight_smile:

Cheers
Sam

···

On Aug 15, 12:11 am, Christopher Barker <Chris.Bar...@noaa.gov> wrote:

For those of us that haven't followed the whole thread, please post (or
re-post) a description of what you are trying to achieve, and maybe we
can offer something.