2012-05-31 46 views
0

我有一個控制面板來控制wxPython框架中的matplotlib圖形的編輯。 wxPython安裝最近從2.6.4.0更新到2.8.12.1,並打破了一些東西,即滾動面板不再填充一個塊,而是停留在最小尺寸。我現在剛剛從一年前開始接受這件事,所以我有點生疏。任何幫助將非常感激!wxPython ScrolledWindow太小

下面是可以自行運行並顯示問題的精簡版代碼。 ScrolledWindow應該擴大到400px。當我運行它self.scroll.GetSize()返回(292, 257)但它顯然不是以該大小顯示。

# testing scroll panel for PlotEditFrame 

import wx 

# spoof the necessary matplotlib objects 
class FakePlot: 
    def __init__(self): 
     self.figure = FakeFigure() 
    def get_figure(self): 
     return self.figure 
class FakeFigure: 
    def __init__(self): 
     self.axes = [FakeAxis() for i in range(0,2)] 
class FakeAxis: 
    def __init__(self): 
     self.lines = [FakeLine(i) for i in range(0, 4)] 
class FakeLine: 
    def __init__(self,i): 
     self.label = "line #%s"%i 
    def get_label(self): 
     return self.label 

class PlotEditFrame(wx.Frame): 
    """ 
    This class holds the frame for plot editing tools 
    """ 

    def __init__(self, parent, plot): 
     """Constructor for PlotEditFrame""" 
     wx.Frame.__init__(self, parent, -1, "Edit Plot") 
     self.parent = parent 
     self.plot = plot 
     self.figure = plot.get_figure() 
     self.advanced_options = None 
     self.scroll = wx.ScrolledWindow(self, -1) 
     self.InitControls() 

    def InitControls(self): 
     """Create labels and controls based on the figure's attributes""" 

     # Get current axes labels 
     self.lineCtrls = [(wx.StaticText(self.scroll, -1, "Column:"), 
          wx.StaticText(self.scroll, -1, "Color:"), 
          wx.StaticText(self.scroll, -1, ""))] 

     for axis in self.figure.axes: 
      for line in axis.lines: 
       color = wx.Colour(255,0,0,0) 
       lineTxt = wx.TextCtrl(self.scroll, -1, line.get_label(), size=(175,-1)) 
       lineColor = wx.TextCtrl(self.scroll, -1, "#%02x%02x%02x"%color.Get()) 
       lineBtn = wx.Button(self.scroll, -1, size=(25,25)) 
       lineBtn.SetBackgroundColour(color) 
       self.lineCtrls.append((lineTxt, lineColor, lineBtn)) 

     # Place controls 
     boxSizer = wx.BoxSizer(wx.VERTICAL) 

     lineBox = wx.StaticBox(self, -1, "Lines") 
     lineBoxSizer = wx.StaticBoxSizer(lineBox, wx.VERTICAL) 
     lineSizer = wx.FlexGridSizer(rows=len(self.lineCtrls)+1, cols=4, vgap=3, hgap=3) 
     for ctrls in self.lineCtrls: 
      lineSizer.AddMany([(ctrls[0], 0, wx.ALIGN_LEFT | wx.EXPAND), 
           (ctrls[1], 0, wx.ALIGN_LEFT), 
           (ctrls[2], 0, wx.ALIGN_CENTER| wx.FIXED_MINSIZE), 
           ((3,3), 0, wx.ALIGN_CENTER)]) 
     lineSizer.AddGrowableCol(0) 

     # Set size 
     self.scroll.SetSizer(lineSizer) 
     width = self.scroll.GetBestSize().width 
     height = self.scroll.GetBestSize().height 
     if height > 400: 
      height = 400 
      width = width + 25 # button size 
     self.scroll.SetSize((width, height)) 
     self.scroll.SetScrollbars(0, 1, 1,1) 
     print "set scrollbars at %s x %s"%(width, height) 

     lineBoxSizer.Add(self.scroll, 0, wx.EXPAND) 

     boxSizer.AddMany([ (lineBoxSizer, 0, wx.EXPAND) ]) 

     self.SetSizer(boxSizer) 
     self.SetAutoLayout(1) 
     self.Fit() 

     height = self.GetSize().GetHeight() 
     self.SetSizeHints(minH=height, maxH=height, 
           minW=width, maxW=width*5) 

if __name__ == '__main__': 
    app = wx.PySimpleApp(0) 
    parent = wx.Frame(None, wx.ID_ANY, 'test', size=(300,300)) 
    plot = FakePlot() 
    panel = PlotEditFrame(parent, plot) 
    panel.Show() 
    app.MainLoop() 

我找不出需要調整大小的面板。有些事情我已經試過了,沒有用:

# These have no visible effect 
boxSizer.SetMinSize((width, height)) 
self.scroll.SetVirtualSize((width, height)) 
lineBoxSizer.Fit(self.scroll) 
lineBoxSizer.SetVirtualSizeHints(self.scroll) 

# This makes the window the right size, but not the scroll panel 
lineBoxSizer.SetMinSize((width, height)) 

回答

