2013-04-08 2 views
3

Создан один пользовательский wx.frame для размещения окна разделителя с двумя элементами управления сеткой внутри. Он используется для сравнения данных в каждой сетке. В этот момент полоса прокрутки двух сеток должна поддерживать синхронизацию.Как синхронизировать полосы прокрутки двух сеток в wx

Вопросы:

  1. Как получить событие прокрутки этих двух GRID в? Я попытался выровнять событие wx.EVT_SCROLL в кадре, но не удалось. Я также пытаюсь связать событие прокрутки в настраиваемом элементе управления сеткой, это тоже не удалось.
  2. Как синхронизировать прокрутку полосы прокрутки двух сеток? Ответ родственника question, упомянутый для использования gridInstance.Scroll (строка, 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

+0

Клиент, что это ... так, это нужно. Столбец данных будет сравниваться как winmerge и добавить столбец фиктивной строки, чтобы совместить одинаковые столбцы. – Erxin

+0

Все остальные функции реализованы, за исключением синхронизации, прокручивая полосы прокрутки двух сетки. Это кажется общей проблемой, уже [кто-то спросил] (http://stackoverflow.com/questions/11269558/wxgrid-detecting-scroll-event), как обнаружить событие прокрутки. Я мог только узнать, как связать событие колеса мыши из окна сетки. – Erxin

ответ

4

Следующий код получает 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

+0

Благодарим вас за ответ, сэр. – alwbtc

Смежные вопросы