By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,345 Members | 1,775 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,345 IT Pros & Developers. It's quick & easy.

wxPython before MainLoop

P: n/a
I'd like to refresh the display before I start the main loop.

I have code like this:

app = App()
app.Show()
app.long_slow_init()
app.MainLoop()
The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.

Alternatively, I could code

app = App()
app.long_slow_init()
app.Show()
app.MainLoop()

Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.

I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.

Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?

Or is there a better idea?

(david)
Aug 9 '07 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On Aug 8, 11:25 pm, "[david]" <da...@nospam.spamwrote:
I'd like to refresh the display before I start the main loop.

I have code like this:

app = App()
app.Show()
app.long_slow_init()
app.MainLoop()

The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.

Alternatively, I could code

app = App()
app.long_slow_init()
app.Show()
app.MainLoop()

Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.

I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.

Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?

Or is there a better idea?

(david)
You can use a separate thread to execute long_slow_init():

--------------------------
import wx
import threading
import time

class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "My Window")

panel = wx.Panel(self, -1)
button = wx.Button(panel, -1, "click me, quick!", pos=(40,
40))
self.Bind(wx.EVT_BUTTON, self.onclick)

def onclick(self, event):
print "button clicked"

def receive_result(self, result):
print "Hey, I'm done with that long, slow initialization."
print "The result was:", result
class MyApp(wx.App):
def __init__(self):
wx.App.__init__(self, redirect=False)
def OnInit(self):
the_frame = MyFrame()
the_frame.Show()

t = MyThread(the_frame)
t.start() #calls run() in t's class

return True
class MyThread(threading.Thread):
def __init__(self, a_frame):
threading.Thread.__init__(self)

self.frame_obj = a_frame

def run(self):
self.result = self.long_slow_init()

def long_slow_init(self):
print "starting long_slow_init()..."
time.sleep(6)
result = 20.5

#Send result to frame:
wx.CallAfter(self.frame_obj.receive_result, result)

app = MyApp()
app.MainLoop()
----------------------------
Aug 9 '07 #2

P: n/a
I reorganized my Thread class a little bit:

------------
class MyThread(threading.Thread):
def __init__(self, a_frame):
threading.Thread.__init__(self)
self.frame_obj = a_frame

def run(self):
result = self.long_slow_init()

wx.CallAfter(self.frame_obj.receive_result, result)
#CallAfter() calls the specified function with the specified
argument
#when the next pause in execution occurs in this thread.

def long_slow_init(self):
print "starting long_slow_init()..."
time.sleep(6)
result = 20.5
return result
--------------

Aug 9 '07 #3

P: n/a
[david] wrote:
I'd like to refresh the display before I start the main loop.
[...]
I'd like to just make app.Show() finish correctly before running
long_slow_init.
IMHO, this will bring no gain. If you see an inresponsive user
interface or not is quite meaningless.
Or is there a better idea?
As suggested, a solution using threads is feasible.

Regards,
Björn

--
BOFH excuse #422:

Someone else stole your IP address, call the Internet detectives!

Aug 9 '07 #4

P: n/a
On Aug 9, 12:25 am, "[david]" <da...@nospam.spamwrote:
I'd like to refresh the display before I start the main loop.

I have code like this:

app = App()
app.Show()
app.long_slow_init()
app.MainLoop()

The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.

Alternatively, I could code

app = App()
app.long_slow_init()
app.Show()
app.MainLoop()

Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.

I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.

Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?

Or is there a better idea?

(david)
Yeah, I think 7stud's thread is the way to go. It's what I do with
long running tasks, see also:
http://wiki.wxpython.org/LongRunningTasks

If your screen doesn't load correctly, be sure to call the Layout()
method.

Mike

Aug 9 '07 #5

P: n/a
On Aug 8, 11:25 pm, "[david]" <da...@nospam.spamwrote:
I'd like to refresh the display before I start the main loop.

I have code like this:

app = App()
app.Show()
app.long_slow_init()
app.MainLoop()

The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.

Alternatively, I could code

app = App()
app.long_slow_init()
app.Show()
app.MainLoop()

Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.

I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.

Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?

Or is there a better idea?

