I have an app in which I want to use one panel to hold images that I can drag and drop, and one that will hold various controls
I cannot make the image panel display correctly:
import wx
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1,
'Display panels',
size=(900, 700))
sizer = wx.GridBagSizer()
image_panel = ImagePanel(self)
sizer.Add(image_panel, pos=(1, 2))
#self.SetSizer(sizer)
self.Centre()
self.Show()
class ImagePanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.Bind(wx.EVT_PAINT, self.on_paint)
def on_paint(self, event):
dc = wx.PaintDC(self)
dc.Clear()
self.PrepareDC(dc)
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen(wx.BLACK, 4))
dc.DrawLine(0, 0, 500, 500)
if __name__ == '__main__':
screen_app = wx.App()
main_frame = MainFrame()
screen_app.MainLoop()
If the SetSizer line is commented out it works; if it's not commented, it just appears as a small box in top-left
Can anyone help please?
The key is to have a single panel that is the ONLY child widget of the frame. Then you add your other panels as children of that top-level panel.
Now, I prefer using wx.BoxSizer
over wx.GridBagSizer
, although I'm sure you could make it work. Anyway, for this example, I will use the BoxSizer:
import wx
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1,
'Display panels',
size=(900, 700))
main_panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
image_panel = ImagePanel(main_panel)
sizer.Add(image_panel, 1, wx.EXPAND|wx.ALL, 5)
# Add your control panel here
main_panel.SetSizer(sizer)
self.Centre()
self.Show()
class ImagePanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.Bind(wx.EVT_PAINT, self.on_paint)
def on_paint(self, event):
dc = wx.PaintDC(self)
dc.Clear()
self.PrepareDC(dc)
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen(wx.BLACK, 4))
dc.DrawLine(0, 0, 500, 500)
if __name__ == '__main__':
screen_app = wx.App()
main_frame = MainFrame()
screen_app.MainLoop()
As you can see, when we add the ImagePanel
to the sizer, I also pass in the proportion it should be, 1, which means that the ImagePanel should take up 100% of the space. I also pass the wx.EXPAND
flag which tells wxPython to expand that widget to fill the space.
You can do something similar with GridBagSizer, but you will need to make the widget cross cell boundaries, and frankly, I find it a bit of a pain. You are welcome to dig into the documentation though if you really want to use that sizer.