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

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

本文介绍了如何在wx中同步两个网格的滚动条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题:


  1. 如何获得这两个网格的滚动事件?我试图在框架中装入wx.EVT_SCROLL事件,但失败了。我也尝试绑定自定义网格控件中的滚动事件,它也失败了。

  2. 如何同步滚动两个网格的滚动条?一个相对的回答提到使用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)
s elf.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()

#无法在帧$ b处捕获滚动事件$ b 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& wxpython 2.9.4.0&

 导入wx 
导入wx.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)

$ b $ 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:
sel f.frame1.grid.Scroll(event.Position,-1)
else:
self.frame1.grid.Scroll(-1,event.Position)
event.Skip()

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

这是另一个使用计时器检查和设置滚动位置的版本,因此它涵盖了任何类型的滚动更改。



<$导入wx
导入wx.grid格子


类框架(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 = fr ame1
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或不self.frame2:
self.timer.Stop()
返回
如果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)
$ b $ def getFrame1Pos(self):
horizo​​ntal = self.frame1.grid.GetScrollPos(wx.SB_HORIZONTAL)
vertical = self.frame1.grid.GetScrollPos(wx.SB_VERTICAL)
返回n水平,垂直

def getFrame2Pos(self):
horizo​​ntal = self.frame2.grid.GetScrollPos(wx.SB_HORIZONTAL)
vertical = self.frame2.grid.GetScrollPos wx.SB_VERTICAL)
返回水平,垂直


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


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:

  1. How to get these two grid's scroll event? I have tried to bin the wx.EVT_SCROLL event at the frame but failed. I also try to bind the scroll event in the custom grid control, it's failed too.
  2. How to sync scroll the scrollbar of the two grids? An answer of a relative question mentioned to use gridInstance.Scroll(row, col) to scroll the grid client window. But it doesn't contain how to sync the scrollbar.

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

这篇关于如何在wx中同步两个网格的滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 07:09