One custom wx.frame is created to contain a splitter window with two grid controls inside. It's used to compare the data in each of the grid. At this point the scrollbar of two grids need to support sync scroll.
Questions:
Many thanks for any suggestion.
The init method of the custom frame
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())
The following code gets 2 scrollbars moving together when you grab one or the other.
Python version 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()
Here is another version that uses a timer to check and set scroll positions, so it cover any type of scroll change.
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With