SplitterWindow sash not visible on Windows

No matter what style(s) I enable, the sash is never visible. I’m using wxFormBuilder to create the UI. Everything works as expected, the only problem is the sash isn’t visible.

I can only embed one image, so I’ll add a screenshot in a reply.

Here’s the structure in wxFormBuilder:

And all mentions of the Splitter in the generated Frame code:

        self.m_splitter1 = wx.SplitterWindow( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.SP_3D|wx.SP_THIN_SASH )
        self.m_splitter1.SetSashGravity( 0.5 )
        self.m_splitter1.Bind( wx.EVT_IDLE, self.m_splitter1OnIdle )
        self.m_splitter1.SetMinimumPaneSize( 50 )
...
        self.m_panel1 = wx.Panel( self.m_splitter1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
...
        self.m_panel2 = wx.Panel( self.m_splitter1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
...
        self.m_splitter1.SplitHorizontally( self.m_panel1, self.m_panel2, 0 )
        bSizer7.Add( self.m_splitter1, 1, wx.EXPAND, 5 )
...
    def m_splitter1OnIdle( self, event ):
        self.m_splitter1.SetSashPosition( 0 )
        self.m_splitter1.Unbind( wx.EVT_IDLE )

Any suggestions on how to get the sash to be visible?

Screenshot showing the sash is there and functional, just not visible.

Unfortunately that’s now the standard on Windows. If you don’t know that there is a splitter, you’re lost…

Ah yes, “broken as designed”. Invented at IBM in the '70s but embraced by all software manufacturers over time -:frowning:

Hi, I am also working on Windows and noticed a similar behavior. Here are my observations regarding the styles in wxFormBuilder:

By default, wxFormBuilder enables wxSP_3D. If you also check wxSP_NO_XP_THEME, the border style changes and the sash becomes visible. Based on this, I found that:

  • If wxSP_3D is unchecked: Checking wxSP_3DBORDER or wxSP_BORDER only changes the border.
  • If wxSP_3D is unchecked: Checking wxSP_3DSASH only makes the sash appear.

Conclusion:
It seems that wxSP_3D behaves as:
wxSP_3D = (wxSP_3DSASH | wxSP_3DBORDER) or (wxSP_3DSASH | wxSP_BORDER)

Workaround:
If you only want to display the sash, try enabling wxSP_NO_XP_THEME. This works successfully in both the wxFormBuilder preview (press F5 than OK) and the following code:

import wx

class MyFrame2(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(
            self,
            parent,
            id=wx.ID_ANY,
            title=wx.EmptyString,
            pos=wx.DefaultPosition,
            size=wx.Size(500, 300),
            style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL,
        )

        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
        bSizer47 = wx.BoxSizer(wx.VERTICAL)

        # Applying wxSP_3DSASH | wxSP_NO_XP_THEME
        self.m_splitter4 = wx.SplitterWindow(
            self,
            wx.ID_ANY,
            wx.DefaultPosition,
            wx.DefaultSize,
            wx.SP_3DSASH | wx.SP_NO_XP_THEME,
        )
        self.m_splitter4.Bind(wx.EVT_IDLE, self.m_splitter4OnIdle)

        self.m_panel14 = wx.Panel(
            self.m_splitter4,
            wx.ID_ANY,
            wx.DefaultPosition,
            wx.DefaultSize,
            wx.TAB_TRAVERSAL,
        )
        self.m_panel15 = wx.Panel(
            self.m_splitter4,
            wx.ID_ANY,
            wx.DefaultPosition,
            wx.DefaultSize,
            wx.TAB_TRAVERSAL,
        )
        self.m_splitter4.SplitVertically(self.m_panel14, self.m_panel15, 200)
        bSizer47.Add(self.m_splitter4, 1, wx.EXPAND, 5)

        self.SetSizer(bSizer47)
        self.Layout()
        self.Centre(wx.BOTH)

    def m_splitter4OnIdle(self, event):
        self.m_splitter4.SetSashPosition(200)
        self.m_splitter4.Unbind(wx.EVT_IDLE)

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

Result:

Side Note: I noticed that checking wxSP_THIN_SASH causes an error in the wxFormBuilder preview, but the code runs without issues in the actual application.