Wxpython scrolled Panel Doesn't update scrollbars

I use winxp and wxpython (wxpython 3.1, python 2.6) to make a GUI program that will copy text from TextCtrl into a ScrollablePanel that contains a StaticText. All this works great, however, the scrollable part does not work correctly. It looks like it will not be updated in real time. When I moisten the window and enlarge it again, the scroll bar is updated. However, if I start typing text in TextCtrl again (thereby adding text to the StaticText inside the ScrollablePanel using the event), the scrollbar on the panel will not be updated unless I hide again and so on.

So the question is, how can I update the ScrolledPanel in real time? I have an event setting that is waiting for text to change in TextCtrl, where I think the update should go. I tried updating, updating, and layout, but they didn't seem to do much. The big question is: what minimizes the window and maximizes it again, what not, update, update and layout? Thank you for helping with this. Sorry, I can’t send the code confidential. I would be grateful for any help you could give me. Usually I can find the problems on my own, but I just did not find any documentation on this. This is the first time for me, but I get a lot of help from your answers. Thanks again!:)

Added:

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

This is usually what happens without paying too much attention to the purpose of the program. I tweak the virtual size thinking so that the size of the panel is larger than the area it fills, hoping that it will have constant scrollbars, but it is not.

+4
source share
1 answer

It would be better if you publish something that you can run right after copying and pasting.

Anyway, it looks like you have skipped the following actions, which are required for the scroll to work:

  • The scroll bar should have a sizer. This can be done using the self.test_panel.SetSizer(self.a_sizer) method. All other controls inside the panel should be attached to this sizer.

  • You should call the SetupScrolling () method on your panel, for example. self.test_panel.SetupScrolling()

  • You must enable automatic panel layout, for example. self.test_panel.SetAutoLayout(1)

PS Have you ever seen wxPython code examples? I ask because almost all of them have a wonderful method like __do_layout or something like that. This approach will help make your code more readable.

EDIT:

You need to add the self.test_panel.FitInside () method to TextChange to make the panel recount the sizes of the child controls and update its own virtual size.

Here is the complete solution:

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

All Articles