I have a hourglass cursor that is present during a long running task
in a thread, and when the task is done, the cursor is set back to the
standard one, but it doesn't update to that one until the user moves
the mouse. Since a return to the standard cursor is one of the cues
to the user that the processing is done, I want the cursor to return
to normal immediately.
TypeError: in method 'new_MouseEvent', expected argument 1 of type 'wxEventType'
I thought that's what I had provided, but clearly I'm misunderstanding
something. Or perhaps I'm going about updating the cursor entirely
the wrong way?
I have a hourglass cursor that is present during a long running task
in a thread, and when the task is done, the cursor is set back to the
standard one, but it doesn't update to that one until the user moves
the mouse. Since a return to the standard cursor is one of the cues
to the user that the processing is done, I want the cursor to return
to normal immediately.
TypeError: in method 'new_MouseEvent', expected argument 1 of type 'wxEventType'
I thought that's what I had provided, but clearly I'm misunderstanding
something.
wx.EVT_MOTION is an instance of a Python class called wx.PyEventBinder. It has an attribute that is the C++ wxEventType value (an integer):
>>> wx.EVT_MOTION
<wx._core.PyEventBinder object at 0x595cd0>
>>> wx.EVT_MOTION.typeId
10033
>>>
Or perhaps I'm going about updating the cursor entirely
the wrong way?
However I don't think posing the event like the above will actually do the job. It doesn't actually send the system level messages that will move the cursor and in turn generate the corresponding events. It just sends the wx event through the wx layers.
To really move the cursor you can use wx.Window.WarpPointer. On the other hand, perhaps just a wx.WakeUpIdle() will work, or a wx.Yield().
I tried these last two now, and neither worked. Maybe I'm using them
wrongly? I tried them either before or after the SetCursor() call,
but neither did it.
I'm probably missing some key point here... For more info, here is the
structure of the relevant code:
I start a new thread (using the thread module, not the threading
module) that calls the function self.StartProcess():
status = thread.start_new_thread( self.StartProcess, ("Thread-1",))
Within the StartProcess() function, I set the cursor to the hourglass,
while it is working.
Then after that line, I have the call to set the standard (arrow) cursor:
self.SetCursor(self.stockCursor1)
Is there something different I should be doing? This is the first
time I have used threads with long running tasks. It is working
beautifully other than the cursor update.
Thanks.
···
On Mon, Jul 22, 2013 at 1:08 PM, Robin Dunn <robin@alldunn.com> wrote:
C M wrote:
I have a hourglass cursor that is present during a long running task
in a thread, and when the task is done, the cursor is set back to the
standard one, but it doesn't update to that one until the user moves
the mouse. Since a return to the standard cursor is one of the cues
to the user that the processing is done, I want the cursor to return
to normal immediately.
TypeError: in method 'new_MouseEvent', expected argument 1 of type
'wxEventType'
I thought that's what I had provided, but clearly I'm misunderstanding
something.
wx.EVT_MOTION is an instance of a Python class called wx.PyEventBinder. It
has an attribute that is the C++ wxEventType value (an integer):
>>> wx.EVT_MOTION
<wx._core.PyEventBinder object at 0x595cd0>
>>> wx.EVT_MOTION.typeId
10033
>>>
Or perhaps I'm going about updating the cursor entirely
the wrong way?
However I don't think posing the event like the above will actually do the
job. It doesn't actually send the system level messages that will move the
cursor and in turn generate the corresponding events. It just sends the wx
event through the wx layers.
To really move the cursor you can use wx.Window.WarpPointer. On the other
hand, perhaps just a wx.WakeUpIdle() will work, or a wx.Yield().
On Mon, Jul 22, 2013 at 1:08 PM, Robin Dunn<robin@alldunn.com> wrote:
C M wrote:
I have a hourglass cursor that is present during a long running task
in a thread, and when the task is done, the cursor is set back to the
standard one, but it doesn't update to that one until the user moves
the mouse. Since a return to the standard cursor is one of the cues
to the user that the processing is done, I want the cursor to return
to normal immediately.
TypeError: in method 'new_MouseEvent', expected argument 1 of type
'wxEventType'
I thought that's what I had provided, but clearly I'm misunderstanding
something.
wx.EVT_MOTION is an instance of a Python class called wx.PyEventBinder. It
has an attribute that is the C++ wxEventType value (an integer):
>>> wx.EVT_MOTION
<wx._core.PyEventBinder object at 0x595cd0>
>>> wx.EVT_MOTION.typeId
10033
>>>
Or perhaps I'm going about updating the cursor entirely
the wrong way?
However I don't think posing the event like the above will actually do the
job. It doesn't actually send the system level messages that will move the
cursor and in turn generate the corresponding events. It just sends the wx
event through the wx layers.
To really move the cursor you can use wx.Window.WarpPointer. On the other
hand, perhaps just a wx.WakeUpIdle() will work, or a wx.Yield().
I tried these last two now, and neither worked. Maybe I'm using them
wrongly? I tried them either before or after the SetCursor() call,
but neither did it.
I'm probably missing some key point here... For more info, here is the
structure of the relevant code:
I start a new thread (using the thread module, not the threading
module) that calls the function self.StartProcess():
status = thread.start_new_thread( self.StartProcess, ("Thread-1",))
Within the StartProcess() function, I set the cursor to the hourglass,
while it is working.
Then after that line, I have the call to set the standard (arrow) cursor:
self.SetCursor(self.stockCursor1)
The whole point of using threads is to allow the main thread to continue moving forward while the thread is working in the background. But since you are trying to reset the cursor immediately it seems that you are expecting the calling thread to not move forward until the background job is done. Regardless, you should not do anything in the background thread that directly interacts with the UI.
The whole point of using threads is to allow the main thread to continue
moving forward while the thread is working in the background. But since you
are trying to reset the cursor immediately it seems that you are expecting
the calling thread to not move forward until the background job is done.
Regardless, you should not do anything in the background thread that
directly interacts with the UI.
Well, maybe I'm going about this the wrong way. Putting this in terms
of the user experience, I thought it would be good to have the
following conditions:
1) While the numbers are crunching (up to a minute or more), the
cursor is an hourglass, to mean "please wait and don't bother to do
anything, we're not done".
2) But, so that the user doesn't wonder whether the program has simply
crashed and is never going to finish (which had happened in earlier
versions with my client), I thought it would be great to keep the GUI
updating the user on the status by writing text about which file is
processed. (Thus using a worker thread so as to not block the GUI
thread).
3) Then, when it's all done, the hourglass returns to the arrow cursor
to mean, "Now you can click on the 'See the results' button if you
want.". In fact, this is complementary to the other UX point of the
text saying, "Files processed!".
I would think this is the default approach in the GUI world, and
updating the cursor once a number crunching thread is finished should
be trivial.
Does that make sense? Sorry to draw this out, but it's more about the
learning point for me more than even this program (in that the cursor
is not that crucial at all). Thanks again!
Well, maybe I'm going about this the wrong way. Putting this in terms
of the user experience, I thought it would be good to have the
following conditions:
1) While the numbers are crunching (up to a minute or more), the
cursor is an hourglass, to mean "please wait and don't bother to do
anything, we're not done".
2) But, so that the user doesn't wonder whether the program has simply
crashed and is never going to finish (which had happened in earlier
versions with my client), I thought it would be great to keep the GUI
updating the user on the status by writing text about which file is
processed. (Thus using a worker thread so as to not block the GUI
thread).
3) Then, when it's all done, the hourglass returns to the arrow cursor
to mean, "Now you can click on the 'See the results' button if you
want.". In fact, this is complementary to the other UX point of the
text saying, "Files processed!".
I would think this is the default approach in the GUI world, and
updating the cursor once a number crunching thread is finished should
be trivial.
Right. Here's how you do that in an event driven world. In the routine
that fires off the number crunching, you set the cursor to hourglass,
fire off the thread, and return.
In the thread, you do your number crunching, then when the crunching is
done, you use wx.CallAfter or fire off an event to the main window
saying "we're done".
Then, in the "we're done" handler, you set the cursor back to the default.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Right. Here's how you do that in an event driven world. In the routine
that fires off the number crunching, you set the cursor to hourglass,
fire off the thread, and return.
In the thread, you do your number crunching, then when the crunching is
done, you use wx.CallAfter or fire off an event to the main window
saying "we're done".
Thanks, Tim. wx.CallAfter did the trick; I couldn't easily figure out
how to post an event, but this seems like a simple way to do it.
Sorry to all if what I was trying to do before wasn't clear. I've
never used threads until now; nice addition to my (glacially rapid)
growing wx knowledge.
On Wednesday, July 24, 2013 12:41:13 PM UTC-5, Che M wrote:
Right. Here’s how you do that in an event driven world. In the routine
that fires off the number crunching, you set the cursor to hourglass,
fire off the thread, and return.
In the thread, you do your number crunching, then when the crunching is
done, you use wx.CallAfter or fire off an event to the main window
saying “we’re done”.
Thanks, Tim. wx.CallAfter did the trick; I couldn’t easily figure out
how to post an event, but this seems like a simple way to do it.
Sorry to all if what I was trying to do before wasn’t clear. I’ve
never used threads until now; nice addition to my (glacially rapid)
growing wx knowledge.
I should have jumped in and said something. You might find my old article helpful the next time you want to deal with threads: wxPython and Threads - Mouse Vs Python