Python 如何在wx中同步两个网格的滚动条

Python 如何在wx中同步两个网格的滚动条,python,grid,scrollbar,sync,wxwidgets,Python,Grid,Scrollbar,Sync,Wxwidgets,创建一个自定义wx.frame以包含一个拆分器窗口,其中包含两个栅格控件。它用于比较每个网格中的数据。此时,两个网格的滚动条需要支持同步滚动 问题: 如何获得这两个网格的滚动事件?我已尝试在帧处存储wx.EVT_滚动事件,但失败。我还尝试在自定义网格控件中绑定scroll事件,但也失败了 如何同步两个网格的滚动条?使用gridInstance.Scroll(行、列)可滚动网格客户端窗口。但它不包含如何同步滚动条 非常感谢你的建议 自定义框架的init方法 def __init__(sel

创建一个自定义wx.frame以包含一个拆分器窗口,其中包含两个栅格控件。它用于比较每个网格中的数据。此时,两个网格的滚动条需要支持同步滚动

问题:

  • 如何获得这两个网格的滚动事件?我已尝试在帧处存储wx.EVT_滚动事件,但失败。我还尝试在自定义网格控件中绑定scroll事件,但也失败了
  • 如何同步两个网格的滚动条?使用gridInstance.Scroll(行、列)可滚动网格客户端窗口。但它不包含如何同步滚动条 非常感谢你的建议

    自定义框架的init方法

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

    下面的代码使两个滚动条在抓取其中一个时一起移动

    Python版本2.7.3和Wxpython2.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()
    

    你为什么不把所有的数据放在同一个网格中,并排放在一起呢?客户知道这是什么。。。所以,这是必须的。数据列将像winmerge一样进行比较,并添加虚拟列以匹配和对齐相等的列。除同步滚动两个网格的滚动条外,其他所有功能均已实现。这似乎是一个常见的问题,已经有了如何检测滚动事件的方法。我只能从网格窗口找到如何绑定鼠标滚轮事件。谢谢。这是工作,但鼠标滚轮、页面上/下和队列上/下事件仍然需要单独处理。谢谢您的回答,先生。