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

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

问题:

>如何获得这两个网格的滚动事件?我试图将wx.EVT_SCROLL事件绑定到该帧,但是失败了.我还尝试将滚动事件绑定到自定义网格控件中,它也失败了.
>如何同步滚动两个网格的滚动条?提到了一个相对question的答案,该答案使用gridInstance.Scroll(row,col)滚动网格客户端窗口.但是它不包含如何同步滚动条.

非常感谢您的任何建议.

自定义框架的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())

解决方法:

下面的代码使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()
上一篇:移动端隐藏滚动条,css方法


下一篇:css滚动条样式修改