Last active
July 25, 2021 09:28
-
-
Save ushiushix/87c3927c9d831f66da067bd88f01cc8c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: UTF-8 -*- | |
import wx | |
import sys | |
import json | |
from wx.core import TreeItemIcon_Expanded, Treebook | |
class TreeVisitor: | |
def __init__(self, tree_ctrl: wx.TreeCtrl, list_ctrl: wx.ListCtrl): | |
self.tree_ctrl = tree_ctrl | |
self.list_ctrl = list_ctrl | |
self.node = None | |
def visit_node(self, node: wx.TreeItemId): | |
if node != self.node: | |
self.tree_ctrl.SelectItem(node) | |
self.node = node | |
self.fill_list() | |
def visit_parent(self): | |
parent = self.tree_ctrl.GetItemParent(self.node) | |
if parent.IsOk(): | |
self.visit_node(parent) | |
def visit_first_child(self): | |
child, cookie = self.tree_ctrl.GetFirstChild(self.node) | |
if child.IsOk(): | |
self.visit_node(child) | |
def visit_item(self, item: wx.ListItem): | |
name = item.GetText() | |
child, cookie = self.tree_ctrl.GetFirstChild(self.node) | |
while child.IsOk(): | |
if self.tree_ctrl.GetItemText(child) == name: | |
break | |
else: | |
child, cookie = self.tree_ctrl.GetNextChild(child, cookie) | |
if child.IsOk(): | |
self.tree_ctrl.SelectItem(child) | |
def fill_list(self): | |
data = self.tree_ctrl.GetItemData(self.node) | |
if isinstance(data, dict): | |
self.list_ctrl.DeleteAllItems() | |
for k,v in data.items(): | |
self.list_ctrl.Append((k, self.format_value(v))) | |
elif isinstance(data, list): | |
self.list_ctrl.DeleteAllItems() | |
for i in range(len(data)): | |
self.list_ctrl.Append(('[{}]'.format(i), self.format_value(data[i]))) | |
def format_value(self, value): | |
if isinstance(value, list): | |
return '[{}]'.format(len(value)) | |
elif isinstance(value, dict): | |
return '{' + ','.join(value.keys()) + '}' | |
else: | |
return value | |
class DataViewer(wx.Frame): | |
def __init__(self, *args, **kwds): | |
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE | |
wx.Frame.__init__(self, *args, **kwds) | |
self.SetSize((640, 480)) | |
self.SetTitle("DataViewer") | |
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)) | |
self.panel_1 = wx.Panel(self, wx.ID_ANY) | |
main_sizer = wx.BoxSizer(wx.VERTICAL) | |
#controls_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
#main_sizer.Add(controls_sizer, 1, wx.EXPAND, 0) | |
#controls_sizer.Add((0, 0), 0, 0, 0) | |
viewer_sizer = wx.BoxSizer(wx.HORIZONTAL) | |
main_sizer.Add(viewer_sizer, 1, wx.EXPAND, 0) | |
self.data_tree = wx.TreeCtrl(self.panel_1, wx.ID_ANY, style=wx.BORDER_SUNKEN | wx.TR_HAS_BUTTONS | wx.TR_NO_BUTTONS) | |
viewer_sizer.Add(self.data_tree, 1, wx.EXPAND, 0) | |
self.data_list = wx.ListCtrl(self.panel_1, wx.ID_ANY, style=wx.LC_HRULES | wx.LC_REPORT | wx.LC_VRULES) | |
self.data_list.AppendColumn("Key", format=wx.LIST_FORMAT_LEFT, width=-1) | |
self.data_list.AppendColumn("Value", format=wx.LIST_FORMAT_LEFT, width=-1) | |
viewer_sizer.Add(self.data_list, 1, wx.EXPAND, 0) | |
self.panel_1.SetSizer(main_sizer) | |
self.Layout() | |
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeSelChanged, self.data_tree) | |
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnListItemActivated, self.data_list) | |
self.Bind(wx.EVT_LIST_KEY_DOWN, self.OnListKeyDown, self.data_list) | |
self.Bind(wx.EVT_TREE_KEY_DOWN, self.OnTreeKeyDown, self.data_tree) | |
self.load_data() | |
self.data_tree.ExpandAll() | |
def load_data(self): | |
argv = sys.argv | |
if len(argv) == 2: | |
with open(argv[1], 'rb') as fp: | |
self.data = json.load(fp) | |
else: | |
self.data = json.load(sys.stdin) | |
self.root = self.data_tree.AddRoot('Root') | |
self.data_tree.SetItemData(self.root, self.data) | |
for key, value in self.data.items(): | |
self.set_tree_data(self.root, key, value) | |
self.visitor = TreeVisitor(self.data_tree, self.data_list) | |
self.visitor.visit_node(self.root) | |
def OnTreeSelChanged(self, event): | |
item = event.GetItem() | |
self.visitor.visit_node(item) | |
def OnListItemActivated(self, event): | |
item = event.GetItem() | |
self.visitor.visit_item(item) | |
def OnListKeyDown(self, event): | |
keycode = event.GetKeyCode() | |
if keycode == wx.WXK_BACK: | |
self.visitor.visit_parent() | |
else: | |
event.Skip() | |
def OnTreeKeyDown(self, event): | |
keycode = event.GetKeyCode() | |
if keycode == ord('.'): | |
self.visitor.visit_first_child() | |
else: | |
event.Skip() | |
def set_tree_data(self, node: wx.TreeItemId, key, value): | |
id = self.data_tree.AppendItem(node, key) | |
self.data_tree.SetItemData(id, value) | |
if isinstance(value, dict): | |
for k, v in value.items(): | |
self.set_tree_data(id, k, v) | |
elif isinstance(value, list): | |
for i in range(len(value)): | |
self.set_tree_data(id, '[{}]'.format(i), value[i]) | |
# end of class DataViewer | |
class MyApp(wx.App): | |
def OnInit(self): | |
self.frame = DataViewer(None, wx.ID_ANY, "") | |
self.SetTopWindow(self.frame) | |
self.frame.Show() | |
return True | |
# end of class MyApp | |
if __name__ == "__main__": | |
app = MyApp(0) | |
app.MainLoop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment