wxpython滚动面板不更新滚动条 [英] wxpython scrolled Panel Not Updating scroll bars

查看:25
本文介绍了wxpython滚动面板不更新滚动条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 winxp 和 wxpython(wxpython 3.1,python 2.6)制作一个 GUI 程序,该程序将文本从 TextCtrl 复制到包含 StaticText 的 ScrollablePanel.这一切正常,但是,Scrolled 部分工作不太正常.好像不会实时更新.当我将窗口最大化并再次最大化时,滚动条会更新.但是,如果我再次开始在 TextCtrl 中输入(从而使用事件将文本添加到 ScrollablePanel 内的 StaticText )面板上的滚动条不会更新,除非我再次最小化等等.

I'm using winxp and wxpython ( wxpython 3.1, python 2.6 ) to make a GUI program which will copy the text from a TextCtrl, into a ScrollablePanel that contains a StaticText. This all works fine, however, the Scrolled part doesn't work quite right. It seems like it won't update in real time. When I ummaximize the window and maximize it again, the scroll bar updates. However, if I start typing in the TextCtrl again ( Thereby adding text to the StaticText inside the ScrollablePanel using an event ) the scrollbar on the panel doesn't update unless I minimize again and so on.

那么问题来了,我怎样才能实时更新 ScrolledPanel?我有一个事件设置等待 TextCtrl 中的文本更改,我认为这是更新需要进行的地方.我已经尝试过更新、刷新和布局,但它们似乎没什么用.更大的问题是,最小化窗口和再次最大化它会做什么而更新、刷新和布局没有?谢谢你在这方面的帮助.抱歉,我不能发布代码,保密.我很感激你能给我的任何帮助.我通常可以通过搜索自己找到问题,但我还没有找到任何关于这种事情的文档.这对我来说是第一次,但我从你的回答中得到了很多帮助.再次感谢!:)

So the question is, how can I update the ScrolledPanel in real time? I have an event setup waiting for the text to change in the TextCtrl, which is where I think the update would need to go. I've tried Update, Refresh, and Layout but they didn't seem to do much. The bigger question is, what does minimizing the window and maximixing it again do that Update, Refresh and Layout do not? Thanks for you help in this. Sorry I can't post code, confidential. I would appreciate any help you could give me. I can normally find problems out on my own by searching but I just haven't found any documentation about this kind of thing. This is the first time for me, but I get a lot of help from your answers. Thanks again! :)

添加:

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

一般来说,这是在没有给出太多程序目的的情况下发生的.我设置了虚拟尺寸,认为会使面板的尺寸大于它填充的区域,希望它有永久滚动条,但事实并非如此.

Generally, This is what is going on without giving too much of the purpose of the program. I setup the virtual size thinking that would make the size of the panel bigger than the area it was filling, hoping it would have permanent scroll bars but its not the case.

推荐答案

如果您发布一些可以在复制和粘贴后立即运行的内容会更好.

It would be better if you'll post something that could be running right after copy and paste.

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

Anyway it appears that you missed the following things that are mandatory to make scrolled panel works:

  1. 滚动面板必须有一个sizer.这可以通过 self.test_panel.SetSizer(self.a_sizer) 方法来完成.面板内的所有其他控件都必须附加到此 sizer.

  1. Scrolled panel must have a sizer. This could be done via self.test_panel.SetSizer(self.a_sizer) method. All other controls inside the panel must be attached to this sizer.

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

You must call SetupScrolling() method on your panel, e.g. self.test_panel.SetupScrolling()

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

You must enable auto layout for the panel, e.g. self.test_panel.SetAutoLayout(1)

附言你见过 wxPython 代码的例子吗?我问是因为几乎所有人都有像 __do_layout 之类的好方法.这种方法将有助于使您的代码更具可读性.

P.S. Have you ever seen an examples of the wxPython code? I'm asking since almost all of them have wonderful method like __do_layout or something like that. This approach will help to make your code much more readable.

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

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

这是完整的解决方案:

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

这篇关于wxpython滚动面板不更新滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