Sizeable static text

Hello all,
I try to display a static text which shall wordwrap and use the available space.
Several months ago Robin Dunn suggested a solution
(http://article.gmane.org/gmane.comp.python.wxpython/56713) and it works in
principle. But one point remains:

If I change the text later on and want to show a shorter one, the old, longer
text is visible until the next resize.

The sourcecode below demonstrates the problem.
* start the form
* press the button and see the mixture of both texts
* Resize and everything is fine

I tried to use a CallAfter in the SetLabel Procedure but to no avail.

Thanks for listening !

Norbert
Follows the sourcecode.

···

-----
#!/usr/bin/env python

# http://article.gmane.org/gmane.comp.python.wxpython/56713
import wx
print wx.version()

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.st = wx.StaticText(self, -1, label, style=style)
        self._label = label # save the unwrapped text
        self._Rewrap()
        self.Bind(wx.EVT_SIZE, self.OnSize)

    def SetLabel(self, label):
        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)
        self.st.Thaw()

    def DoGetBestSize(self):
        # this should return something meaningful for what the best
        # size of the widget is, but what that size should be while we
        # still don't know the actual width is still an open
        # question... Just return a dummy value for now.
        return wx.Size(100,100)

text = """\
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 to grow ripe it was
found that every night one of them
was gone. The king became very angry at this, and ordered the gardener to keep
watch all night under the
tree. The gardener set his eldest son to watch; but about twelve o'clock he fell
asleep, and in the morning
another of the apples was missing. Then the second son was ordered to watch; and
at midnight he too fell
asleep, and in the morning another apple was gone. Then the third son offered to
keep watch; but the
gardener at first would not let him, for fear some harm should come to him:
however, at last he consented,
and the young man laid himself under the tree to watch. As the clock struck
twelve he heard a rustling noise
in the air, and a bird came flying that was of pure gold; and as it was snapping
at one of the apples with its
beak, the gardener's son jumped up and shot an arrow at it. But the arrow did
the bird no harm; only it dropped
a golden feather from its tail, and then flew away. The golden feather was
brought to the king in the
morning, and all the council was called together. Everyone agreed that it was
worth more than all the
wealth of the kingdom: but the king said, 'One feather is of no use to me, I
must have the whole bird.'
"""

class TestFrame(wx.Frame):
    def __init__(self, *args, **kw):
        wx.Frame.__init__(self, *args, **kw)

        p = wx.Panel(self)
        btn = wx.Button(p,-1,"Short Text")
        box = wx.StaticBox(p, -1, "AutoWrapStaticText")
        sbs = wx.StaticBoxSizer(box, wx.VERTICAL)
        self.awst = AutoWrapStaticText(p, label=text)
        sbs.Add(self.awst, 1, wx.EXPAND)

        sizer = wx.BoxSizer()
        sizer.Add(sbs, 1, wx.EXPAND|wx.ALL, 25)
        p.SetSizer(sizer)
        self.Bind(wx.EVT_BUTTON, self.ShortText, btn)
    def ShortText(self, event):
        self.awst.SetLabel('This is a short text')

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()

Hello,

Try calling self.st.Refresh() and or self.Layout() after changing the text to tell the window(s) to update.

···

On Fri, Oct 3, 2008 at 8:28 AM, Norbert Klamann Norbert.Klamann@projecthome.de wrote:

Hello all,

I try to display a static text which shall wordwrap and use the available space.

Several months ago Robin Dunn suggested a solution

(http://article.gmane.org/gmane.comp.python.wxpython/56713) and it works in

principle. But one point remains:

If I change the text later on and want to show a shorter one, the old, longer

text is visible until the next resize.

The sourcecode below demonstrates the problem.

  • start the form

  • press the button and see the mixture of both texts

  • Resize and everything is fine

I tried to use a CallAfter in the SetLabel Procedure but to no avail.

Thanks for listening !

Norbert

Follows the sourcecode.


#!/usr/bin/env python

http://article.gmane.org/gmane.comp.python.wxpython/56713

import wx

print wx.version()

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.st](http://self.st) = wx.StaticText(self, -1, label, style=style)

    self._label = label # save the unwrapped text

    self._Rewrap()

    self.Bind(wx.EVT_SIZE, self.OnSize)



def SetLabel(self, label):

    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)

    self.st.Thaw()



def DoGetBestSize(self):

    # this should return something meaningful for what the best

    # size of the widget is, but what that size should be while we

    # still don't know the actual width is still an open

    # question...  Just return a dummy value for now.

    return wx.Size(100,100)

text = “”"\

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 to grow ripe it was

found that every night one of them

was gone. The king became very angry at this, and ordered the gardener to keep

watch all night under the

tree. The gardener set his eldest son to watch; but about twelve o’clock he fell

asleep, and in the morning

another of the apples was missing. Then the second son was ordered to watch; and

at midnight he too fell

asleep, and in the morning another apple was gone. Then the third son offered to

keep watch; but the

gardener at first would not let him, for fear some harm should come to him:

however, at last he consented,

and the young man laid himself under the tree to watch. As the clock struck

twelve he heard a rustling noise

