2011-05-06 71 views
4

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

所以问题是,我怎样才能实时更新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

我觉得你的代码的相关部分可能是发生在这里。它会帮助你得到更好的答案。我在这方面没有太多知识,但我猜这是一个非常具体的问题,可能是**你的**程序中的一个错误,所以,很难在没有看到你在做什么的情况下猜测问题。 – Trufa 2011-05-06 14:53:34

+0

感谢您的回复,添加了我以上的可能 – Isaac 2011-05-06 15:16:18

+0

也忘记提及我正在使用Windows XP操作系统 – Isaac 2011-05-06 15:25:02

回答

7

如果您发布的东西可以在复制和粘贴后立即运行,那会更好。

反正看来你错过了以下事情是必须做滚动面板厂:

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

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

  3. 您必须为面板启用自动布局,例如,

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

1.我确实为框架设置了sizer,我只是没有列出代码。我认为它是给出的。我明白那不是。我已经将它添加到上面的代码中。 2.我尝试调用SetupScrolling,但没有做太多。我也是在假定设置滚动速率的情况下运行的,并且这样可以实现滚动。这不是这种情况吗?无论哪种方式,我已经改变它使用SetupScrolling和问题仍然存在3.我确实有这看到新的代码 P.S.很明显,我看过wxpython的例子,或者我不知道它是如何工作的,我发现你的评论缺乏洞察力。 – Isaac 2011-05-06 16:46:37

+1

@Isaac你的代码的问题是你没有“通知”面板,其子控件的大小已经改变,但所有控件的大小在调整大小时会自动重新计算,这就是为什么当你调整窗口大小时一切正常。为了让你的代码有效,只需将self.test_panel.FitInside()添加到TextChanged方法。另外我已经做了一些清理你的代码。查看更新的答案。 – Vader 2011-05-06 20:18:35

+0

谢谢,这个工程。这个Fit功能是我不知道的内部工作原理。谢谢你教我新东西。 – Isaac 2011-05-06 21:05:18