My last wxPython problem took a long time to fix and now that it is, I
don't even know why! I'm on wxPython 2402, Python 222, Linux.
When the program launches, the text is "messed up". See here:
http://chuckesterbrook.com/files/python/wx/problems/display-01/1.png
When I resize, or move the window off screen and back on, the text is
displayed correctly:
http://chuckesterbrook.com/files/python/wx/problems/display-01/2.png
The code is here (and inlined further down):
http://chuckesterbrook.com/files/python/wx/problems/display-01/AppFrame.py
My first four individual attempts all failed:
self.Refresh()
self.Update()
self.Show()
wxYield()
My fifth attempt was all four at the same time. That failed.
In my last attempt, I was just reaching:
wxSafeYield()
It worked! But without any threads, long running loops, timers, or
what-have-you, I don't know the answer to any of these questions:
1. Why is any invocation needed at all? Shouldn't the creation of
StaticText in the panel cause the affected region to be updated at
the end of the event loop, or in response to some kind of generated
refresh event?
2. Given that an invocation is needed, why doesn't a simple Refresh()
and/or Update() work?
3. Given that wxSafeYield() works, why doesn't wxYield()? If I read the
docs right, wxSafeYield() is like wxYield(), but it locks out user
input. I don't see the relation to this code.
4. How come the problem also disappears if the second page of the
notebook is not added???
I feel totally lost now, wondering where else I might have to sprinkle
in wxSafeYields(). I've read plenty of wxPython wikis, mails and docs,
but I can't relate the required wxSafeYield() in this program to its
simple set up (a notebook with two pages and some static text added
in). There's the activate event of course, but it *seems* harmless.
Any insights are greatly appreciated!
The code:
http://chuckesterbrook.com/files/python/wx/problems/display-01/AppFrame.py
And inlined:
from wxPython.wx import *
class AppFrame(wxFrame):
def __init__(self):
wxFrame.__init__(self, None, -1, "", size=(200, 200))
self.firstTime = True
self.nb = wxNotebook(self, -1)
wrapper = wxPanel(self.nb, -1)
self.myView = MyView(wrapper, -1)
sizer = wxBoxSizer(wxHORIZONTAL)
sizer.Add(self.myView, 1, wxEXPAND)
wrapper.SetSizer(sizer)
self.nb.AddPage(wrapper, "A")
if 1:
# btw, if no second notebook page is added, the problem goes away
# (otherwise wx.SafeYield is required)
v = wxPanel(self.nb, -1)
self.nb.AddPage(v, "B")
EVT_ACTIVATE(self, self.onActivate)
def onActivate(self, e):
if self.firstTime:
self.myView.addLabels()
self.firstTime = False
e.Skip() # don't know if this is needed, but doesn't affect the \
problem either way
class MyView(wxPanel):
def addLabels(self):
# this method is called in response to our (ultimately) containing \
frame's on-activate event.
self.addLabel('Hello, world.', 10, 10)
# none of the following are sufficient, even together.
# self.Refresh()
# self.Update()
# self.Show()
# wxYield()
# SafeYield is the *only* invocation here that fixes the display \
problem!
# wxSafeYield()
def addLabel(self, msg, x, y):
color = wxColor(255, 255, 127)
offsets = [
(+1, +1),
(-1, -1),
(+1, -1),
(-1, +1),
]
for dx, dy in offsets:
text = wxStaticText(self, -1, msg, wxPoint(x+dx, y+dy))
text.SetForegroundColour(color)
wxStaticText(self, -1, msg, wxPoint(x, y))
if __name__=='__main__':
wxApp = wxPySimpleApp()
AppFrame().Show()
wxApp.MainLoop()