wxPython wx.grid.Grid is not loading fully with scrollbars

212 Views Asked by At

Issue

I created an wx application with 1 Frame. The Frame will have menubar, which has open menu option.

When open is clicked, a Wx.grid.Grid must be created in the frame with given rows, columns.

I have been trying hard, but scrollbars are not appearing by default.

I referred to this: https://stackoverflow.com/a/54753248/11658861

Actual Look

Scroll bars are not present which ideally must come automatically.

Post minimize and maximize Look

If I minimize and maximize frame once, then scrollbars are appearing!

Kindly someone please help! I need a solution, which creates proper grid with scrollbars, in same application flow.

Windows V20H2, Python 3.10.7, WxPython 4.2.0

Code (feel free to copy paste this into a Python IDE and test!):

import wx
import wx.grid


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="A Simple Grid")

        menubar = wx.MenuBar()
        file_menu = wx.Menu()
        menubar.Append(file_menu, "File")
        open_item = wx.MenuItem(file_menu, wx.ID_OPEN, '&Open\tCtrl+O')
        file_menu.Append(open_item)
        self.Bind(wx.EVT_MENU, self.callForm2, open_item)
        self.SetMenuBar(menubar)
        self.Maximize()

    def callForm2(self, event):
        panel = wx.Panel(self)
        myGrid = MyGrid(panel)
        myGrid.fillGrid()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(myGrid, 1, wx.EXPAND)
        panel.SetSizerAndFit(sizer)


class MyGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, style=wx.HSCROLL | wx.VSCROLL)

    def fillGrid(self):
        self.CreateGrid(100, 5)

        self.SetColLabelValue(0, "Column1")
        self.SetColLabelValue(1, "Column2")
        self.SetColLabelValue(2, "Column3")
        self.SetColLabelValue(3, "Column4")
        self.SetColLabelValue(4, "Column5")

        self.SetDefaultColSize(width=350, resizeExistingCols=True)
        self.SetDefaultRowSize(height=30, resizeExistingRows=True)


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Summary

How to properly create a wx.grid.Grid with scrollbars in parent window, when an action is triggered from a child window?

Thanks in advance!

1

There are 1 best solutions below

0
Rolf of Saxony On BEST ANSWER

You'll need to use Layout() and Refresh(), at least on Linux, after you have set the sizer.

Note that the scrollbars will only show if needed, so I've added a 6th column, so the horizontal scrollbar shows too.

import wx
import wx.grid


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="A Simple Grid")

        menubar = wx.MenuBar()
        file_menu = wx.Menu()
        menubar.Append(file_menu, "File")
        open_item = wx.MenuItem(file_menu, wx.ID_OPEN, '&Open\tCtrl+O')
        quit_item = wx.MenuItem(file_menu, wx.ID_EXIT, '&Quit\tCtrl+Q')
        file_menu.Append(open_item)
        file_menu.Append(quit_item)
        self.Bind(wx.EVT_MENU, self.callForm2, open_item)
        self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
        self.SetMenuBar(menubar)
        self.Maximize()

    def callForm2(self, event):
        panel = wx.Panel(self)
        myGrid = MyGrid(panel)
        myGrid.fillGrid()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(myGrid, 1, wx.EXPAND, 0)
        panel.SetSizerAndFit(sizer)
        self.Layout()
        self.Refresh()

    def OnExit(self, event):
        self.Destroy()

class MyGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, style=wx.HSCROLL | wx.VSCROLL)

    def fillGrid(self):
        self.CreateGrid(100, 6)

        self.SetColLabelValue(0, "Column1")
        self.SetColLabelValue(1, "Column2")
        self.SetColLabelValue(2, "Column3")
        self.SetColLabelValue(3, "Column4")
        self.SetColLabelValue(4, "Column5")
        self.SetColLabelValue(5, "Column6")
        self.SetDefaultColSize(width=350, resizeExistingCols=True)
        self.SetDefaultRowSize(height=30, resizeExistingRows=True)

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()