1

我編輯你的代碼一點得到它的工作:

import wx 

# spoof the necessary matplotlib objects 
class FakePlot: 
    def __init__(self): 
     self.figure = FakeFigure() 
    def get_figure(self): 
     return self.figure 
class FakeFigure: 
    def __init__(self): 
     self.axes = [FakeAxis() for i in range(0,2)] 
class FakeAxis: 
    def __init__(self): 
     self.lines = [FakeLine(i) for i in range(0, 4)] 
class FakeLine: 
    def __init__(self,i): 
     self.label = "line #%s"%i 
    def get_label(self): 
     return self.label 

class PlotEditFrame(wx.Frame): 
    """ 
    This class holds the frame for plot editing tools 
    """ 

    def __init__(self, parent, plot, size): 
     """Constructor for PlotEditFrame""" 
     wx.Frame.__init__(self, parent, -1, "Edit Plot", size=size) 
     self.parent = parent 
     self.plot = plot 
     self.figure = plot.get_figure() 
     self.advanced_options = None 
     self.scroll = wx.ScrolledWindow(self, -1) 
     self.InitControls() 

    def InitControls(self): 
     """Create labels and controls based on the figure's attributes""" 

     # Get current axes labels 
     self.lineCtrls = [(wx.StaticText(self.scroll, -1, "Column:"), 
          wx.StaticText(self.scroll, -1, "Color:"), 
          wx.StaticText(self.scroll, -1, ""))] 

     for axis in self.figure.axes: 
      for line in axis.lines: 
       color = wx.Colour(255,0,0,0) 
       lineTxt = wx.TextCtrl(self.scroll, -1, line.get_label(), size=(175,-1)) 
       lineColor = wx.TextCtrl(self.scroll, -1, "#%02x%02x%02x"%color.Get()) 
       lineBtn = wx.Button(self.scroll, -1, size=(25,25)) 
       lineBtn.SetBackgroundColour(color) 
       self.lineCtrls.append((lineTxt, lineColor, lineBtn)) 

     # Place controls 
     boxSizer = wx.BoxSizer(wx.VERTICAL) 

     lineBox = wx.StaticBox(self, -1, "Lines") 
     lineBoxSizer = wx.StaticBoxSizer(lineBox, wx.VERTICAL) 
     lineSizer = wx.FlexGridSizer(rows=len(self.lineCtrls)+1, cols=4, vgap=3, hgap=3) 
     for ctrls in self.lineCtrls: 
      lineSizer.AddMany([(ctrls[0], 0, wx.ALIGN_LEFT | wx.EXPAND), 
           (ctrls[1], 0, wx.ALIGN_LEFT), 
           (ctrls[2], 0, wx.ALIGN_CENTER| wx.FIXED_MINSIZE), 
           ((3,3), 0, wx.ALIGN_CENTER)]) 
     lineSizer.AddGrowableCol(0) 

     # Set size 
     self.scroll.SetSizer(lineSizer) 
     width = self.scroll.GetBestSize().width 
     height = self.scroll.GetBestSize().height 
     if height > 400: 
      height = 400 
      width = width + 25 # button size 
     self.scroll.SetSize((width, height)) 
     self.scroll.SetScrollbars(0, 1, 1,1) 
     print "set scrollbars at %s x %s"%(width, height) 

     lineBoxSizer.Add(self.scroll, 1, wx.EXPAND) 

     boxSizer.Add(lineBoxSizer, 1, wx.EXPAND) 

     self.SetSizer(boxSizer) 
     self.SetAutoLayout(1) 
     #self.Fit() 

     height = self.GetSize().GetHeight() 
     self.SetSizeHints(minH=height, maxH=height, 
           minW=width, maxW=width*5) 

if __name__ == '__main__': 
    app = wx.App(False) 
    plot = FakePlot() 
    frame = PlotEditFrame(None, plot, size=(300,300)) 
    frame.Show() 
    app.MainLoop() 

最主要的是規定的比例爲「1」以下兩行:

lineBoxSizer.Add(self.scroll, 1, wx.EXPAND)  
boxSizer.Add(lineBoxSizer, 1, wx.EXPAND) 

我改變了你啓動的程序,因爲它是一個有點傻把一幀的另一個幀裏面這種情況的方式。此外PySimpleApp已被棄用,所以我也改變了這一點。我幾乎從來沒有找到適用於「Fit()」方法的良好用法,所以我把它解決了,因爲它壓縮了最初的GUI太多。

希望有幫助!

+0

謝謝。這是一個更大的應用程序的一部分,這就是爲什麼它的設置,但你的提示讓我朝着正確的方向。我最終改變了比例,正如你所說的那樣,將最外面的sizer的最小值設置爲內部元素的最小值的總和(爲什麼這不是自動的,我不知道),並保持對'self.Fit( )'把所有的東西都放好。 – whrrgarbl

+0

我認爲問題在於調用Fit時widget的大小仍然非常小,所以它只是隨流而行。如果我們將Fit()調用放在wx.CallAfter()中,可能會有效,所以直到窗口顯示前才調用它。 –