(david)
I don't see my original post, so here it is again....
You can use another thread to execute long_slow_init():

--------------
import wx
import threading
import time

class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "My Window")

panel = wx.Panel(self, -1)
button = wx.Button(panel, -1, "click me, quick!", pos=(40,
40))
self.Bind(wx.EVT_BUTTON, self.onclick)

def onclick(self, event):
print "button clicked"

def receive_result(self, result):
print "Hey, I'm done with that long, slow initialization."
print "The result was:", result
class MyApp(wx.App):
def __init__(self):
wx.App.__init__(self, redirect=False)
def OnInit(self): #called by wx.Python
the_frame = MyFrame()
the_frame.Show()

t = MyThread(the_frame)
t.start() #calls t.run()

return True

class MyThread(threading.Thread):
def __init__(self, a_frame):
threading.Thread.__init__(self)
self.frame_obj = a_frame

def run(self):
result = self.long_slow_init()

wx.CallAfter(self.frame_obj.receive_result, result)
#CallAfter() calls the specified function with the
#specified argument when the next pause in execution
#occurs in this thread:

def long_slow_init(self):
print "starting long_slow_init()..."
time.sleep(6)
result = 20.5
return result
app = MyApp()
app.MainLoop()

Aug 9 '07 #6

P: n/a
I'm disappointed that I didn't get a wxPython solution.

If the only way to get wxPython to correctly handle
this simple task is to code around it, I don't think
wxPython is really ready for Windows.

Is there a better place to ask?

Regarding the suggestions:

Bjoern, you're wrong. The GUI needs to be displayed
for the user to analyse. A delay between display and
readiness is much better than a delay before display
or a delay with the GUI half-drawn.

Mike, the screen does display correctly, it's just
that in Windows, screen updates are not processed
while the application is busy.

7Stud, that's a solution. Unless anyone comes up
with a direct solution, I guess I'll have to do that.

[david]
[david] wrote:
I'd like to refresh the display before I start the main loop.

I have code like this:

app = App()
app.Show()
app.long_slow_init()
app.MainLoop()
The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.

Alternatively, I could code

app = App()
app.long_slow_init()
app.Show()
app.MainLoop()

Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.

I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.

Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?

Or is there a better idea?

(david)
Aug 10 '07 #7

P: n/a
[david] wrote:
I'd like to refresh the display before I start the main loop.
We have this kind of situation in Chandler, where we display and update
the splash screen before we enter MainLoop.

1. Create app object
http://lxr.osafoundation.org/source/...handler.py#080

2. During app object creation, in OnInit, put up splash screen and update it

http://lxr.osafoundation.org/source/...ication.py#433

3. The splash screen refresh is basically: draw new stuff,
self.Layout(), self.Update(), wx.Yield()
http://lxr.osafoundation.org/source/...cation.py#1421

3. Start MainLoop
http://lxr.osafoundation.org/source/...handler.py#086

--
Heikki Toivonen
Aug 10 '07 #8

P: n/a
On Aug 9, 8:51 pm, "[david]" <da...@nospam.spamwrote:
I'm disappointed that I didn't get a wxPython solution.

If the only way to get wxPython to correctly handle
this simple task is to code around it, I don't think
wxPython is really ready for Windows.

Is there a better place to ask?

Regarding the suggestions:

Bjoern, you're wrong. The GUI needs to be displayed
for the user to analyse. A delay between display and
readiness is much better than a delay before display
or a delay with the GUI half-drawn.

Mike, the screen does display correctly, it's just
that in Windows, screen updates are not processed
while the application is busy.

7Stud, that's a solution. Unless anyone comes up
with a direct solution, I guess I'll have to do that.

[david]

