2 wx HyperTreeLists 之间的同步滚动并不完美

Synchronized scrolling is not perfect between 2 wx HyperTreeLists

简介摘要:我需要在 2 个树对象之间创建一个并排差异查看器,我可以在其中完全自定义每个项目的文本颜色和背景颜色。

Python版本:3.5.4

wxPython版本:4.0.3

结构:wx.Dialog 包含 2 个使用水平 boxsizer 的派生 HyperTreeList。

代码(仅包含必需部分的剥离版本;树将始终具有相同的大小,因为展开和折叠是同步的):

import wx
import wx.lib.agw.hypertreelist as HTL

class AutoColumnSizeHTL(HTL.HyperTreeList):
    def __init__(self, parent, agw_style, column_name):
        super().__init__(parent, agwStyle=agw_style)
        self.parent = parent
        self.AddColumn(column_name)
        self.SetColumnWidth(0, 350)
        self.main_window = self.GetMainWindow()
        self.root = self.AddRoot("")
        self.current_item = None
        self.twin_tree = None

        self.main_window.Bind(wx.EVT_SCROLLWIN, self.on_scroll_change)

    def add_new_item(self, text, fg_color):
        self.current_item = self.main_window.AppendItem(self.root, text)
        self.main_window.SetItemTextColour(self.current_item, fg_color)

    def add_new_item_child(self, text, fg_color, bg_color):
        child_item = self.main_window.AppendItem(self.current_item, text)
        self.main_window.SetItemTextColour(child_item, fg_color)
        self.main_window.SetItemBackgroundColour(child_item, bg_color)

    def set_twin_tree(self, twin):
        self.twin_tree = twin

    def OnSize(self, event):
        row_width = self.parent.GetSize()[0] / 2
        scrollbar_width = 21
        self.SetColumnWidth(0, row_width-scrollbar_width)
        super().OnSize(event)

    def on_scroll_change(self, event):
        scroll_units = self.main_window.GetScrollPos(wx.VERTICAL)
        self.twin_tree.main_window.Scroll(-1, scroll_units)
        event.Skip()

Initial Start

After 1 nudge of WheelDown

PS:我使用的是 2 个各有 1 列的超树列表,而不是 1 个有 2 列的超树列表,因为我不知道如何更改第 2 列中项目的颜色。如果你碰巧知道如何做到这一点,也将解决这个麻烦。

如果您使用的是最新的 Phoenix 安装,那么 HyperTreeList 有一个 SetItemBackgroundColour(item, colour, col) 方法来设置每列的背景颜色。

想通了。

def __init__(...):
    ...
    self.main_window.Bind(wx.EVT_MOUSEWHEEL, self.on_scroll_change)

def on_scroll_change(self, event):
    delta = event.GetWheelDelta()
    rotation = event.GetWheelRotation()
    lines_per_action = event.GetLinesPerAction()
    lines = rotation / delta
    if lines != 0:
        lines = lines * lines_per_action
        vsx, vsy = self.twin_tree.main_window.GetViewStart()
        scroll_to = vsy - lines
        self.twin_tree.main_window.Scroll(-1, scroll_to)
        self.main_window.Scroll(-1, scroll_to)

event.Skip() 与我的想法相反。