I am suprised to see that an IDLE or UPDATE_UI event is fired even before I get the visual feedback from clicking on let’s say a CheckBox. In my case I need to run seomthing that needs about a 1 s to process so I moved that code to an IDLE event handler. But I do not see the CheckBox to check or uncheck before the code is started. Is this to be expected and what would you recommend to do without having to use threading?
There is no alternative. ALL of your message handlers happen in the
main UI thread. If a message handler is tied up, the UI goes
unresponsive. If you have a lengthy task, you must spin off a
thread.
Fortunately, that’s trivial in Python.
···
Christian K wrote:
I am suprised to see that an IDLE or UPDATE_UI event is fired
even before I get the visual feedback from clicking on let’s say
a CheckBox. In my case I need to run seomthing that needs about
a 1 s to process so I moved that code to an IDLE event handler.
But I do not see the CheckBox to check or uncheck before the
code is started. Is this to be expected and what would you
recommend to do without having to use threading?
Right, but isn't the UPDATE_UI event thought to be used for things that
should be happen when nothing else has to be done by the main loop? I
thought that updating native widgets would have priority over the wxpython
main loop. Obviously that is not the case. Actually in my case the task is
short enough to be run from the main thread but if the control remains
unresponsive during this time it looks really bad. The solution I found is
to start the "lengthy" one second task via wx.CallLater(200, ....).
Thanks anyway, Christian
···
On Fri, Apr 29, 2016 at 1:32 PM, Tim Roberts <timr@probo.com> wrote:
Christian K wrote:
I am suprised to see that an IDLE or UPDATE_UI event is fired even before
I get the visual feedback from clicking on let's say a CheckBox. In my case
I need to run seomthing that needs about a 1 s to process so I moved that
code to an IDLE event handler. But I do not see the CheckBox to check or
uncheck before the code is started. Is this to be expected and what would
you recommend to do without having to use threading?
There is no alternative. ALL of your message handlers happen in the main
UI thread. If a message handler is tied up, the UI goes unresponsive. If
you have a lengthy task, you must spin off a thread.
wx.CallLater(callable) : it and schedules ‘callable’ object to be called after all current events, i.e. puts it to the end of the list. The function is non-blocking, i.e.exits immediately
wx.Yield() : does all pending events and drawing and the resumes
There are two functions in wx that can help you.
1. wx.CallLater(callable) : it and schedules 'callable' object to be
called after all current events, i.e. puts it to the end of the list. The
function is non-blocking, i.e.exits immediately
2. wx.Yield() : does all pending events and drawing and the resumes
Except that using wx.Yield() is strongly discouraged.
Thank you.
···
On Sat, Apr 30, 2016 at 9:35 AM, Michael Salin <mikesalin@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
wx.CallLater(callable) : it and schedules ‘callable’ object to be
called after all current events, i.e. puts it to the end of the list. The
function is non-blocking, i.e.exits immediately
wx.Yield() : does all pending events and drawing and the resumes
Except that using wx.Yield() is strongly discouraged.
Can you point me to the documentation that specifies that wxYield is discouraged? There are alternatives (like wx.SafeYield or wx. YieldIfNeeded) that I use all the time with no problem whatsoever.
Ok, I get it. That’s yet another email sent just for the sake of writing something.
Igor, would you please refrain from posting into newsgroups on programming languages you know nothing about? Your messages pollutes the threads without adding any value, they are pointless, untimely and prevent other programmers with meaningful insights to chip in.
I have been following the wxWidgets mailing list for years, and I still have to find a single thread in which your reply where actually helpful.
I admire Vadim’s patience and understanding, it must be tough for him.
> There are two functions in wx that can help you.
> 1. wx.CallLater(callable) : it and schedules 'callable' object to be
> called after all current events, i.e. puts it to the end of the list.
> The
> function is non-blocking, i.e.exits immediately
> 2. wx.Yield() : does all pending events and drawing and the resumes
Except that using wx.Yield() is strongly discouraged.
Thank you.
Ok, I get it. That's yet another email sent just for the sake of writing
something.
Igor, would you please refrain from posting into newsgroups on programming
languages you know nothing about? Your messages pollutes the threads without
adding any value, they are pointless, untimely and prevent other programmers
with meaningful insights to chip in.
I have been following the wxWidgets mailing list for years, and I still have
to find a single thread in which your reply where actually helpful.
I admire Vadim's patience and understanding, it must be tough for him.
I did see couple of posts on wx ML were Vadim himself said that using
wxYield() is
not recommended.
I also did see his post in wxBlog where he said so.
I also think that there was a note in the documentation to {at least}
use wxSafeYield(),
but I'm not sure.
Unfortunately the weekend is not a good time for me to look for
something and spend
a big time on it.
I may do so later in the evening.
Thank you.
···
On Sat, Apr 30, 2016 at 2:39 PM, Andrea Gavana <andrea.gavana@gmail.com> wrote:
On Saturday, 30 April 2016, Igor Korot <ikorot01@gmail.com> wrote:
On Sat, Apr 30, 2016 at 9:35 AM, Michael Salin <mikesalin@gmail.com> >> wrote:
Andrea.
--
--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Indeed I found wx.CallLater(200, …) to workaround the issue. I would have expected that a wx.Yield would help as well, but is doesn’t. Also wx.CallAfter is calling the callable before the widget is updated completely, so I really to wait 200 ms before I can call start the lengthy task.
Please try the code attached. In the checkbox event handler try one of the three lines starting job() directly, or using CallAfter and CallLater. Here, only the last version will allow the checkbox to immediatly change its state visibly.
El sábado, 30 de abril de 2016, 13:35:13 (UTC-3), Michael Salin escribió:
There are two functions in wx that can help you.
wx.CallLater(callable) : it and schedules ‘callable’ object to be called after all current events, i.e. puts it to the end of the list. The function is non-blocking, i.e.exits immediately
wx.Yield() : does all pending events and drawing and the resumes
> There are two functions in wx that can help you.
> 1. wx.CallLater(callable) : it and schedules 'callable' object to be
> called after all current events, i.e. puts it to the end of the list.
> The
> function is non-blocking, i.e.exits immediately
> 2. wx.Yield() : does all pending events and drawing and the resumes
Except that using wx.Yield() is strongly discouraged.
Thank you.
Ok, I get it. That's yet another email sent just for the sake of writing
something.
Igor, would you please refrain from posting into newsgroups on programming
languages you know nothing about? Your messages pollutes the threads without
adding any value, they are pointless, untimely and prevent other programmers
with meaningful insights to chip in.
I have been following the wxWidgets mailing list for years, and I still have
to find a single thread in which your reply where actually helpful.
I admire Vadim's patience and understanding, it must be tough for him.
My memory does serve me right:
[quote]
From memory I remember that you always says that usage of
wxYield() is strongly discouraged. And wxSafeYield() is somewhat
a replacement.
I also vaguely remember that there was a post on wxBlog about
that )I am not sure about that one though).
Is it still the case with the new 3.1 release?
Yes. The trouble with wxYield() is fundamental problem with reentrancies
and this is never going to change.
Regards,
VZ
[/quote]
Thank you.
···
On Sat, Apr 30, 2016 at 2:39 PM, Andrea Gavana <andrea.gavana@gmail.com> wrote:
On Saturday, 30 April 2016, Igor Korot <ikorot01@gmail.com> wrote:
On Sat, Apr 30, 2016 at 9:35 AM, Michael Salin <mikesalin@gmail.com> >> wrote:
On Sun, 1 May 2016 11:35:46 -0400 Igor Korot wrote:
Andrea.
--
--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I think wx.Yield works to instantaneously gain control but it may not be suitable for long running jobs. I usually use the threading module from Python and CallAfter for posting messages or light tasks. Attached is your example modified with the threading class. It works just as I think it should. Robin himself recommended in his book to use the Python threading class. I wonder where else we can find wx.Yield or wx.SafeYield useful except for minor tasks. I might be wrong (about the Yield functions).
On Sun, May 1, 2016 at 6:46 AM, Christian K ckkart@gmail.com wrote:
El sábado, 30 de abril de 2016, 13:35:13 (UTC-3), Michael Salin escribió:
There are two functions in wx that can help you.
wx.CallLater(callable) : it and schedules ‘callable’ object to be called after all current events, i.e. puts it to the end of the list. The function is non-blocking, i.e.exits immediately
wx.Yield() : does all pending events and drawing and the resumes
Indeed I found wx.CallLater(200, …) to workaround the issue. I would have expected that a wx.Yield would help as well, but is doesn’t. Also wx.CallAfter is calling the callable before the widget is updated completely, so I really to wait 200 ms before I can call start the lengthy task.
Please try the code attached. In the checkbox event handler try one of the three lines starting job() directly, or using CallAfter and CallLater. Here, only the last version will allow the checkbox to immediatly change its state visibly.
Christian
–
You received this message because you are subscribed to the Google Groups “wxPython-users” group.
Thank you for your comments and the sample. But let us neglect the long running job for a moment. Aren’t wx.Yield, wx.CallAfter, etc. supposed to let the main loop finish all due tasks before let the program do anything else? This is what I don’t get.
Christian
···
El domingo, 1 de mayo de 2016, 21:50:02 (UTC-3), Emad Dlala escribió:
I think wx.Yield works to instantaneously gain control but it may not be suitable for long running jobs. I usually use the threading module from Python and CallAfter for posting messages or light tasks. Attached is your example modified with the threading class. It works just as I think it should. Robin himself recommended in his book to use the Python threading class. I wonder where else we can find wx.Yield or wx.SafeYield useful except for minor tasks. I might be wrong (about the Yield functions).
On Sun, May 1, 2016 at 6:46 AM, Christian K ckk...@gmail.com wrote:
El sábado, 30 de abril de 2016, 13:35:13 (UTC-3), Michael Salin escribió:
There are two functions in wx that can help you.
wx.CallLater(callable) : it and schedules ‘callable’ object to be called after all current events, i.e. puts it to the end of the list. The function is non-blocking, i.e.exits immediately
wx.Yield() : does all pending events and drawing and the resumes
Indeed I found wx.CallLater(200, …) to workaround the issue. I would have expected that a wx.Yield would help as well, but is doesn’t. Also wx.CallAfter is calling the callable before the widget is updated completely, so I really to wait 200 ms before I can call start the lengthy task.
Please try the code attached. In the checkbox event handler try one of the three lines starting job() directly, or using CallAfter and CallLater. Here, only the last version will allow the checkbox to immediatly change its state visibly.
Christian
–
You received this message because you are subscribed to the Google Groups “wxPython-users” group.
I feel we may have a misunderstanding going on here
as to what things do.
wx.*Yield():
My code notices that it is currently iterating over a
large loop (or something like that) which will take some
time thereby blocking the thread it is running in. Should
that thread happen to be the one running the wxPython
main loop the GUI becomes unresponsive. So, my code calls
wx.*Yield(), effectively saying:
Hello wxp-mainloop! I am quite busy, therefore I am
blocking you, but _now_ is a good time for you to do some
of the things you need to do.
If my long running task is running in a _separate_ thread
there is no need for wx.*Yield().
wx.Call*()
My code is running in a thread _separate_ from the main
one (the one running the GUI, that is the wxp main loop).
In that case it is unsafe to update GUI elements from my
code. So, my code calls wx.CallAfter(callback) (et alii)
at appropriate times, effectively saying:
Hello wxp-mainloop! I want you to take _my_ code (in
<callback>) and run it for me in _your_ thread after you
are done doing the things you are currently doing.
This is typically used to tell the GUI (main) thread to
update GUI elements after some long running task in
_another_ thread has finished.
If my long running task is running in the _same_ thread
as the GUI code there is no need for wx.Call*()
Karsten
···
On Sun, May 01, 2016 at 05:49:58PM -0700, Emad Dlala wrote:
I think wx.Yield works to instantaneously gain control but it may not be
suitable for long running jobs. I usually use the *threading *module from
Python and CallAfter for posting messages or light tasks. Attached is your
example modified with the threading class. It works just as I think it
should. Robin himself recommended in his book to use the Python threading
class. I wonder where else we can find wx.Yield or wx.SafeYield useful
except for minor tasks. I might be wrong (about the Yield functions).
Thank you for your comments and the sample. But let us neglect the long
running job for a moment. Aren't wx.Yield, wx.CallAfter, etc. supposed to
let the main loop finish all due tasks
Yes, but ...
before let the program do anything else?
... no. Wx.CallAfter() sets up a callback for wxPython to
execute when it has time to do so. Program flow returns
_immediately_ to the line in the code where wx.CallAfter()
was called. The callback is only executed later. With
wx.Yield() normal program flow continues in the next line of
code after wxPython has done its thing. Nothing happens later.
Karsten
···
On Sun, May 01, 2016 at 07:53:36PM -0700, Christian K wrote:
--
GPG key ID E4071346 @ eu.pool.sks-keyservers.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346
Yes, I agree, I have put it too simple. The fact is that both can be used to achieve the same thing: allow wxPython to finish things that have to be done. But obvioulsy wxPython does not consider the redrawing of the widget to be something important. Would you have expected that?
Question aside: will a call to wx.Yield actually trigger the processing of all pending events?
Christian
···
El lunes, 2 de mayo de 2016, 4:09:19 (UTC-3), Karsten Hilbert escribió:
On Sun, May 01, 2016 at 07:53:36PM -0700, Christian K wrote:
Thank you for your comments and the sample. But let us neglect the long
running job for a moment. Aren’t wx.Yield, wx.CallAfter, etc. supposed to
let the main loop finish all due tasks
Yes, but …
before let the program do anything else?
… no. Wx.CallAfter() sets up a callback for wxPython to
execute when it has time to do so. Program flow returns
immediately to the line in the code where wx.CallAfter()
was called. The callback is only executed later. With
wx.Yield() normal program flow continues in the next line of
code after wxPython has done its thing. Nothing happens later.
One more comment with respect to wx.CallAfter. Even if call the lenghty job via wx.CallAfter, the job is processed before the widget is redrawn. I would simply not have expected that behaviour. In addition, to me it does not make much sense to use wx.CallAfter in that case.
Christian
···
El lunes, 2 de mayo de 2016, 4:09:19 (UTC-3), Karsten Hilbert escribió:
On Sun, May 01, 2016 at 07:53:36PM -0700, Christian K wrote:
Thank you for your comments and the sample. But let us neglect the long
running job for a moment. Aren’t wx.Yield, wx.CallAfter, etc. supposed to
let the main loop finish all due tasks
Yes, but …
before let the program do anything else?
… no. Wx.CallAfter() sets up a callback for wxPython to
execute when it has time to do so. Program flow returns
immediately to the line in the code where wx.CallAfter()
was called. The callback is only executed later. With
wx.Yield() normal program flow continues in the next line of
code after wxPython has done its thing. Nothing happens later.
> Thank you for your comments and the sample. But let us neglect the long
> running job for a moment. Aren't wx.Yield, wx.CallAfter, etc. supposed
> to
> let the main loop finish all due tasks
Yes, but ...
> before let the program do anything else?
... no. Wx.CallAfter() sets up a callback for wxPython to
execute when it has time to do so. Program flow returns
_immediately_ to the line in the code where wx.CallAfter()
was called. The callback is only executed later. With
wx.Yield() normal program flow continues in the next line of
code after wxPython has done its thing. Nothing happens later.
Yes, I agree, I have put it too simple. The fact is that both can be used to
achieve the same thing: allow wxPython to finish things that have to be
done. But obvioulsy wxPython does not consider the redrawing of the widget
to be something important. Would you have expected that?
Question aside: will a call to wx.Yield actually trigger the processing of
all pending events?
Yes, this is the sole purpose of wxYield().
However, it has a problem with re-entrancy as Vadim wrote, and
therefore, not recommended
if it can be avoided.
Thank you.
···
On Mon, May 2, 2016 at 8:45 AM, Christian K <ckkart@gmail.com> wrote:
El lunes, 2 de mayo de 2016, 4:09:19 (UTC-3), Karsten Hilbert escribió:
On Sun, May 01, 2016 at 07:53:36PM -0700, Christian K wrote:
Christian
--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
> Thank you for your comments and the sample. But let us neglect the long
> running job for a moment. Aren't wx.Yield, wx.CallAfter, etc. supposed
> to
> let the main loop finish all due tasks
Yes, but ...
> before let the program do anything else?
... no. Wx.CallAfter() sets up a callback for wxPython to
execute when it has time to do so. Program flow returns
_immediately_ to the line in the code where wx.CallAfter()
was called. The callback is only executed later. With
wx.Yield() normal program flow continues in the next line of
code after wxPython has done its thing. Nothing happens later.
One more comment with respect to wx.CallAfter. Even if call the lenghty job
via wx.CallAfter, the job is processed before the widget is redrawn. I would
simply not have expected that behaviour. In addition, to me it does not make
much sense to use wx.CallAfter in that case.
Just start you lengthy job in a thread.
This is by far the best and simplest solution.
Thank you.
···
On Mon, May 2, 2016 at 8:49 AM, Christian K <ckkart@gmail.com> wrote:
El lunes, 2 de mayo de 2016, 4:09:19 (UTC-3), Karsten Hilbert escribió:
On Sun, May 01, 2016 at 07:53:36PM -0700, Christian K wrote:
Christian
--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
No. There is really nothing wx-specific about this. When a
component needs to be updated, someone generates an “invalidate”
request, which queues up a WM_PAINT event. That event gets unrolled
by the thread’s main message loop, just like all of the other
messages. If the code never gets back to the main message loop, the
WM_PAINT event remains in the queue, and the component is not
redrawn.
Well, that still means your UI is going to lock up during that
time. Lengthy tasks should be done in a separate thread. It is
worth your time to figure out how to do it, and it’s not hard.
I am suprised to see that an IDLE or UPDATE_UI event
is fired even before I get the visual feedback from
clicking on let’s say a CheckBox. In my case I need
to run seomthing that needs about a 1 s to process
so I moved that code to an IDLE event handler. But I
do not see the CheckBox to check or uncheck before
the code is started. Is this to be expected and what
would you recommend to do without having to use
threading?
There is no alternative. ALL of your message handlers
happen in the main UI thread. If a message handler is
tied up, the UI goes unresponsive. If you have a
lengthy task, you must spin off a thread.
Right, but isn't the UPDATE_UI event thought to be used
for things that should be happen when nothing else has to
be done by the main loop? I thought that updating native
widgets would have priority over the wxpython main loop.
Obviously that is not the case.
Actually in my case the task is short enough to be run
from the main thread but if the control remains
unresponsive during this time it looks really bad. The
solution I found is to start the “lengthy” one second task
via wx.CallLater(200, …).
It’s true that the “yield” routines work. They have been part of
Windows since the very beginning. In fact they were absolutely
critical in the original Windows implementation, because processes
were cooperative, not pre-emptive – if you didn’t get back to your
main loop, you froze ALL applications, not just your own.
However, it is my view in today’s world that the use of wx.Yield is
indicative of a design flaw. It is single-threaded thinking in a
multi-threaded world. Long-running tasks should be in a separate
thread, and the definition of long" keeps getting shorter. Even the
simplest smart phone today has four processor cores, and the only
way to keep those four cores busy is to use threads. Programmers
today must be just as comfortable throwing threads around as they
are throwing messages. A programmer who has that comfort will never
find a need for wx.Yield.
···
Andrea Gavana wrote:
Hi,
On Saturday, 30 April 2016, Igor Korot < >
wrote:
Can you point me to the documentation that specifies that wxYield
is discouraged? There are alternatives (like wx.SafeYield or wx.
YieldIfNeeded) that I use all the time with no problem whatsoever.