in the air, and a bird came flying that was of pure gold; and as it was snapping

at one of the apples with its

beak, the gardener’s son jumped up and shot an arrow at it. But the arrow did

the bird no harm; only it dropped

a golden feather from its tail, and then flew away. The golden feather was

brought to the king in the

morning, and all the council was called together. Everyone agreed that it was

worth more than all the

wealth of the kingdom: but the king said, 'One feather is of no use to me, I

must have the whole bird.’

“”"

class TestFrame(wx.Frame):

def __init__(self, *args, **kw):

    wx.Frame.__init__(self, *args, **kw)



    p = wx.Panel(self)

    btn = wx.Button(p,-1,"Short Text")

    box = wx.StaticBox(p, -1, "AutoWrapStaticText")

    sbs = wx.StaticBoxSizer(box, wx.VERTICAL)

    self.awst = AutoWrapStaticText(p, label=text)

    sbs.Add(self.awst, 1, wx.EXPAND)



    sizer = wx.BoxSizer()

    sizer.Add(sbs, 1, wx.EXPAND|wx.ALL, 25)

    p.SetSizer(sizer)

    self.Bind(wx.EVT_BUTTON, self.ShortText, btn)

def ShortText(self, event):

    self.awst.SetLabel('This is a short text')

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()


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Cody Precord <codyprecord <at> gmail.com> writes:

Hello,
Try calling self.st.Refresh() and or self.Layout() after changing the text to

tell the window(s) to update.

Thanks a lot Cody, for the fast reply.
I tried both statements in the SetLabel procedure and as a CallAfter to no avail.

Does anyone have another idea ?

Thanks again

Norbert

Hello,

Sorry I didn’t look at your code very closely before. Call Refresh on the StaticBox that contains your text after you make the change.

···

On Fri, Oct 3, 2008 at 9:26 AM, Norbert Klamann Norbert.Klamann@projecthome.de wrote:

Cody Precord <codyprecord gmail.com> writes:

Hello,

Try calling self.st.Refresh() and or self.Layout() after changing the text to

tell the window(s) to update.

Thanks a lot Cody, for the fast reply.

I tried both statements in the SetLabel procedure and as a CallAfter to no avail.

Does anyone have another idea ?

Thanks again

Norbert


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Cody Precord <codyprecord <at> gmail.com> writes:

Hello,
Sorry I didn't look at your code very closely before. Call Refresh on the

StaticBox that contains your text after you make the change.On Fri, Oct 3, 2008

That works fine , Thanks again

Corrected version follows for the record.

···

--------
#!/usr/bin/env python

# based on http://article.gmane.org/gmane.comp.python.wxpython/56713
import wx
print wx.version()

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.st = wx.StaticText(self, -1, label, style=style)
        self._label = label # save the unwrapped text
        self._Rewrap()
        self.parent= parent
        self.Bind(wx.EVT_SIZE, self.OnSize)

    def SetLabel(self, label):
        self._label = label
        self._Rewrap()
        self.parent.Refresh()

    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)
        self.st.Thaw()

    def DoGetBestSize(self):
        # this should return something meaningful for what the best
        # size of the widget is, but what that size should be while we
        # still don't know the actual width is still an open
        # question... Just return a dummy value for now.
        return wx.Size(100,100)

text = """\
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 to grow ripe it was
found that every night one of them
was gone. The king became very angry at this, and ordered the gardener to keep
watch all night under the
tree. The gardener set his eldest son to watch; but about twelve o'clock he fell
asleep, and in the morning
another of the apples was missing. Then the second son was ordered to watch; and
at midnight he too fell
asleep, and in the morning another apple was gone. Then the third son offered to
keep watch; but the
gardener at first would not let him, for fear some harm should come to him:
however, at last he consented,
and the young man laid himself under the tree to watch. As the clock struck
twelve he heard a rustling noise
in the air, and a bird came flying that was of pure gold; and as it was snapping
at one of the apples with its
beak, the gardener's son jumped up and shot an arrow at it. But the arrow did
the bird no harm; only it dropped
a golden feather from its tail, and then flew away. The golden feather was
brought to the king in the
morning, and all the council was called together. Everyone agreed that it was
worth more than all the
wealth of the kingdom: but the king said, 'One feather is of no use to me, I
must have the whole bird.'
"""

class TestFrame(wx.Frame):
    def __init__(self, *args, **kw):
        wx.Frame.__init__(self, *args, **kw)

        p = wx.Panel(self)
        btn = wx.Button(p,-1,"Short Text")
        box = wx.StaticBox(p, -1, "AutoWrapStaticText")
        sbs = wx.StaticBoxSizer(box, wx.VERTICAL)
        self.awst = AutoWrapStaticText(p, label=text)
        sbs.Add(self.awst, 1, wx.EXPAND)

        sizer = wx.BoxSizer()
        sizer.Add(sbs, 1, wx.EXPAND|wx.ALL, 25)
        p.SetSizer(sizer)
        self.Bind(wx.EVT_BUTTON, self.ShortText, btn)
    def ShortText(self, event):
        self.awst.SetLabel('This is a short text')

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()