Search code examples
user-interfacewxpython

How to get the size of the wxpython panel


I'm developing a calendar application The top level window is a frame containing a panel that displays the calendar grid and a panel that contains a "Close" button. I'm unable to obtain the size of the calendar grid panel. When I add code to get the panel size, the result is (20,20), which cannot be correct The screen size is (1920,1080) so I'm expecting something like (1920, 1000) When I add the wx.lib.inspection module, I see the correct size being displayed. It is (1920, 968)

Can anyone shed some light how to get the correct size of the panel?

This is the code I have so far

import wx
     
class DrawFrame(wx.Frame):
  def __init__(self):
    wx.Frame.__init__(self, parent=None, title='Agenda', style= wx.CAPTION | wx.CLOSE_BOX)
    self.drawpanel = DrawPanel(self)
    self.buttonpanel = ButtonPanel(self)
    self.framesizer = wx.BoxSizer(wx.VERTICAL)
    self.framesizer.Add(self.drawpanel,1, flag=wx.EXPAND)

    # Add an empty space 10 pixels high above and below the button panel
    self.framesizer.Add((0,10),0)
    self.framesizer.Add(self.buttonpanel,0, flag=wx.EXPAND)
    self.framesizer.Add((0,10),0)
    self.SetSizer(self.framesizer)
    self.SetInitialSize()
    self.Maximize()
    self.Show()


  def GetPanelSize(self):
    return self.drawpanel.GetSize()


  def OnClose(self, event):
    self.Close()


class DrawPanel(wx.Panel):
  # This panel's parent is DrawFrame. DrawFrame is the top level window.
  def __init__(self, parent):
    wx.Panel.__init__(self, parent=parent)
    self.parent = parent
    self.Bind(wx.EVT_PAINT, self.OnPaint)
    self.x1, self.y1, self.x2, self.y2 = wx.GetClientDisplayRect()
    b = self.x1, self.y1, self.x2, self.y2 
    print b
    self.width, self.height = wx.GetDisplaySize()
    c = self.width, self.height
    print c

    
  def OnPaint(self, event=None):
    dc = wx.PaintDC(self)
    dc.Clear()
    dc.SetPen(wx.Pen(wx.BLACK, 2))
    dc.SetBrush(wx.Brush('WHITE'))

    """
    DrawRectangle (self, x, y, width, height)
    Draw a rectangle with the given corner coordinate and size.
    x and y specify the top left corner coordinates and both width and height are positive.
    """

    dc.DrawRectangle(self.x1 + 5, self.y1, self.x2 - 10, self.y2 - 60)
    dc.DrawLine(40, 100, 600, 100)


class ButtonPanel(wx.Panel):
  # This panel's parent is DrawFrame. DrawFrame is the top level window.
  def __init__(self, parent):
    wx.Panel.__init__(self, parent=parent)
    self.parent=parent
    self.buttonpanelsizer = wx.BoxSizer(wx.HORIZONTAL)
    self.closebutton = wx.Button(self, label = 'Close')
    self.Bind(wx.EVT_BUTTON, self.OnClose, self.closebutton)
    self.buttonpanelsizer.AddStretchSpacer(prop=1)
    self.buttonpanelsizer.Add(self.closebutton, 0, wx.ALIGN_CENTER)
    self.SetSizer(self.buttonpanelsizer)


  def OnClose(self, event):
    self.parent.OnClose(event)


app = wx.App(False)
frame = DrawFrame()
print frame.GetPanelSize()
app.MainLoop()

Much appreciated, Thanks


Solution

  • You are calling the GetPanelSize too early. Keep in mind that wxPython (and pretty much any GUI framework) is event based. That means that for it to work it must keep processing events, which in case of wxPython means that app.MainLoop() must run. So do not call GetPanelSize before calling app.MainLoop(). Instead, call it when you need it. Do you need it when you paint something? Just use dc.GetSize(). Do you need it elsewhere? Process the wx.EVT_SIZE event and store the current size. Possibly you will have to trigger some action in the EVT_SIZE handler.