How to add sizers to a scrolledPanel?

Hi,
I’m trying to add a sizer to a scrolledPanel, but I don’t know how. BoxSizers have the Add method, which I can add widgets or other sizers, but ScrolledPanel don’t. So, how do I do it?

I’m trying to build something like this:
wx

I the loop of _organizeData , every time there is a new month, I want to add some buttons to a GridSizer, which is inside a vertical box with a text on the top. I can’t figure it out to add this vertical BoxSizer (vBox) to the scrollPanel . Here’s my code:

import wx

import wx.lib.scrolledpanel as scrolled

class GraphCalendar(wx.Frame):

    def __init__(self, parent, data):

        wx.Frame.__init__(self, parent)

        self.data = data

        self.consumption = []

        self.text = wx.StaticText(self, wx.ID_ANY, label="This is a test")

        self.scrollPanel = scrolled.ScrolledPanel(self, wx.ID_ANY, size=((400, 600)), style=wx.SUNKEN_BORDER)

        self.scrollPanel.SetupScrolling()

        self.topVerticalBox = wx.BoxSizer(wx.VERTICAL)

        self.topVerticalBox.Add(self.text, flag=wx.EXPAND)

        self.topVerticalBox.Add(self.scrollPanel)

        self.Center()

        self._organizeData()

    def _organizeData(self):

        currentMonth = ''

        for i in range(0, len(self.data)):

            words = self.data[i]['date'].split('-')  # words -> [0]day, [1]month and [2]year.

            if currentMonth != words[1]:

                currentMonth = words[1]

                vBox = wx.BoxSizer(wx.VERTICAL)

                # Name of the month / year.

                text = wx.StaticText(self, wx.ID_ANY, f"{(words[1])} of {words[2]}")

                # Grid where the button of the days will be added

                gridSizer = wx.GridSizer(rows=5, cols=5, hgap=5, vgap=5)

                vBox.Add(text, wx.ID_ANY)

                vBox.Add(gridSizer, wx.ID_ANY)

                self.scrollPanel.Add(vBox) # <-- Error here.

            # Create the button of the day and add it to the gridSizer.

            button = wx.Button(self, 1000 + i, label=words[0], size=((20, 20)))

            button.Bind(wx.EVT_BUTTON, self.OnButtonClicked)

            gridSizer.Add(button, border=5)

        self.SetSizerAndFit(self.topVerticalBox)

    def OnButtonClicked(self, event):

        event.GetEventObject()

        print(event.GetId())

app = wx.App()
frame = GraphCalendar(None, data=[{'date': '14-03-2021', 'xyValues': [['01:00', '02:00'], [18.5, 17.2]]}, {'date': '15-04-2021', 'xyValues': [['01:00', '02:00'], [19.5, 18.2]]}])
frame.Show()
app.MainLoop()

Thank you!

Create a sizer for the scrollPanel.

topsizer = wx.BoxSizer(wx.VERTICAL)
self.scrollPanel.SetSizer(topsizer)

Then add your sizers to this master sizer.

vBox = wx.BoxSizer(wx.VERTICAL)
...
topsizer.Add(vBox)
1 Like

Thanks so much @ioprst0904
That was it. :grinning_face_with_smiling_eyes:

That’s a “weird” way to add stuff to a scrolledPanel.

I see that you are using self (main frame) everywhere as the parent window for all widgets.
I think that you should use the panel scrolledPanel as the parent window for the widgets you want to place on it.

In my thinking, this way I would be putting the widgets individually. I wanted the major SizerBox that contains all of them (representing a month) to be there.