[david] wrote:
I'd like to refresh the display before I start the main loop.
I have code like this:
app = App()
app.Show()
app.long_slow_init()
app.MainLoop()
The main frame partly loads at Show, but because the mainloop has not
started yet, the display does not update until long_slow_init() finishes.
Alternatively, I could code
app = App()
app.long_slow_init()
app.Show()
app.MainLoop()
Which would give me a crisp Show, but there would be a long slow wait
before the app showed any activity at all. I would need a splash screen.
I'd rather not have a splash screen (and I don't know how anyway). I'd
like to just make app.Show() finish correctly before running
long_slow_init.
Is there a wx internal method that I can use to give Windows the
opportunity to finish painting the frame before I run long_slow_init()?
Or is there a better idea?
(david)
Chris is right. The only way to interact with a gui is with a separate
thread, otherwise you're blocking the gui's mainloop thread. That's
why I gave that link. That's how to do it in every GUI I'm aware of.

Mike

Aug 10 '07 #9

P: n/a
[david] wrote:
I'm disappointed that I didn't get a wxPython solution.

If the only way to get wxPython to correctly handle
this simple task is to code around it,
LOL -- did you try coding this app with native windows means, like
MFC? You will have *exactly* the same problem, and *exactly* for
the same reason. The organisation of wxWidgets (and thus, wxPython)
is very near to Windows GUI coding philosophy.
I don't think wxPython is really ready for Windows.
I suggest you first went getting experience with other GUI libraries
before you make such statements.

Also, wxPython is a thin wrapper around wxWidgets C++ library which
is widely used for Windows apps. And with wxWidgets, you'd *also*
have the same problem.
Bjoern, you're wrong. The GUI needs to be displayed
for the user to analyse. A delay between display and
readiness is much better than a delay before display
or a delay with the GUI half-drawn.
This may be, but it strongly depends on the application itself.
Mike, the screen does display correctly, it's just
that in Windows, screen updates are not processed
while the application is busy.
That's the matter in just about *every* GUI framework using an event
loop. And I don't know any that doesn't. Thus, there are two widely
used standard solutions:

* use a worker thread, or

* call a "process all pending events now" function repeatedly during
the work (here: wx.Yield, wx.SafeYield, wx.YieldIfNeeded).

Regards,
Björn

--
BOFH excuse #92:

Stale file handle (next time use Tupperware(tm)!)

Aug 10 '07 #10

P: n/a
[david] wrote:
[...] I don't think wxPython is really ready for Windows.
I don't think you are really ready to for GUIs ;-)

Fortunately, it doesn't matter what *I* think.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

Aug 10 '07 #11

P: n/a
Well yes, I have tried this app with native windows,
and I know how to do it.

But if all wxPython can offer is a poor imitation
of MFC, I'm better off using MFC aren't I?

And too all those people who wrote back to insist
that users MUST explicitly build a multi-threaded
framework for wxPython:

It's supposed to already be a framework :~)

(david)

Bjoern Schliessmann wrote:
[david] wrote:
>I'm disappointed that I didn't get a wxPython solution.

If the only way to get wxPython to correctly handle
this simple task is to code around it,

LOL -- did you try coding this app with native windows means, like
MFC? You will have *exactly* the same problem, and *exactly* for
the same reason. The organisation of wxWidgets (and thus, wxPython)
is very near to Windows GUI coding philosophy.
>I don't think wxPython is really ready for Windows.

I suggest you first went getting experience with other GUI libraries
before you make such statements.

Also, wxPython is a thin wrapper around wxWidgets C++ library which
is widely used for Windows apps. And with wxWidgets, you'd *also*
have the same problem.
>Bjoern, you're wrong. The GUI needs to be displayed
for the user to analyse. A delay between display and
readiness is much better than a delay before display
or a delay with the GUI half-drawn.

This may be, but it strongly depends on the application itself.
>Mike, the screen does display correctly, it's just
that in Windows, screen updates are not processed
while the application is busy.

That's the matter in just about *every* GUI framework using an event
loop. And I don't know any that doesn't. Thus, there are two widely
used standard solutions:

* use a worker thread, or

* call a "process all pending events now" function repeatedly during
the work (here: wx.Yield, wx.SafeYield, wx.YieldIfNeeded).

Regards,
Björn
Aug 14 '07 #12

P: n/a
[david] wrote:
Well yes, I have tried this app with native windows,
and I know how to do it.

But if all wxPython can offer is a poor imitation
of MFC, I'm better off using MFC aren't I?

And too all those people who wrote back to insist
that users MUST explicitly build a multi-threaded
framework for wxPython:

