wx中如何同步两个网格的滚动条 [英] How to sync the scrollbars of two grids in wx

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

问题描述

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

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.

问题:

  1. 如何获取这两个网格的滚动事件?我试图在框架上绑定 wx.EVT_SCROLL 事件但失败了.我也尝试在自定义网格控件中绑定滚动事件,也失败了.
  2. 如何同步滚动两个网格的滚动条?提到使用 gridInstance.Scroll 的相对 问题 的答案(row, col) 滚动网格客户端窗口.但它不包含如何同步滚动条.
  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.

自定义框架的init方法

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

推荐答案

当你抓住一个或另一个时,下面的代码让 2 个滚动条一起移动.

The following code gets 2 scrollbars moving together when you grab one or the other.

Python 版本 2.7.3 &wxpython 2.9.4.0 &Windows XP.

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中如何同步两个网格的滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