2013-04-08 55 views
3

創建一個自定義wx.frame以包含內部具有兩個網格控件的分離器窗口。它用於比較每個網格中的數據。此時兩個網格的滾動條需要支持同步滾動。如何同步wx中兩個網格的滾動條

問題:

  1. 如何獲得這兩個網格的滾動事件?我試圖在框架中裝入wx.EVT_SCROLL事件,但失敗了。我也嘗試綁定自定義網格控件中的滾動事件,但它也失敗了。
  2. 如何同步滾動兩個網格的滾動條?一個相對question的回答使用gridInstance.Scroll(row,col)來滾動網格客戶端窗口。但它不包含如何同步滾動條。

非常感謝您的任何建議。

定製幀

def __init__(self, parent): 
     wx.Frame.__init__(self, parent, -1, title='', size=(640,480)) 
     main_panel = wx.Panel(self, -1) 
     self.TBFLAGS = (wx.TB_HORIZONTAL| wx.NO_BORDER| wx.TB_FLAT) 
     self.controller = None 
     self.isSyncScroll = True 

     #hsizer = wx.BoxSizer(wx.VERTICAL) 
     gsizer = wx.FlexGridSizer(rows = 1, 
                cols = 1, 
                vgap = 2, 
                hgap = 2) 
     gsizer.AddGrowableRow(0) 
     gsizer.AddGrowableCol(0) 
     self.tb = self.init_toolbar() 
     (sub_panel0, sub_panel1) = self.init_splitter(main_panel) 
     self.grid0 = self.init_grid(sub_panel0) 
     self.grid1 = self.init_grid(sub_panel1) 
     self.init_status_bar() 

     gsizer.Add(main_panel, 1, wx.EXPAND) 
     self.SetSizer(gsizer) 

     ico = wx.Icon(u'Compare.ico', wx.BITMAP_TYPE_ICO) 
     self.SetIcon(ico) 
     self.Maximize() 

     #can't catch the scroll event at the frame 
     self.Bind(wx.EVT_SCROLL, self.OnScroll, self.grid0) 
     #self.Bind(wx.EVT_SCROLL, self.OnScroll) 
     #self.Bind(wx.EVT_SCROLL, self.OnScroll, id=self.grid0.GetId()) 
+0

爲什麼不把所有的數據並排放在同一個網格中? – Arthur 2013-04-08 09:16:53

+0

客戶是什麼......所以,它必須。數據列將會像winmerge一樣比較,並添加虛擬列來匹配相等的列。 – Erxin 2013-04-09 01:13:05

+0

除了同步滾動兩個網格的滾動條以外,還實現了所有其他功能。這似乎是一個常見問題,已經有人[問](http://stackoverflow.com/questions/11269558/wxgrid-detecting-scroll-event)如何檢測滾動事件。我只能找出如何綁定網格窗口中的鼠標滾輪事件。 – Erxin 2013-04-09 01:17:54

回答

4

以下代碼的init方法得到2個滾動條時抓住一個或另一個一起移動。

Python版本2.7.3 & wxpython 2.9.4.0 & windows Xp。

import wx 
import wx.grid as grid 


class Frame(wx.Frame): 
    def __init__(self, parent): 
     wx.Frame.__init__(self, parent, -1, "Grid", size=(350, 250)) 
     self.grid = grid.Grid(self) 
     self.grid.CreateGrid(20, 20) 


class ScrollSync(object): 
    def __init__(self, frame1, frame2): 
     self.frame1 = frame1 
     self.frame2 = frame2 
     self.frame1.grid.Bind(wx.EVT_SCROLLWIN, self.onScrollWin1) 
     self.frame2.grid.Bind(wx.EVT_SCROLLWIN, self.onScrollWin2) 

    def onScrollWin1(self, event): 
     if event.Orientation == wx.SB_HORIZONTAL: 
      self.frame2.grid.Scroll(event.Position, -1) 
     else: 
      self.frame2.grid.Scroll(-1, event.Position) 
     event.Skip() 

    def onScrollWin2(self, event): 
     if event.Orientation == wx.SB_HORIZONTAL: 
      self.frame1.grid.Scroll(event.Position, -1) 
     else: 
      self.frame1.grid.Scroll(-1, event.Position) 
     event.Skip() 

if __name__ == '__main__': 
    app = wx.App() 
    frame1 = Frame(None) 
    frame1.Show() 
    frame2 = Frame(None) 
    frame2.Show() 
    ScrollSync(frame1, frame2) 
    app.MainLoop() 

這是另一個使用計時器檢查和設置滾動位置的版本,因此它覆蓋了任何類型的滾動更改。

import wx 
import wx.grid as grid 


class Frame(wx.Frame): 
    def __init__(self, parent): 
     wx.Frame.__init__(self, parent, -1, "Grid", size=(350, 250)) 
     self.grid = grid.Grid(self) 
     self.grid.CreateGrid(20, 20) 


class ScrollSync(wx.EvtHandler): 
    def __init__(self, frame1, frame2): 
     super(ScrollSync, self).__init__() 
     self.frame1 = frame1 
     self.frame2 = frame2 
     self.frame1ScrollPos = self.getFrame1Pos() 
     self.frame2ScrollPos = self.getFrame2Pos() 
     self.Bind(wx.EVT_TIMER, self.onTimer) 
     self.timer = wx.Timer(self) 
     self.timer.Start(20) 

    def onTimer(self, event): 
     if not self.frame1 or not self.frame2: 
      self.timer.Stop() 
      return 
     if self.frame1ScrollPos != self.getFrame1Pos(): 
      self.frame1ScrollPos = self.getFrame1Pos() 
      self.frame2.grid.Scroll(self.frame1ScrollPos) 
     elif self.frame2ScrollPos != self.getFrame2Pos(): 
      self.frame2ScrollPos = self.getFrame2Pos() 
      self.frame1.grid.Scroll(self.frame2ScrollPos) 

    def getFrame1Pos(self): 
     horizontal = self.frame1.grid.GetScrollPos(wx.SB_HORIZONTAL) 
     vertical = self.frame1.grid.GetScrollPos(wx.SB_VERTICAL) 
     return horizontal, vertical 

    def getFrame2Pos(self): 
     horizontal = self.frame2.grid.GetScrollPos(wx.SB_HORIZONTAL) 
     vertical = self.frame2.grid.GetScrollPos(wx.SB_VERTICAL) 
     return horizontal, vertical 


if __name__ == '__main__': 
    app = wx.App() 
    frame1 = Frame(None) 
    frame1.Show() 
    frame2 = Frame(None) 
    frame2.Show() 
    ScrollSync(frame1, frame2) 
    app.MainLoop() 
+0

謝謝你的工作,但鼠標滾輪,頁面上/下和上/下行事件仍然需要單獨處理。 – Erxin 2013-04-10 07:52:18

+0

謝謝你的回答,先生。 – alwbtc 2013-12-15 14:56:10