(Newbie) Size of StaticText after font change

I’m just getting started with wxPython, and I’m working with the “Hello, World Part 2” example at https://wxpython.org/pages/overview/#hello-world-part-2 . The wx.StaticText widget seems to be getting created correctly, but when the font is changed, the widget is not resized. It appears that the overview’s author intended for the widget to be resized when the font size is changed, and the screenshots back this up.

I’m not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.

I’m using the python3-wxgtk4.0 package on Ubuntu 19.04. A screenshot of the broken version (without the SetSize call) is attached, as well as source code for my fixed version with the “SetSize” call.

Am I doing something wrong? Is this just a behavior that changed in Phoenix, and the example is meant to be pre-Phoenix? This feels like I’m doing things the wrong way, but I’m new here and don’t know what the right way is.

A related doc note: in the wxPython wx.Window docs at https://wxpython.org/Phoenix/docs/html/wx.Window.html , the docs don’t describe GetTextExtent, but they do refer to it in the SetFont description. The GetFullTextExtent method description doesn’t describe how it differs from GetTextExtent. (I suspect the difference is that GetTextExtent only returns the x and y values from C++'s wxWindow::GetTextExtent, while Python’s GetFullTextExtent also returns the descent and externalLeading parameters. But this did take some digging to figure out.)

Thanks,

Piquan

HelloWorldFail.png

xfr.py (938 Bytes)

The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.

···

On May 17, 2019, at 7:38 PM, Joel Holveck <piquan@gmail.com> wrote:

I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.


Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.

The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.

Thanks for the suggestion. I did try that. I also tried calling Fit, and SetSize(-1, -1). None of these seemed to have a useful effect.

Piquan

Hi,

wx.StaticText autosizing does not work when changing font under Phoenix
(which is usually built with GTK3, so the latter may have something to
do with it), it stays at the size of the initial label font until
manually updating the size. The only reliable work-around I found was to
use GetTextExtent() to figure out the correct size, like you did. I've
reported the issue[1]. Possibly related: [2] (I also don't think the
"fix" for [2] is a good one because it is non-obvious and
platform-specific. StaticText should automatically do the right thing
when a label/font is changed).

Florian.

[1] https://github.com/wxWidgets/Phoenix/issues/1228
[2] https://github.com/wxWidgets/Phoenix/issues/1182

···

Am 19.05.2019 um 08:25 schrieb Piquan Holveck:

I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.

The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.

Thanks for the suggestion. I did try that. I also tried calling Fit, and SetSize(-1, -1). None of these seemed to have a useful effect.

Piquan

If the best size has already been calculated then it could be returning a cached value. I find it’s best to call InvalidateBestSize so that cached value will be wiped out. Then the next time there’s a sizer layout a new best size will be calculated (and cached.) In this example, since there is no sizer used, then the new size can be calculated and the widget resized, like this:

    st.InvalidateBestSize()

    st.SetSize(st.BestSize)
···

On Saturday, May 18, 2019 at 9:56:27 PM UTC-7, Tim Roberts wrote:

On May 17, 2019, at 7:38 PM, Joel Holveck piquan@gmail.com wrote:

I’m not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.

The control should automatically resize itself when you call SetLabel.

Robin

Hi all - is this really the outcome of the question? I am also having this problem in wxStaticText on Mac OSX and find it ridiculous that people should have to go through such an ordeal to update a text label.

Is there a better answer here?

Please create a small sample that shows the problem you are having on OSX, as the problems discussed here were mostly due to problems in the wx GTK3 port.

Same problem. Testing is Ubuntu 16.04, wxPython-4.0.7.post2

