wxpython滚动面板不更新滚动条

时间:2011-05-06 14:21:10

标签: python wxpython scrolledwindow

我正在使用winxp和wxpython(wxpython 3.1,python 2.6)创建一个GUI程序,它将文本从TextCtrl复制到包含StaticText的ScrollablePanel。这一切都很好,但是,滚动部分不能正常工作。它似乎不会实时更新。当我最大化窗口并再次最大化时,滚动条会更新。但是,如果我再次开始键入TextCtrl(从而使用事件将文本添加到ScrollablePanel内的StaticText),面板上的滚动条不会更新,除非我再次最小化,依此类推。

所以问题是,如何实时更新ScrolledPanel?我有一个事件设置等待文本在TextCtrl中更改,这是我认为更新需要去的地方。我已经尝试过更新,刷新和布局,但它们似乎没有做太多。更大的问题是,最小化窗口并使其再次最大化,更新,刷新和布局不会这样做?谢谢你的帮助。对不起,我无法发布代码,保密。我很感激你能给我的任何帮助。我通常可以通过搜索自己发现问题,但我还没有找到任何关于此类事情的文档。这是我的第一次,但我从你的答案中得到了很多帮助。再次感谢! :)

添加了:

import wx
import wx.lib.inspection
from wx.lib.scrolledpanel import ScrolledPanel

class MyFrame( wx.Frame ):

    # TODO: add all class variables here for convention
    tin         = None

    hsizer      = None

    def __init__( self, parent, ID, title ):
        wx.Frame.__init__( self, parent, ID, title,
                     wx.DefaultPosition, wx.Size( 200, 150 ) )

        self.InitWidgets()
        self.InitBindings()
        self.InitFinish()


    def InitWidgets( self ):
        self.hsizer = wx.BoxSizer( wx.HORIZONTAL )

        # Add the TextCtrl
        vsizer = wx.BoxSizer( wx.VERTICAL )
        self.tin = wx.TextCtrl( self, style=wx.TE_MULTILINE )
        vsizer.Add( self.tin, 1, wx.EXPAND  )
        self.hsizer.Add( vsizer, 3, wx.TOP|wx.LEFT|wx.BOTTOM|wx.EXPAND, border=20 )

        # Add ScrolledPanel widget
        self.hsizer.Add( wx.Size( 200, -1 ), 1 )
        vsizer2 = wx.BoxSizer( wx.VERTICAL )
        self.test_panel = ScrolledPanel( self )
        self.test_panel.SetupScrolling()

        # Setup static text ( label ) tvs is the 
        # vertical sizer inside the panel
        self.tvs = wx.BoxSizer( wx.VERTICAL )
        self.tin2 = wx.StaticText( self.test_panel )
        self.tvs.Add( self.tin2, 0, wx.EXPAND )
        vsizer2.Add( self.test_panel, 1, wx.EXPAND  )
        self.hsizer.Add( vsizer2, 3, wx.TOP|wx.LEFT|wx.BOTTOM|wx.EXPAND, border=20 )

        # Add Spacer
        self.hsizer.Add( wx.Size( 500, -1 ), 1 ) 

    def InitBindings( self ):
        self.tin.Bind( wx.EVT_TEXT, self.TextChange ) 

    def InitFinish( self ):

        # Setup sizers and frame
        self.SetAutoLayout( True )
        self.test_panel.SetAutoLayout( True )
        self.test_panel.SetSizer( self.tvs )
        self.SetSizer( self.hsizer )
        self.Layout()
        self.Update()
        self.Maximize()

    def TextChange( self, event ):

        #self.CopyValues()
        self.tin2.Label = self.tin.GetValue()
        self.Layout()
        self.Update()
        self.test_panel.Refresh()
        self.test_panel.Update()
        print self.tin.GetValue().split( "\n" )


class MyApp( wx.App ):

    fr = None

    def OnInit( self ):
        self.fr = MyFrame( None, -1, "TitleX" )
        self.fr.Show( True )
        self.SetTopWindow( self.fr )
        return True

app = MyApp( 0 )
app.MainLoop()

def main():

    win = 1
if ( __name__ == "__main__" ):
    main()    

一般来说,这是正在发生的事情,而没有给出该计划的太多目的。我设置虚拟大小思维会使面板的大小大于它所填充的区域,希望它有永久滚动条,但事实并非如此。

1 个答案:

答案 0 :(得分:7)

如果您在复制和粘贴后发布可能正在运行的内容会更好。

无论如何,您似乎错过了以下必须使滚动面板工作的内容:

  1. 滚动面板必须有sizer。这可以通过self.test_panel.SetSizer(self.a_sizer)方法完成。面板内的所有其他控件必须连接到此大小调整器。

  2. 您必须在面板上调用SetupScrolling()方法,例如self.test_panel.SetupScrolling()

  3. 您必须为面板启用自动布局,例如self.test_panel.SetAutoLayout(1)

  4. P.S。你见过wxPython代码的例子吗?我问,因为几乎所有人都有像__do_layout这样的精彩方法。这种方法有助于使您的代码更具可读性。

    修改

    您需要将self.test_panel.FitInside()添加到TextChange方法,以强制面板重新计算子控件的大小并更新其自己的虚拟大小。

    这是完整的解决方案:

    import wx
    from wx.lib.scrolledpanel import ScrolledPanel
    
    class MyFrame( wx.Frame ):
        def __init__( self, parent, ID, title ):
            wx.Frame.__init__( self, parent, ID, title,
                             wx.DefaultPosition, wx.Size( 600, 400 ) )
            #Controls
            self.tin = wx.TextCtrl( self, 
                                    size = wx.Size( 600, 400 ),
                                    style=wx.TE_MULTILINE )        
            self.test_panel = ScrolledPanel( self, 
                                             size = wx.Size( 600, 400 ) )
            self.test_panel.SetupScrolling()
            self.tin2 = wx.StaticText( self.test_panel )
    
            #Layout
            #-- Scrolled Window
            self.panel_sizer = wx.BoxSizer( wx.HORIZONTAL )
            self.panel_sizer.Add( self.tin2, 0, wx.EXPAND )
            self.test_panel.SetSizer( self.panel_sizer )
            self.panel_sizer.Fit(self.test_panel)
            #-- Main Frame
            self.inner_sizer = wx.BoxSizer( wx.HORIZONTAL )        
            self.inner_sizer.Add( self.tin, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 50  )
            self.inner_sizer.Add( self.test_panel, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 50  )
    
            self.sizer = wx.BoxSizer( wx.VERTICAL )
            self.sizer.Add(self.inner_sizer, 1, wx.ALL | wx.EXPAND, 20)        
            self.SetSizer(self.sizer)
            self.sizer.Fit(self)
            self.sizer.Layout()
    
            self.test_panel.SetAutoLayout(1)
    
            #Bind Events
            self.tin.Bind( wx.EVT_TEXT, self.TextChange )
    
        def TextChange( self, event ):
            self.tin2.SetLabel(self.tin.GetValue())
            self.test_panel.FitInside()
    
    
    class MyApp( wx.App ):
        def OnInit( self ):
            self.fr = MyFrame( None, -1, "TitleX" )
            self.fr.Show( True )
            self.SetTopWindow( self.fr )
            return True
    
    app = MyApp( 0 )
    app.MainLoop()
    
    def main():
    
        win = 1
    
    if ( __name__ == "__main__" ):
        main()