Search code examples
wxpython

wxPython Panel is two shades of gray?


sure this is easy for you. :) But I am trying to open a "preferences" menu and have it pop up and display the applications stored preferences. My issue is now cosmetic, I have no idea what the little "tetris piece" is on the upper left corner of my app. It is the color that I want to fill the entire frame, but I can't quite figure out how to do that.

Here's an image:

enter image description here

Here's my panel code re: the sizer in use:

def __init__(self):
    """Constructor"""
    import wx.lib.inspection
    wx.lib.inspection.InspectionTool().Show()                    

    wx.Frame.__init__(self, None, title="Title Options", size=(520, 390))

    prefPanel = wx.Panel(self)
    prefPanel = self

    # SET THE SIZER OBJECT UP
    prefSizer = wx.GridBagSizer(13, 9)

    # SET BASELINE INDEX VARIABLES
    xIndex = 0
    yIndex = 0

# DEFAULT DATABSE EXTENSIONS
    self.tc_DBExt = wx.TextCtrl(prefPanel, -1, "", (0,0), (150,21))
    self.label_DBExt = wx.StaticText(prefPanel, label="Default Database Extensions:")
    help_tc_DBExt= "Enter this as: *.<extension>"
    self.tc_DBExt.SetToolTip(wx.ToolTip(help_tc_DBExt))        
    self.tc_DBExt.Value = guiFunctions.configMe("general", "database_extensions")

    prefSizer.Add(self.label_DBExt, pos=(xIndex, 0), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=10)
    prefSizer.Add(self.tc_DBExt, pos=(xIndex, 1), span=(1,5), flag=wx.EXPAND|wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=10).SetMinSize((200,22))


    panel.SetSizer(sizer2)
    sizer2.Fit(panel)

    panel.Refresh()
    panel.Update()
    panel.Layout()

How do I get the little guy up in that lefthand corner to fill the entire panel?

UPDATE: Added widget info in case I am applying things in the wrong order...


Solution

  • Short answer: You may or may not have a parent panel, but you did not make it sizing properly. Because wx.Frame on Windows has a dark gray background, it will shine through if you do not use a wx.Panel instead (and make it size properly).

    Long answer: Tried to include a minimum running example from your code. It looks ugly (TextCtrl and Button), because the definition panel comes from outside and it is very difficult to synchronize their sizers. It would be much better to do all element creation/sizing in one wx.Panel/wx.Frame. All my comments to your code are include in triple quotes and should give you an idea why that what you are trying to do is complicated/bad/simple not working.

    import wx
    
    class panel_class(wx.Panel):
        def __init__(self, *args, **kwds):
            """Trying to implement your magic ``panel```"""
            wx.Panel.__init__(self, *args, **kwds)
            pnl = self
            szmain = wx.BoxSizer(wx.HORIZONTAL)
            szmain.Add(wx.TextCtrl(pnl, -1, 'Database path'), 1, wx.EXPAND)
            szmain.Add(wx.Button(pnl, -1, 'Database path'), 0, wx.EXPAND)
            pnl.SetSizer(szmain)
    
    
    class myframe(wx.Frame):
        def __init__(self, *args, **kwds):
            """Constructor"""
    
            wx.Frame.__init__(self, *args, **kwds)#None, title="Title Options", size=(520, 390))
    
            prefPanel = wx.Panel(self)
    
            """This makes no sense: according to the wx.Frame.__init__ above self is a wx.Frame."""
    #         prefPanel = self
    
            # SET THE SIZER OBJECT UP
            prefSizer = wx.GridBagSizer(13, 9)
    
            # SET BASELINE INDEX VARIABLES
            xIndex = 0
            yIndex = 0
    
            # DEFAULT DATABSE EXTENSIONS
            self.tc_DBExt = wx.TextCtrl(prefPanel, -1, "", (0,0), (150,21))
            self.label_DBExt = wx.StaticText(prefPanel, label="Default Database Extensions:")
            help_tc_DBExt= "Enter this as: *.<extension>"
            self.tc_DBExt.SetToolTip(wx.ToolTip(help_tc_DBExt))
            """Replaced with something static."""
            self.tc_DBExt.Value = 'conftxt'#guiFunctions.configMe("general", "database_extensions")
    
            prefSizer.Add(self.label_DBExt, pos=(xIndex, 0), flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=10)
            prefSizer.Add(self.tc_DBExt, pos=(xIndex, 1), span=(1,5), flag=wx.EXPAND|wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=10).SetMinSize((200,22))
    
            """Assuming panel definition from outside.
    
            It has to be created here. If it is to be created **before**
            the parent is created, it is very complicated to create it with a
            dummy parent and ``Reparent`` it to this Frame/Panel. Don't do that."""
    
            panel = panel_class(prefPanel, -1)
    
            """Attach ``panel`` to a sizer in **this** hierarchy
            It looks disconnected, because it has brought already it's own
            sizer, which is child to the GridBagSizer.""" 
            xindex = 1
            prefSizer.Add(panel, pos=(xindex, 0), span=(1,5), flag=wx.EXPAND|wx.LEFT|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=10).SetMinSize((200,22))
    
            """You have to tell wxPython somehow to what element the sizer is coupled (in this case to the main pane)l"""
            prefPanel.SetSizer(prefSizer)
    
            """I have no idea """
            #panel.SetSizer(sizer2)
            #sizer2.Fit(panel)
    
            """Normally not needed/happening automagically on standard controls"""    
            #panel.Refresh()
            #panel.Update()
            #panel.Layout()
    
        def add_panel_to_layout(self):
            pass
    
    if __name__ == '__main__':
        app = wx.App(0)
    
        frm = myframe(None, -1,  title="Title Options", size=(520, 390))
    
        frm.Show()
    
        """Call it here **after** all elements have been created"""
        import wx.lib.inspection
        wx.lib.inspection.InspectionTool().Show()
        app.MainLoop()
    

    Rules for working with Sizers in wxPython:

    • Always use a wx.Panel as parent for your controls. It does not matter if your controls are themselves parented on panels, you can stack them atop as many layers as you want. If you parent direct to a wx.Frame, you will get the ugly grey background on Windows.
    • Define your control objects (can again be a panel)
    • Select an appropriate sizer
    • Layout all your elements in the sizer
    • IMPORTANT: tell your main sizer to which parent element to orient itself (main_panel.SetSizer(mymainsizer))
    • Tell the sizer of the main panel which size of the panel parent to adapt to (mymainsizer.Fit(self), assuming self is the parent of main_panel. Use self.SetSize((<w>, <h>)) if Fit goes wrong.

    Example sizer for this question