It's supposed to already be a framework :~)
The answer is simple. If you don't see any advantage to using wxPython
then don't use it. Personally I believe wxPython is far from a poor
imitation of MFC, but if you are already familiar with MFC then go ahead
and use it.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

Aug 14 '07 #13

P: n/a
Steve, it wasn't me that raised the comparison
with MFC. If you don't think that's a helpful
comparison, why not reply to that post instead?

I don't mind Björn's suggestion that I don't
know what I'm talking about, because I started
it by telling him he was wrong.

But you don't have that excuse.

(david)


Steve Holden wrote:
[david] wrote:
>Well yes, I have tried this app with native windows,
and I know how to do it.

But if all wxPython can offer is a poor imitation
of MFC, I'm better off using MFC aren't I?

And too all those people who wrote back to insist
that users MUST explicitly build a multi-threaded
framework for wxPython:

It's supposed to already be a framework :~)
The answer is simple. If you don't see any advantage to using wxPython
then don't use it. Personally I believe wxPython is far from a poor
imitation of MFC, but if you are already familiar with MFC then go ahead
and use it.

regards
Steve
Aug 14 '07 #14

P: n/a
[david] wrote:
Steve, it wasn't me that raised the comparison
with MFC. If you don't think that's a helpful
comparison, why not reply to that post instead?
It _was_ a comparison, saying that they follow similar principles.
You twisted this comparison by saying wxPython was an imitation of
MFC. You ignored the fact that your problem is solved by MFC in a
similar way, just as in every other GUI toolkit other posters here
and me know of.
I don't mind Björn's suggestion that I don't
know what I'm talking about,
Where did I write this?
because I started it by telling him he was wrong.
Excuse me, where am I wrong?
Björn

--
BOFH excuse #163:

no "any" key on keyboard

Aug 14 '07 #15

P: n/a
Chris Mellon wrote:
On 8/9/07, Heikki Toivonen <he****@osafoundation.orgwrote:
>>[david] wrote:
>>>I'd like to refresh the display before I start the main loop.
If your window isn't able to interact with the user, then I'd consider
it a splash screen, no matter if it does look exactly like your main
application interface.
>>We have this kind of situation in Chandler, where we display and update
the splash screen before we enter MainLoop.
[...]
>>3. The splash screen refresh is basically: draw new stuff,
self.Layout(), self.Update(), wx.Yield()
http://lxr.osafoundation.org/source/...cation.py#1421
Looking at the Chandler code suggests a solution to [david]'s original
problem. It is possible that, on Windows only, he may need to call
Update to finish painting the display.

1432 self.Layout()
1433 if wx.Platform == '__WXMSW__':
1434 self.Update()
1435 wx.GetApp().Yield(True)
wxYield spins the event loop in place. This can have some serious
consequences if you aren't very careful with your usage, like
recursively entering event handlers. I generally consider it an
experts only interface, and avoid it.
I'll confess to being one of those old-school programmers who, back in
the day, wrote his code around big select loops instead of using
threads, but I'm intriged by the "experts only" designation. Can
someone explain further? Thanks!
Aug 15 '07 #16

P: n/a
On 8/15/07, samwyse <de******@email.comwrote:
Chris Mellon wrote:
On 8/9/07, Heikki Toivonen <he****@osafoundation.orgwrote:
>[david] wrote:

I'd like to refresh the display before I start the main loop.

If your window isn't able to interact with the user, then I'd consider
it a splash screen, no matter if it does look exactly like your main
application interface.
>We have this kind of situation in Chandler, where we display and update
the splash screen before we enter MainLoop.
[...]
>3. The splash screen refresh is basically: draw new stuff,
self.Layout(), self.Update(), wx.Yield()
http://lxr.osafoundation.org/source/...cation.py#1421

Looking at the Chandler code suggests a solution to [david]'s original
problem. It is possible that, on Windows only, he may need to call
Update to finish painting the display.

1432 self.Layout()
1433 if wx.Platform == '__WXMSW__':
1434 self.Update()
1435 wx.GetApp().Yield(True)
wxYield spins the event loop in place. This can have some serious
consequences if you aren't very careful with your usage, like
recursively entering event handlers. I generally consider it an
experts only interface, and avoid it.

