Reputation: 241
The following application contains a scrolled panel within a frame. The scrolled panel contains a row of buttons to which a user can add/remove rows. The problem I'm running into is two-fold:
I've looked at several of the other ScrolledPanel topics but can't seem to find one that quite matches this issue.
import wx
from wx.combo import OwnerDrawnComboBox as ComboBox
from wx.lib.scrolledpanel import ScrolledPanel
class Choice(wx.Panel):
def __init__(self, parent, allow_delete=True):
wx.Panel.__init__(self, parent)
self.colChoice = ComboBox(self, choices=['a','b','c'], style=wx.CB_READONLY)
self.colChoice.Select(0)
if allow_delete:
self.minus_button = wx.Button(self, label='-', size=(30,-1))
self.minus_button.Bind(wx.EVT_BUTTON, lambda event: self.Parent.on_remove_choice(event,self))
self.plus_button = wx.Button(self, label='+', size=(30,-1))
self.plus_button.Bind(wx.EVT_BUTTON, lambda event: self.Parent.on_add_choice(event,self))
colSizer = wx.BoxSizer(wx.HORIZONTAL)
colSizer.Add(self.colChoice, 1, wx.EXPAND|wx.ALL,1)
colSizer.AddSpacer((5,-1))
colSizer.Add(self.plus_button, 0, wx.EXPAND|wx.ALL,1)
if allow_delete:
colSizer.AddSpacer((5,-1))
colSizer.Add(self.minus_button, 0, wx.EXPAND)
else:
colSizer.AddSpacer((5,-1))
colSizer.Add(wx.StaticText(self), 0,wx.EXPAND)
self.SetSizerAndFit(colSizer)
class ChoicePanel(ScrolledPanel):
def __init__(self,parent):
ScrolledPanel.__init__(self, parent, -1)
self.panel_sizer = wx.BoxSizer( wx.VERTICAL )
self.choices = []
c = Choice(self, False)
self.panel_sizer.Add(c, 0, wx.EXPAND)
self.choices.append(c)
self.SetSizer(self.panel_sizer)
self.SetAutoLayout(1)
self.SetupScrolling(False,True)
def on_add_choice(self,event,selected_filter):
self.choices.append(Choice(self, True))
self.panel_sizer.Add(self.choices[-1], 0, wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, 5)
self.SetupScrolling(False,True)
self.panel_sizer.SetMinSize(self.panel_sizer.GetMinSize())
self.SetSizerAndFit(self.panel_sizer)
self.SetAutoLayout(1)
self.Refresh()
self.Layout()
def on_remove_choice(self,event,selected_filter):
i = self.choices.index(selected_filter)
self.choices.remove(selected_filter)
self.panel_sizer.Remove(selected_filter)
selected_filter.Destroy()
self.SetupScrolling(False,len(self.choices) < 3 )
self.Refresh()
self.Layout()
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.test_panel = ChoicePanel(self)
self.sizer.Add(wx.StaticText(self, -1, "Some text here:"), 0, wx.CENTER|wx.ALL, 4)
self.sizer.AddSpacer((4,-1))
self.sizer.Add(self.test_panel, 1, wx.CENTER|wx.ALL, 4)
self.SetSizer(self.sizer)
self.Layout()
if __name__=='__main__':
app = wx.PySimpleApp()
f = TestFrame()
f.Show()
app.MainLoop()
Upvotes: 0
Views: 264
Reputation: 2170
I had to add wx.EXPAND to a few sizers, and then the magic in the add and remove methods... personally I'd opt for the scroll bars to always be shown, since the way it is now I accidentally clicked the remove button after the scroll bars show up. Also PySimpleApp is deprecated so I changed that to App:
import wx
from wx.combo import OwnerDrawnComboBox as ComboBox
from wx.lib.scrolledpanel import ScrolledPanel
class Choice(wx.Panel):
def __init__(self, parent, allow_delete=True):
wx.Panel.__init__(self, parent)
self.colChoice = ComboBox(self, choices=['a','b','c'], style=wx.CB_READONLY)
self.colChoice.Select(0)
if allow_delete:
self.minus_button = wx.Button(self, label='-', size=(30,-1))
self.minus_button.Bind(wx.EVT_BUTTON, lambda event: self.Parent.on_remove_choice(event,self))
self.plus_button = wx.Button(self, label='+', size=(30,-1))
self.plus_button.Bind(wx.EVT_BUTTON, lambda event: self.Parent.on_add_choice(event,self))
colSizer = wx.BoxSizer(wx.HORIZONTAL)
colSizer.Add(self.colChoice, 1, wx.EXPAND|wx.ALL,1)
colSizer.AddSpacer((5,-1))
colSizer.Add(self.plus_button, 0, wx.EXPAND|wx.ALL,1)
if allow_delete:
colSizer.AddSpacer((5,-1))
colSizer.Add(self.minus_button, 0, wx.EXPAND)
else:
colSizer.AddSpacer((5,-1))
colSizer.Add(wx.StaticText(self), 0,wx.EXPAND)
self.SetSizerAndFit(colSizer)
class ChoicePanel(ScrolledPanel):
def __init__(self,parent):
ScrolledPanel.__init__(self, parent, -1)
self.panel_sizer = wx.BoxSizer( wx.VERTICAL )
self.choices = []
c = Choice(self, False)
self.panel_sizer.Add(c, 0, wx.EXPAND)
self.choices.append(c)
self.SetSizer(self.panel_sizer)
self.SetAutoLayout(1)
self.SetupScrolling(False,True)
def on_add_choice(self,event,selected_filter):
self.choices.append(Choice(self, True))
self.panel_sizer.Add(self.choices[-1], 0, wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, 5)
self.panel_sizer.Layout()
self.Fit()
self.GetParent().Layout()
def on_remove_choice(self,event,selected_filter):
i = self.choices.index(selected_filter)
self.choices.remove(selected_filter)
self.panel_sizer.Remove(selected_filter)
selected_filter.Destroy()
self.panel_sizer.Layout()
self.Fit()
self.GetParent().Layout()
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
panel = wx.Panel(self, -1)
self.test_panel = ChoicePanel(panel)
self.sizer.Add(wx.StaticText(panel, -1, "Some text here:"), 1, wx.EXPAND|wx.CENTER|wx.ALL, 4)
self.sizer.AddSpacer((4,-1))
self.sizer.Add(self.test_panel, 1, wx.EXPAND|wx.CENTER|wx.ALL, 4)
panel.SetSizer(self.sizer)
panel.Layout()
if __name__=='__main__':
app = wx.App(False)
f = TestFrame()
f.Show()
app.MainLoop()
Upvotes: 1