Size a frame to fit

I have a very simple application that looks like

frame
    panel
        horizontal sizer
            text control
            text control

During init I would like the panel and frame to automatically resize to just contain the two side-by-side text controls (it’s a countdown timer with two intervals). At the moment I just fiddle with the frame size to get it right, but there should be an automatic way to do this if, for example, I increase or decrease the font of the text controls. Any suggestions? I’ve tried

self.Fit()

but this makes the frame so small it hides the text controls.

Does this do what you want?

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.SetTitle("Fit 2 TextCtrls")
        self.panel_1 = wx.Panel(self, wx.ID_ANY)
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        self.text_ctrl_1 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
        self.text_ctrl_1.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
        sizer_1.Add(self.text_ctrl_1, 0, 0, 0)
        self.text_ctrl_2 = wx.TextCtrl(self.panel_1, wx.ID_ANY, "")
        self.text_ctrl_2.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
        sizer_1.Add(self.text_ctrl_2, 0, 0, 0)
        self.panel_1.SetSizer(sizer_1)
        sizer_1.Fit(self)
        self.Layout()

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

Screenshot at 2024-01-06 08-38-39

Tested using Python 3.10.12 + wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1 on Linux Mint 21.2

Aaaarrrrggghhh!

I tried “fit” on the frame thinking that was what had to be adjusted to fit, I didn’t think to try it on the sizer. I added that one line and was fine. I should have been looking from the inside out rather than outside in. Thanks.

Someone once said “I’m battling elephants and losing to fleas.” It’s always in the little details.

Woods and trees come mind as well, as in couldn’t see one for the other. :slight_smile:
The amount of coding time devoted to ‘losing to fleas’ is astonishing.
Best walk away and do something else, it’s amazing how often the lightbulb comes on, if you do.
Personally, I’ve lost more battles to fleas, than I care to count. :wink:

well, collect all these fleas, wrap them with an AI sticker on and you may be out of the woods :hatched_chick:

I think that’s the way to go when you separate the panel and the frame classes like:

class MyPanel(wx.Panel): 
    def __init__(self, *args, **kwds):
        wx.Panel.__init__(self, *args, **kwds)

        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
        
        self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "")
        self.text_ctrl_1.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
        sizer_1.Add(self.text_ctrl_1, 0, 0, 0)
        
        self.text_ctrl_2 = wx.TextCtrl(self, wx.ID_ANY, "")
        self.text_ctrl_2.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, 0, ""))
        sizer_1.Add(self.text_ctrl_2, 0, 0, 0)

        self.SetSizer(sizer_1)
        sizer_1.Fit(self)


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        
        self.panel_1 = MyPanel(self, wx.ID_ANY)
        self.Fit()

MyFrame(None).Show()

Fit works as expected since the frame knows the client’s best size.

https://docs.wxpython.org/window_sizing_overview.html

Truly. I’ll go to bed. :sleeping_bed::zzz:

You can always ask auntie Emma, helps in 99% of cases.