Search code examples
pythonwxpythonsizer

Cant add a text control without blocking the toolbar in wxpython


I reproduced the error here;

import wx
import debug

class MyFrame(wx.Frame):


    def __init__(self, parent):

        wx.Frame.__init__(self, parent, -1, "Test")
        self.SetSize((600,500))

        vbox = wx.BoxSizer(wx.VERTICAL)
        toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
        toolbar.Realize()
        vbox.Add(toolbar, 0, border=5)

app = wx.App(0)

frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()

app.MainLoop()

Now wherever i add this line to add a text control;

self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)

it appears over the toolbar. I read the documentation and followed some tutorials but still i cant fully grasp the concept. How can i achieve what i want? I want the text control to appear below the toolbar and fit the remaining space.


Solution

  • Well, there are a couple of issues

    1. you haven't added the TextCtrl to the BoxSizer, so it won't get laid out
    2. you haven't set the sizer for the Frame

    You can do something like this...

    def __init__(self, parent):
    
        wx.Frame.__init__(self, parent, -1, "Test")
        self.SetSize((600,500))
    
        toolbar = wx.ToolBar(self, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
        toolbar.Realize()
    
        self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)
    
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(toolbar, 0, border=5)
        vbox.Add(self.control, 1, border=5)
    
        self.SetSizer(vbox)
    

    ...but it's probably better to use the Frame's CreateToolBar() method, then you don't have to worry about its layout...

    def __init__(self, parent):
    
        wx.Frame.__init__(self, parent, -1, "Test")
        self.SetSize((600,500))
    
        toolbar = self.CreateToolBar(style=wx.TB_HORIZONTAL | wx.NO_BORDER)
        toolbar.Realize()
    
        self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)
    
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.control, 1, border=5)
    
        self.SetSizer(vbox)
    

    ...indeed, if the TextCtrl is the only other thing in the frame, you don't even need the sizer...

    def __init__(self, parent):
    
        wx.Frame.__init__(self, parent, -1, "Test")
        self.SetSize((600,500))
    
        toolbar = self.CreateToolBar(style=wx.TB_HORIZONTAL | wx.NO_BORDER)
        toolbar.Realize()
    
        self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)