2011-05-06 41 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