[wxPython] wxNotebook inside a wxBoxSizer?

Hi guys,

Okay, I'm stumped. I'm trying to write an "Editor" class which builds input
screens from an XML template. After some mucking about I managed to get the
basic input screen layout working nicely -- but for the life of me I can't get
a wxNotebook to size itself correctly when the editor is first opened.

I'm using a wxNotebookSizer to size the notebook appropriately, and the
wxNotebook itself is inside a wxBoxSizer along with some other input-screen
elements. The thing is, the wxNotebook never seems to be sized correctly --
the bottom-most fields are partially hidden because the notebook is too small.

I'll paste some code below which shows up the problem. Initially, I suspected
I was using the wxBoxSizer in a strange way -- but if I replace the wxNotebook
with another panel everything works. It's only with the wxNotebook that the
wxBoxSizer seems to be getting the size wrong...

Anyway, here's the code:

···

=============================================================================
from wxPython.wx import *

class TestFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__(self, parent, id, title)

        sizer = wxBoxSizer(wxVERTICAL)

        notebook = wxNotebook(self, -1)

        notebook.AddPage(self.makePanel(notebook), "1")
        notebook.AddPage(self.makePanel(notebook), "2")
        notebook.AddPage(self.makePanel(notebook), "3")

        nbSizer = wxNotebookSizer(notebook)

        sizer.Add(nbSizer, 1, wxGROW)

        sizer.Add(self.makePanel(self), 1, wxGROW)

        self.SetSizer(sizer)
        self.SetAutoLayout(TRUE)
        sizer.Fit(self)

    def makePanel(self, parent):
        panel = wxPanel(parent, -1)
        sizer = wxFlexGridSizer(0, 2, 2, 2)

        label1 = wxStaticText(panel, -1, "Field 1")
        sizer.Add(label1, -1, wxALIGN_RIGHT)

        field1 = wxTextCtrl(panel, -1, "Value 1")
        sizer.Add(field1, -1, wxALIGN_LEFT)

        label2 = wxStaticText(panel, -1, "Field 2")
        sizer.Add(label2, -1, wxALIGN_RIGHT)

        field2 = wxTextCtrl(panel, -1, "Value 2")
        sizer.Add(field2, -1, wxALIGN_LEFT)

        panel.SetSizer(sizer)
        panel.SetAutoLayout(true)
        sizer.Fit(panel)

        return panel

class TestApp(wxApp):
    def OnInit(self):
       frame = TestFrame(NULL, -1, "Test")
       self.SetTopWindow(frame)
       frame.Show(TRUE)
       return TRUE

app = TestApp(0)
app.MainLoop()

Any suggestions?

Thanks,

- Erik.

I'm using a wxNotebookSizer to size the notebook appropriately, and the
wxNotebook itself is inside a wxBoxSizer along with some other

input-screen

elements. The thing is, the wxNotebook never seems to be sized

correctly --

the bottom-most fields are partially hidden because the notebook is too

small.

What platform? It looks okay to me on Win2k, a bit cramped but okay. The
problem is that the CalcMin method of the wxNotebookSizer seems to be a bit
of an unfinished hack. Here's how it starts:

wxSize wxNotebookSizer::CalcMin()
{
    // This will have to be done platform by platform
    // as there is no way to guess the thickness of
    // the wxNotebook tabs and border.

    int borderX = 5;
    int borderY = 5;
    if ((m_notebook->HasFlag(wxNB_RIGHT)) ||
        (m_notebook->HasFlag(wxNB_LEFT)))
    {
        borderX += 90; // improvements later..
    }
    else
    {
        borderY += 40; // improvements later..
    }
...

See what I mean? There's a lot of stuff like different fonts, etc. that
could throw it off. You might want to submit a bug report about it (with
your sample code and maybe a screen shot too) so whomever did this will get
the reminder that they need to go back and do something about it.

In the meantime I'd suggest adding a bit of extra space to the sizers used
on your notebook pages as a buffer. You can either give the bottom items a
bottom border, or just add an extra item to the sizer with a width and
height (but no window or sizer) like this:

    sizer.Add(10, 25)

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

Hi Robin,

> I'm using a wxNotebookSizer to size the notebook appropriately, and the
> wxNotebook itself is inside a wxBoxSizer along with some other
input-screen
> elements. The thing is, the wxNotebook never seems to be sized
correctly --
> the bottom-most fields are partially hidden because the notebook is too
small.

What platform?

Sorry, I should have mentioned that. I'm running on Linux...

It looks okay to me on Win2k, a bit cramped but okay.

Well, here's a snapshot of what the window looks like running under Linux:

  http://www.wave.co.nz/~kiwicorp/wxpython/wxNotebookSizerBug.jpg

As you can see, it's very cramped...and it gets worse if you have more than
just two fields one above the other. In my actual program, the bottom line of
the input form is completely hidden...

The problem is that the CalcMin method of the wxNotebookSizer seems to be a
bit of an unfinished hack. Here's how it starts:

wxSize wxNotebookSizer::CalcMin()
{
    // This will have to be done platform by platform
    // as there is no way to guess the thickness of
    // the wxNotebook tabs and border.

    int borderX = 5;
    int borderY = 5;
    if ((m_notebook->HasFlag(wxNB_RIGHT)) ||
        (m_notebook->HasFlag(wxNB_LEFT)))
    {
        borderX += 90; // improvements later..
    }
    else
    {
        borderY += 40; // improvements later..
    }
...

See what I mean? There's a lot of stuff like different fonts, etc. that
could throw it off. You might want to submit a bug report about it (with
your sample code and maybe a screen shot too) so whomever did this will get
the reminder that they need to go back and do something about it.

Ahh, that makes sense. Okay, I'll submit a bug report...

In the meantime I'd suggest adding a bit of extra space to the sizers used
on your notebook pages as a buffer. You can either give the bottom items a
bottom border, or just add an extra item to the sizer with a width and
height (but no window or sizer) like this:

    sizer.Add(10, 25)

Yup, that's a good workaround for now.

Thanks!

- Erik.