添加/删除子窗口小部件时调整ScrolledPanel的大小时出现问题

时间:2014-08-07 19:05:08

标签: python wxpython wxwidgets

以下应用程序包含框架内的滚动面板。滚动面板包含一行按钮,用户可以向其添加/删除行。我遇到的问题有两个:

  1. 添加行会导致滚动面板消失。添加足够的行以超出周围帧的高度会导致行从帧中移出。
  2. 删除行不会调整周围滚动面板的大小
  3. 我已经查看了其他几个ScrolledPanel主题,但似乎找不到与此问题完全匹配的主题。

    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()    
    

1 个答案:

答案 0 :(得分:1)

我必须将wx.EXPAND添加到几个sizer中,然后添加和删除方法中的魔法......我个人选择滚动条始终显示,因为它现在的方式我不小心滚动条显示后单击删除按钮。此外,PySimpleApp已弃用,因此我将其更改为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()