SetSize(st.GetTextExtent(st.GetLabel())) remedies the problem however not in Choicebook panel inside a sizer. Works fine in Simplebook and Notebook panels. Very strange.

  import wx
  
  class PageNoSizer(wx.Panel):
      def __init__(self, parent):
          super().__init__(parent)
          self.SetBackgroundColour(wx.BLACK)
          st = wx.StaticText(self, label="HELLO WORLD", pos=(60, 55), style=wx.TE_CENTER | wx.EXPAND | wx.ALL)
          
          st.SetForegroundColour(wx.Colour(0x00FF44))
          stylish_font = wx.Font(wx.FontInfo(20).FaceName("liberation").Bold())
          st.SetFont(stylish_font)
          st.SetSize(st.GetTextExtent(st.GetLabel()))
          
          btn = wx.Button(self, label="Next Page")
          self.Bind(wx.EVT_BUTTON, parent.OnNextPage, btn)
          
  class PageWithSizer(wx.Panel):
      def __init__(self, parent):
          super().__init__(parent)
          self.SetBackgroundColour(wx.BLACK)
          
          vbox = wx.BoxSizer(wx.VERTICAL)
          st = wx.StaticText(self, label="HELLO WORLD", style=wx.TE_CENTER | wx.EXPAND | wx.ALL)
          
          st.SetForegroundColour(wx.Colour(0x00FF44))
          stylish_font = wx.Font(wx.FontInfo(20).FaceName("liberation").Bold())
          st.SetFont(stylish_font)
          st.SetSize(st.GetTextExtent(st.GetLabel()))
          
          vbox.Add(st)
          
          btn = wx.Button(self, label="Next Page")
          vbox.Add(btn, 0, wx.ALIGN_RIGHT)
          self.Bind(wx.EVT_BUTTON, parent.OnNextPage, btn)
          
          self.SetSizer(vbox)
  
  # class TestingBook(wx.Simplebook):
  class TestingBook(wx.Choicebook):
  # class TestingBook(wx.Notebook):
      def __init__(self, parent):
          super().__init__(parent)
  
          noSizer = PageNoSizer(self)      
          withSizer = PageWithSizer(self)  
   
          self.AddPage(noSizer, "PageNoSizer")
          self.AddPage(withSizer, "PageWithSizer")
          
      def OnNextPage(self, evt):
          current = self.GetSelection()
          current += 1
          if current >= self.GetPageCount():
              current = 0
          self.ChangeSelection(current)
  
  class MainFrame(wx.Frame):
      
      def __init__(self):
          wx.Frame.__init__(self, None, size=wx.Size(800, 600))
          TestingBook(self)
          self.Show()
  
  if __name__ == '__main__':
      app = wx.App(redirect=False)
      frame = MainFrame()
      app.MainLoop()

If you are creating a wxPython application that is meant to run on GTK (eg, linux, RPi) and you run into problems described in this thread…

Use this generic version of StaticText rather than wx.StaticText.

from wx.lib.stattext import GenStaticText as StaticText
static_text_instance = StaticText(...)

# Replaces this
# static_text_instance = wx.StaticText(...)

Behaves correctly in sizers too!!

On the other hand, creating a StaticText and then immediately changing the font is quite unusual. Certainly it’s too unusual for a Hello World example.

I would rather suggest to remove the font change and put a second element into the the sizer. E.g. a button with an event handler. Or maybe a button and a text control, where the button event handler reads the text, modifies it, puts it back into the text control and reports the result in a MessageDialog.

This way the reader has the basic building blocks for a simple application.

The font example is something one might need in the second year of using wx…

Dang, this didn’t work for me.

I’m calling
wx.Font(25, wx.MODERN, wx.ITALIC, wx.NORMAL)

and then
self.introText = StaticText(self.panel, label=“Some Text”)

finally I add self.introText to a StaticBoxSizer.

The text rendered from self.introText remains as it did with defaults.

I rather suspect I may be missing something with respect to producing text for my interfaces.
Any advice would be greatly appreciated.

Cheers :smiley:

Please forgive the edit, I neglected to mention I’m on the latest phoenix on a fully updated raspbian/raspberry pi 4 4GB

Heh,
As usual, I should have looked at one more resource before hitting the forums. Here’s what worked:

font = wx.Font(25,wx.MODERN,wx.ITALIC,wx.NORMAL)

self.introTxt = StaticText(self.panel, label= “Try.”)

self.introTxt.SetFont(font)

Thanks for looking at my question just the same :smiley: