Hi,
I’ll post the code below, it’s runnable. It’s python 2.x and wxpython 3.0-gtk.
(I would be trying Python 3 if Phoenix were in the Linux repos.)
The ghost of AutoWrapStaticText rises again.
The thing:
I want a StaticText label which can:
- Have its content changed any time: SetLabel(“some new whatever”)
- It should then wrap (or not) and
- resize its surrounds (somehow).
The test code has a BoxSizer like so:
label
···
–
text control
button
The button sets a long/short string on the label. I am hoping to see the sizer change as the the label changes.
I guess it’s something to do with Layout/Fit, but I can’t find the magic. At the moment it only redraws when you manually resize the frame.
If I can’t get past this hurdle, I will use the ellipses thing to indicate to the user that the window must be made wider.
Any clues?
/d
CODE:
When run, drag the frame a bit first.
import wx
class AutoWrapStaticText(wx.PyControl):
def init(self, parent, id=-1, label="",
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name=“wrapStatText”):
wx.PyControl.init(self, parent, id, pos, size, wx.NO_BORDER,
wx.DefaultValidator, name)
self.p = parent
[self.st](http://self.st) = wx.StaticText(self, -1, label, style=style)
self._label = label
self._rows = 0
# Measure the string once, to get a lineheight.
# My thinking is it will be faster to math
# with that than to render and measure
# the entire string each time.
f = self.st.GetFont()
dc = wx.ScreenDC()
dc.SetFont(f)
w,h,lh = dc.GetMultiLineTextExtent(label,f)
self._lineheight = lh
self._Rewrap()
self.Bind(wx.EVT_SIZE, self.OnSize)
def _lh(self):
# return a tup of parent width, text height
# lineheight * rows should = ~ height
h = self._rows * self._lineheight
sz = ( self.p.GetSize()[0], h )
print sz
return sz
def SetLabel(self, label):
# This is the NB one. I need to set different
# strings - and they can be long or short.
# I.e. they can wrap or not.
# The space the string is in should resize,
# but I can't get it right.
self._label = label
self._Rewrap()
def GetLabel(self):
return self._label
def SetFont(self, font):
self.st.SetFont(font)
self._Rewrap()
def GetFont(self):
return self.st.GetFont()
def OnSize(self, evt):
self.st.SetSize(self.GetSize())
self._Rewrap()
def _Rewrap(self):
self.st.Freeze()
self.st.SetLabel(self._label)
self.st.Wrap(self.GetSize().width)
# here I count the rows:
self._rows = self.st.GetLabel().count("\n") + 1
self.st.Thaw()
def DoGetBestSize(self):
# Trying to use the lineheight etc.
return self._lh()
longstring = “A certain king had a beautiful garden, and in the garden stood a tree which bore golden apples. These apples were always counted, and about the time when they began.”
shortstring = “I am set to a shortstring.”
txt = “This area should move up/down as the string above changes and/or wraps.”
class TestFrame(wx.Frame):
def init(self, *args, **kw):
wx.Frame.init(self, *args, **kw)
p = wx.Panel(self)
bs = wx.BoxSizer(wx.VERTICAL)
# First slot - the wrap text
self.awst = AutoWrapStaticText(p, label=longstring)
bs.Add(self.awst, 0, wx.EXPAND)
# Second slot - the text ctrl
printer = wx.TextCtrl(p, -1, txt,
style = wx.TE_READONLY | wx.TE_MULTILINE)
bs.Add(printer, 1, wx.EXPAND)
# Last slot the button
b = wx.Button( p, label = "press me" )
self.tog = True
self.Bind(wx.EVT_BUTTON, self._press, b)
bs.Add(b, 0)
p.SetSizer(bs)
p.Layout() # guessing.
def _press(self, evt):
self.awst.SetLabel(shortstring if self.tog else longstring)
self.tog = not self.tog
app = wx.App(redirect=False)
frm = TestFrame(None, title=“test wrapping static text”)
frm.Show()
#import wx.lib.inspection
#wx.lib.inspection.InspectionTool().Show()
app.MainLoop()