I'll confess to being one of those old-school programmers who, back in
the day, wrote his code around big select loops instead of using
threads, but I'm intriged by the "experts only" designation. Can
someone explain further? Thanks!
The biggest problem is recursive events. You can end up entering an
event handler downstack from itself. There's other common problems -
event handlers are generally written to be short and sweet and not to
expect recursion and to complete without interruption. wxYield can
easily end up breaking that. Components that call wxYield are
especially dangerous. For example, some parts of wxWidgets call
wxYield internally. An event handler that aquired a lock was changed
to use one of those components and ended up deadlocking when it was
re-entered by the yield. I've also seen crashes when wxYield processed
a destroy event for a window in the middle of it's own event handler.

Because analyzing your event code to make sure it's reentrant is hard,
and is complicated even more by the fact that wxYield in a component
can cause problems far upstack in a caller, and because there is an
excellent alternative in the form of python generators, I avoid it's
usage from wxPython entirely.
Aug 15 '07 #17

P: n/a
On 2007-08-14, [david] <da***@nospam.spamwrote:
Steve, it wasn't me that raised the comparison
with MFC. If you don't think that's a helpful
comparison, why not reply to that post instead?

I don't mind Björn's suggestion that I don't
know what I'm talking about, because I started
it by telling him he was wrong.

But you don't have that excuse.

(david)
Oh dear, arguing with Steve Holden is a rather inauspicious way
to start out in c.l.p.

--
Grant Edwards grante Yow! CHUBBY CHECKER just
at had a CHICKEN SANDWICH in
visi.com downtown DULUTH!
Aug 15 '07 #18

P: n/a
Looking at the Chandler code suggests a solution
... he may need to call Update to finish painting
the display.

Yes, and thank you to Chandler for pointing that out.

Without the splash screen there was no need to call
Yield or use a generator.

(david)

samwyse wrote:
Chris Mellon wrote:
>On 8/9/07, Heikki Toivonen <he****@osafoundation.orgwrote:
>>[david] wrote:

I'd like to refresh the display before I start the main loop.

If your window isn't able to interact with the user, then I'd consider
it a splash screen, no matter if it does look exactly like your main
application interface.
>>We have this kind of situation in Chandler, where we display and update
the splash screen before we enter MainLoop.
[...]
>>3. The splash screen refresh is basically: draw new stuff,
self.Layout(), self.Update(), wx.Yield()
http://lxr.osafoundation.org/source/...cation.py#1421

Looking at the Chandler code suggests a solution to [david]'s original
problem. It is possible that, on Windows only, he may need to call
Update to finish painting the display.

1432 self.Layout()
1433 if wx.Platform == '__WXMSW__':
1434 self.Update()
1435 wx.GetApp().Yield(True)
>wxYield spins the event loop in place. This can have some serious
consequences if you aren't very careful with your usage, like
recursively entering event handlers. I generally consider it an
experts only interface, and avoid it.

I'll confess to being one of those old-school programmers who, back in
the day, wrote his code around big select loops instead of using
threads, but I'm intriged by the "experts only" designation. Can
someone explain further? Thanks!
Aug 21 '07 #19

P: n/a
Thanks for that suggestion, and sorry I took so
long to get back to you. That worked.

Because I don't want the splash screen, just
self.Update

regards,

[david]

Heikki Toivonen wrote:
[david] wrote:
>I'd like to refresh the display before I start the main loop.

We have this kind of situation in Chandler, where we display and update
the splash screen before we enter MainLoop.

1. Create app object
http://lxr.osafoundation.org/source/...handler.py#080

2. During app object creation, in OnInit, put up splash screen and update it

http://lxr.osafoundation.org/source/...ication.py#433

3. The splash screen refresh is basically: draw new stuff,
self.Layout(), self.Update(), wx.Yield()
http://lxr.osafoundation.org/source/...cation.py#1421

3. Start MainLoop
http://lxr.osafoundation.org/source/...handler.py#086
Aug 21 '07 #20

This discussion thread is closed

Replies have been disabled for this discussion.