【问题标题】:wxpython scrolled Panel Not Updating scroll barswxpython滚动面板不更新滚动条
【发布时间】:2011-08-20 05:51:29
【问题描述】:

我正在使用 winxp 和 wxpython ( wxpython 3.1, python 2.6 ) 制作一个 GUI 程序,它将文本从 TextCtrl 复制到包含 StaticText 的 ScrollablePanel 中。这一切都很好,但是,滚动部分不能很好地工作。好像不会实时更新。当我 ummaximize 窗口并再次最大化它时,滚动条会更新。但是,如果我再次开始在 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()    

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

【问题讨论】:

  • 我认为您的代码的相关部分可能在这里。它将帮助您获得更好的答案。我在这方面的知识不多,但我猜这是一个非常具体的问题,可能是 your 程序中的一个错误,所以,如果不看你是什么就很难猜出问题做。
  • 感谢您的回复,我可以在上面添加内容
  • 另外忘了说我用的是windows XP os
  • 没问题!祝你在这个问题上好运!还有一件事,每当您使用评论系统时,我建议您使用@Isaac 或在这种情况下使用@Trufa,以便通知用户。
  • 很高兴你能解决你的问题!欢迎来到 StackOverflow。

标签: python wxpython scrolledwindow


【解决方案1】:

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

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

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

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

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

附:你见过 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()    

【讨论】:

  • 1.我确实为框架设置了 sizer,只是没有列出代码。我以为是给的。我看不是这样。我已将其添加到上面的代码中。 2.我尝试调用SetupScrolling,但它没有做太多。我还假设设置滚动速率等会启用滚动。不是这样吗?无论哪种方式,我都已将其更改为使用 SetupScrolling,但问题仍然存在 3. 我确实有这个,请参阅新代码 P.S.显然我看过 wxpython 示例,否则我不知道它是如何工作的,我发现你的评论缺乏洞察力。
  • @Isaac 您的代码的问题是您没有“通知”面板其子控件的大小已更改,但是所有控件的大小都会在调整大小时自动重新计算,这就是为什么调整窗口大小时正在工作。要让您的代码正常工作,只需将 self.test_panel.FitInside() 添加到 TextChanged 方法。此外,我对您的代码进行了一些清理。查看更新的答案。
  • 谢谢,这行得通。这个 Fit 功能是我不知道的内部工作原理。谢谢你教我一些新东西。
  • 致所有也在寻找答案的人 - 请参阅 Vader 的评论,而不是冗长的答案。我只需要 FitInside() 命令。我不需要两个尺码器。
猜你喜欢
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 2014-11-08
  • 2017-03-31
  • 2014-02-18
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多