Why doesn't the frame display all grid columns completely?

Hi,

I had asked a similar question here, but this one is slightly different.
I have a frame and a grid on it. Although I use wx.EXPAND flag and SetSizerAndFit and Layout methods, the frame doesn’t display the grid columns completely. There appears a horizontal scroll bar on the grid, and user has to scroll to right to display all grid columns.

Why does the system behave this way at start up? How to solve it?

import wx
import wx.grid as grid_lib
import wx.lib.agw.flatnotebook as fnb


class TheFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "The Frame", #size=(600, 600),
                          style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
                          )

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        grid_sizer = self.create_grid()
        self.sizer.Add(grid_sizer, 1, wx.EXPAND)
        self.SetSizerAndFit(self.sizer)
        self.Layout()

    def create_grid(self):


        self.current_row = None
        grid_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.grid = grid_lib.Grid(self, -1, name="grid")
        self.grid.CreateGrid(0, 15)

        self.grid.DisableDragColSize()
        self.grid.DisableDragRowSize()
        self.grid.HideRowLabels()
        self.grid.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)

        col_labe_font = wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, faceName="Calibri")
        self.grid.SetLabelFont(col_labe_font)

        grid_sizer.Add(self.grid, 0, wx.EXPAND)

        for i in range(100):
            self.grid.AppendRows(1)
        self.grid.Refresh()
        grid_sizer.Layout()

        return grid_sizer


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

Hi Steve,

You specified wx.EXPAND flag to the horizontal grid_sizer, thus it expands vertically, but with proportion=0 the control does not fill the client area horizontally. First, you need to modify:

        grid_sizer.Add(self.grid, 1, wx.EXPAND)

See also: wx.Sizer — wxPython Phoenix 4.2.2 documentation

Then, follow the recipe in the previous post you mentioned above. Or, maybe better would be:

        grid_sizer.Fit(self)
        vsb_width = wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X)
        self.Size = (self.Size[0] + vsb_width,
                     self.Size[1])

Hi Komoto,

Thank you for your reply. Setting proportion=0 didn’t work. The frame still doesn’t display all grid columns completely.

Why do I have to tell the scroll bar width explicitly to the application in the start up? I’m using wx.EXPAND flag and proportion=1 parameter and self.Layout() method. It should have taken care of everything automatically by itself. I think this is a bug, @Robin for your information.

Hi Steve,

I don’t think it is a bug, just a design.
For example, suppose you have a small number of data rows, such as 10 or 20. Replace your code with:

        for i in range(10):
            self.grid.AppendRows(1)

Then, I guess the resulting layout would be what you expected.

If you replace it with range(1000) that is too large to show at once, the frame fits its height to the desktop and a vertical scrollbar will appear but the width of the frame won’t change. As a result, a horizontal scrollbar appears.

So, the width is not being automatically adjusted to not show the horizontal scrollbar, and it is not preferable for you, and if you think it’s a bug, then yes, it is a bug, in your code. :slightly_smiling_face:

1 Like

well @steve2, I think what @komoto48g said is quite plausible because every designer has to take a choice

if you don’t like that choice then, I’m afraid, you’ll have to find a way to implement your idea on top of that choice and, luckily, wxPython offers a lot to make your own ideas come true (I think :joy:)

import wx.grid as grid_lib

class TheFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "The Frame", #size=(600, 600),
                          style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX
                          )

        vbox = wx.BoxSizer(wx.VERTICAL)
        grid = self.create_grid(vbox)
        self.SetSizerAndFit(vbox)
        self.Show()

        cor = wx.SystemSettings.GetMetric(wx.SYS_VSCROLL_X)
        x, y = self.GetSize()
        self.SetSize(x + cor, y)
        x, y = grid.GetSize()
        grid.SetSize(x + cor, y)

    def create_grid(self, sizer):

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(hbox)

        grid = grid_lib.Grid(self, -1, name="grid")
        grid.CreateGrid(0, 15)
        grid.DisableDragColSize()
        grid.DisableDragRowSize()
        grid.HideRowLabels()
        grid.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
        col_labe_font = wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, faceName="Calibri")
        grid.SetLabelFont(col_labe_font)
        grid.AppendRows(100)

        hbox.Add(grid, 0, wx.EXPAND)
        return grid

app = wx.App(False)
TheFrame()
app.MainLoop()