How can i stop a button event handler from another button event handler.
I have one button “Start” which starts a function. Some times I have to reset this function. So I need to have another button, which essentially takes me to the initial stage (just started the application)
How can i stop a button event handler from another button event handler.
I have one button "Start" which starts a function. Some times I have
to reset this function. So I need to have another button, which
essentially takes me to the initial stage (just started the application)
You shouldn't be running long functions within an event handler. That
will lock up your API, so that it won't even be possible to press any
other button.
Instead, your "Start" handler should start another thread to handle your
long function. That function can check a "should I exit?" flag every
now and then. Your "Stop" handler can then set that flag.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Is it possible to stop or remove one handler in the middle ?
Not very OO but if you have a continue flag that you set on the start button being clicked, check after each yield and clear with your other button it may do the job but you will need to make sure your (safe)yield is called often enough to keep things responsive. Personally I find the threading model preferable.
I disagree. Breaking a job into small chunks and doing them one at a
time is a perfectly fine solution. Threads add complexity which many
programmers are just not prepared to deal with properly. Not everyone
is adept at writing solid multi-threaded code, and if this is a
long-lived program that may have other people maintain it over time,
keeping complexity down (*) is a Win.
* Of course, without seeing the code it's possible that the yield
solution adds its own type of complexity, but it's just as possible
that it's elegant and simple.
I like to stay away from absolute rules in programming -- threading
has its place but so do other techniques.
···
On Thu, Dec 23, 2010 at 11:49 AM, Tim Roberts <timr@probo.com> wrote:
Hans A wrote:
Instead of threads , i use Yield.
Although it might provide results, that's not the right way to solve
this problem.
Actually a better implementation of the slice-it-up-into-little-chunks approach is to execute each chunk in an EVT_IDLE handler, and when a chunk is finished call event.RequestMore if there are still more chunks to be done. IOW, something like this:
def OnIdle(self, evt):
self.doNextChunk()
if self.moreChunksInQueue():
evt.RequestMore()
Due to the fact that yielding essentially implements a full nested event loop there are some inherent potential problems and pitfalls that can result. One is the fact that you can end up with an unexpected recursion if the user triggers the same event that starts the same long running task again, or anything else where your program may misbehave if it's still in an unexpected state due to being in a nested event loop. Granted, its not an insurmountable problem, but the workaround is messier than it needs to be, and with the possibility of event recursion there is always the chance of some unexpected thing happening that you haven't implemented a workaround for yet.
···
On 12/23/10 10:50 AM, Bryan Oakley wrote:
On Thu, Dec 23, 2010 at 11:49 AM, Tim Roberts<timr@probo.com> wrote:
Hans A wrote:
Instead of threads , i use Yield.
Although it might provide results, that's not the right way to solve
this problem.
I disagree. Breaking a job into small chunks and doing them one at a
time is a perfectly fine solution. Threads add complexity which many
programmers are just not prepared to deal with properly. Not everyone
is adept at writing solid multi-threaded code, and if this is a
long-lived program that may have other people maintain it over time,
keeping complexity down (*) is a Win.
To OP. When using OnIdle() there are some things to consider.
I think the OnIdle event is not generated over and over again enmass while your app is idle but instead one OnIdle event is sent for a “set” of OnIdle events - I believe. If the number of OnIdle events differs on various OSes I couldn’t say.
I do not know what effect (a) busy CPU(s) have on the generation of a “set” of OnIdle events. Meaning if your OS has your cores (cpus) busy with other software if the number of OnIdle events in a set is reduced. If this is the case your app will effectively have it’s “priority” level reduced (essentially the OS will seem to give less “time” slicing to your app) For more see Window’s Task Manager you can set an app’s priority - which works out to be how much the OS gives in time to an app.
Personally I like to think of OnIdle as a way to do non-important - extra stuff, like an autoback feature of a text editor or the like.
The above are more really questions to Robin and others more knowledgable about use of OnIdle.
To OP. When using OnIdle() there are some things to consider.
I think the OnIdle event is not generated over and over again enmass
while your app is idle but instead one OnIdle event is sent for a
"set" of OnIdle events - I believe. If the number of OnIdle events
differs on various OSes I couldn't say.
OnIdle is triggered when your message queue goes empty. It will not be
called again until you get and handle another message, and the queue
once again transitions to "empty". If you need periodic calls, you
should use a timer.
Personally I like to think of OnIdle as a way to do non-important -
extra stuff, like an autoback feature of a text editor or the like.
Yes. It was really designed for tasks like updating the
enabled/disabled state of controls based on the current application
state, although of course it has many other uses as well.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
I've generally done that, too, but with judicious use of wx.WakeUpIdle(), you can use Idle event for longer running stuff.
It has the advantage of not requiring you to know it advance what a reasonable timer timestep should be.
-Chris
···
On 12/28/10 10:25 AM, Tim Roberts wrote:
OnIdle is triggered when your message queue goes empty. It will not be
called again until you get and handle another message, and the queue
once again transitions to "empty". If you need periodic calls, you
should use a timer.
--
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
To OP. When using OnIdle() there are some things to consider.
I think the OnIdle event is not generated over and over again enmass
while your app is idle but instead one OnIdle event is sent for a "set"
of OnIdle events - I believe. If the number of OnIdle events differs on
various OSes I couldn't say.
The way it works is that when the event queue *becomes empty* then an idle event is sent to the widgets in the application. If none of the idle event handlers called RequestMore then that is the end of it until the next time the event queue becomes empty. If RequestMore was called then if there are no events pending in the event queue then another idle event is sent right away.
I do not know what effect (a) busy CPU(s) have on the generation of a
"set" of OnIdle events. Meaning if your OS has your cores (cpus) busy
with other software if the number of OnIdle events in a set is reduced.
If this is the case your app will effectively have it's "priority" level
reduced (essentially the OS will seem to give less "time" slicing to
your app) For more see Window's Task Manager you can set an app's
priority - which works out to be how much the OS gives in time to an app.
Personally I like to think of OnIdle as a way to do non-important -
extra stuff, like an autoback feature of a text editor or the like.
The above are more really questions to Robin and others more
knowledgable about use of OnIdle.
It's not necessarily the busyness of the CPU that can starve out idle events, but rather if there is always pending events in the queue. An overloaded system could certainly contribute to that if the system is too busy to let your application process the events as fast as they are coming in, but there are other situations that can cause it too, such as having a timer with a very short time-out.