wxpython - 使用 treectrl 将本地 html 文件加载到面板中
wxpython - Using treectrl to load local html files into a panel
我试图在 wxPython 中制作一个帮助菜单,它在左侧有一个树控件,在右侧有一个 html 查看器; treecontrol 充当一种导航菜单,单击 treecontrol 中的项目时,相应的本地 .html 文件应加载到左侧面板中。
但是,当我尝试实现它时,我无法将任何事件绑定到树控件中的不同节点。这就是我目前所知道的 -- 谁能告诉我哪里出错了?
代码:
import wx
import wx.html
class HelpMenu(wx.Frame):
def __init__(self, parent):
tstr = "Need help?"
super(HelpMenu, self).__init__(
parent, -1, title=tstr, size=wx.Size(800, 500), style=wx.CAPTION |
wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.RESIZE_BORDER)
splitter = wx.SplitterWindow(self)
window1 = NavBar(splitter)
window2 = htmlPanel(splitter)
splitter.SplitVertically(window1, window2)
splitter.SetSashGravity(0.5)
# splitter.SetMinimumPaneSize(20)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
class htmlPanel(wx.Panel):
def __init__(self, parent):
super(htmlPanel, self).__init__(parent)
html = wx.html.HtmlWindow(self)
if 'gtk2' in wx.PlatformInfo:
html.SetStandardFonts()
# htmlszr = wx.BoxSizer(wx.VERTICAL)
# htmlszr.Add(html, 0, wx.EXPAND)
html.LoadPage('.\index.html')
# self.SetSizer(htmlszr)
class NavTree(wx.TreeCtrl):
def __init__(self, parent, id, pos, size, style):
super(NavTree, self).__init__(parent, id, pos, size, style)
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.root = self.tree.AddRoot('Help Contents')
self.welcome = self.tree.AppendItem(self.root, 'Start Page')
self.background = self.tree.AppendItem(self.root, 'Background')
self.method = self.tree.AppendItem(self.root, 'Calculation Method')
self.using = self.tree.AppendItem(self.root, 'Using the Calculator')
self.start = self.tree.AppendItem(self.using, 'Selecting Data Type')
self.params = self.tree.AppendItem(self.using, 'Setting Parameters')
self.results = self.tree.AppendItem(self.using, 'Viewing Results')
self.interp = self.tree.AppendItem(self.root, 'Interpreting Results')
# insert more children of interp here for various issues concerning
# interpretation
self.welcome.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._welcome)
self.background.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._background)
self.method.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._method)
self.using.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._using)
self.start.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._start)
self.params.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._params)
self.results.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._results)
self.interp.Bind(wx.EVT_TREE_ITEM_ACTIVATE, self._interp)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 0, wx.EXPAND)
self.SetSizer(self.treeszr)
def _welcome(self, event):
htmlPanel.html.LoadPage('.\Help\index.html')
def _background(self, event):
htmlPanel.html.LoadPage('.\Help\background.html')
def _method(self, event):
htmlPanel.html.LoadPage('.\Help\method.html')
def _using(self, event):
htmlPanel.html.LoadPage('.\Help\use.html')
def _start(self, event):
htmlPanel.html.LoadPage('.\Help\start.html')
def _params(self, event):
htmlPanel.html.LoadPage('\Help\params.html')
def _results(self, event):
htmlPanel.html.LoadPage('\Help\results.html')
def _interp(self, event):
htmlPanel.html.LoadPage('\Help\interpretation.html')
if __name__ == "__main__":
app = wx.App(False)
frame = HelpMenu(None)
frame.Show()
app.MainLoop()
输出:
>>> Traceback (most recent call last):
File "c:\Python\testing\splitterwindow.py", line 100, in <module>
frame = HelpMenu(None)
File "c:\Python\testing\splitterwindow.py", line 13, in
__init__
window1 = NavBar(splitter)
File "c:\Python\testing\splitterwindow.py", line 60, in __init__
self.welcome.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._welcome)
AttributeError: 'TreeItemId' object has no attribute 'Bind'
>>> C:\Python\testing>
我暗暗怀疑 self.welcome
不是指节点本身,而是指其他东西,这就是错误的来源。我只是不太确定如何在 treecontrol 中引用实际的 node/text 以便能够将事件处理程序绑定到它。
编辑 Rolf 已经完成了 99% 的工作,除了这种奇怪的行为,其中只有根填充 -- none of the children .请参阅下面的屏幕截图。
这是您的代码模型,我已经对其进行了调整,以使用 treectrl 中的标签来决定要显示的内容。
import wx
import wx.html
class HelpMenu(wx.Frame):
def __init__(self, parent):
tstr = "Need help?"
super(HelpMenu, self).__init__(
parent, -1, title=tstr, size=wx.Size(800, 500), style=wx.CAPTION |
wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.RESIZE_BORDER)
splitter = wx.SplitterWindow(self)
window1 = NavBar(splitter)
window2 = htmlPanel(splitter)
splitter.SplitVertically(window1, window2)
splitter.SetSashGravity(0.5)
# splitter.SetMinimumPaneSize(20)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
self.Show()
class htmlPanel(wx.Panel):
def __init__(self, parent):
super(htmlPanel, self).__init__(parent)
self.html = wx.html.HtmlWindow(self)
if 'gtk2' in wx.PlatformInfo:
self.html.SetStandardFonts()
htmlszr = wx.BoxSizer(wx.VERTICAL)
htmlszr.Add(self.html, 1, wx.EXPAND)
self.html.LoadPage('index.html')
self.SetSizer(htmlszr)
class NavTree(wx.TreeCtrl):
def __init__(self, parent, id, pos, size, style):
super(NavTree, self).__init__(parent, id, pos, size, style)
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.parent = parent
self.root = self.tree.AddRoot('Help Contents')
self.welcome = self.tree.AppendItem(self.root, 'Start Page')
self.background = self.tree.AppendItem(self.root, 'Background')
self.method = self.tree.AppendItem(self.root, 'Calculation Method')
self.using = self.tree.AppendItem(self.root, 'Using the Calculator')
self.start = self.tree.AppendItem(self.using, 'Selecting Data Type')
self.params = self.tree.AppendItem(self.using, 'Setting Parameters')
self.results = self.tree.AppendItem(self.using, 'Viewing Results')
self.interp = self.tree.AppendItem(self.root, 'Interpreting Results')
# insert more children of interp here for various issues concerning
# interpretation
self.tree.ExpandAll()
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._click)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 1, wx.EXPAND)
self.SetSizer(self.treeszr)
def _click(self, event):
item = event.GetItem()
label = self.tree.GetItemText(item)
print(label)
if label == 'Help Contents':
self._welcome()
elif label == 'Background':
self._background()
elif label == 'Calculation Method':
self._method()
elif label == 'Start Page':
self._start()
elif label == 'Selecting Data Type':
self._using()
elif label == 'Setting Parameters':
self._params()
elif label == 'Viewing Results':
self._results()
elif label == 'Interpreting Results':
self._interp()
def _welcome(self):
self.parent.GetWindow2().html.LoadPage('index.html')
def _background(self):
self.parent.GetWindow2().html.LoadPage('background.html')
def _method(self):
self.parent.GetWindow2().html.LoadPage('method.html')
def _using(self):
self.parent.GetWindow2().html.LoadPage('use.html')
def _start(self):
self.parent.GetWindow2().html.LoadPage('index.html')
def _params(self):
self.parent.GetWindow2().html.LoadPage('params.html')
def _results(self):
self.parent.GetWindow2().html.LoadPage('results.html')
def _interp(self):
self.parent.GetWindow2().html.LoadPage('interp.html')
if __name__ == "__main__":
app = wx.App(False)
frame = HelpMenu(None)
frame.Show()
app.MainLoop()
这里是 NavBar
class 的变体,使用 lists
作为文本和相关的 html 文件,仅使用索引位置进行链接。
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.labs = ['Help Contents', 'Start Page', 'Background', 'Calculation Method', 'Using the Calculator',\
'Selecting Data Type', 'Setting Parameters', 'Viewing Results', 'Interpreting Results']
self.pages = ['index.html','index.html','background.html','method.html',None,'use.html',\
'params.html','results.html','interp.html']
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.parent = parent
self.root = self.tree.AddRoot(self.labs[0])
self.tree.AppendItem(self.root, self.labs[1])
self.tree.AppendItem(self.root, self.labs[2])
self.tree.AppendItem(self.root, self.labs[3])
self.using = self.tree.AppendItem(self.root, self.labs[4])
self.tree.AppendItem(self.using, self.labs[5])
self.tree.AppendItem(self.using, self.labs[6])
self.tree.AppendItem(self.using, self.labs[7])
self.tree.AppendItem(self.root, self.labs[8])
# insert more children of interp here for various issues concerning
# interpretation
self.tree.ExpandAll()
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._click)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 1, wx.EXPAND)
self.SetSizer(self.treeszr)
def _click(self, event):
item = event.GetItem()
label = self.tree.GetItemText(item)
if label:
pass
else:
return
index = self.labs.index(label)
if self.pages[index]:
self.parent.GetWindow2().html.LoadPage(self.pages[index])
我试图在 wxPython 中制作一个帮助菜单,它在左侧有一个树控件,在右侧有一个 html 查看器; treecontrol 充当一种导航菜单,单击 treecontrol 中的项目时,相应的本地 .html 文件应加载到左侧面板中。
但是,当我尝试实现它时,我无法将任何事件绑定到树控件中的不同节点。这就是我目前所知道的 -- 谁能告诉我哪里出错了?
代码:
import wx
import wx.html
class HelpMenu(wx.Frame):
def __init__(self, parent):
tstr = "Need help?"
super(HelpMenu, self).__init__(
parent, -1, title=tstr, size=wx.Size(800, 500), style=wx.CAPTION |
wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.RESIZE_BORDER)
splitter = wx.SplitterWindow(self)
window1 = NavBar(splitter)
window2 = htmlPanel(splitter)
splitter.SplitVertically(window1, window2)
splitter.SetSashGravity(0.5)
# splitter.SetMinimumPaneSize(20)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
class htmlPanel(wx.Panel):
def __init__(self, parent):
super(htmlPanel, self).__init__(parent)
html = wx.html.HtmlWindow(self)
if 'gtk2' in wx.PlatformInfo:
html.SetStandardFonts()
# htmlszr = wx.BoxSizer(wx.VERTICAL)
# htmlszr.Add(html, 0, wx.EXPAND)
html.LoadPage('.\index.html')
# self.SetSizer(htmlszr)
class NavTree(wx.TreeCtrl):
def __init__(self, parent, id, pos, size, style):
super(NavTree, self).__init__(parent, id, pos, size, style)
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.root = self.tree.AddRoot('Help Contents')
self.welcome = self.tree.AppendItem(self.root, 'Start Page')
self.background = self.tree.AppendItem(self.root, 'Background')
self.method = self.tree.AppendItem(self.root, 'Calculation Method')
self.using = self.tree.AppendItem(self.root, 'Using the Calculator')
self.start = self.tree.AppendItem(self.using, 'Selecting Data Type')
self.params = self.tree.AppendItem(self.using, 'Setting Parameters')
self.results = self.tree.AppendItem(self.using, 'Viewing Results')
self.interp = self.tree.AppendItem(self.root, 'Interpreting Results')
# insert more children of interp here for various issues concerning
# interpretation
self.welcome.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._welcome)
self.background.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._background)
self.method.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._method)
self.using.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._using)
self.start.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._start)
self.params.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._params)
self.results.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._results)
self.interp.Bind(wx.EVT_TREE_ITEM_ACTIVATE, self._interp)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 0, wx.EXPAND)
self.SetSizer(self.treeszr)
def _welcome(self, event):
htmlPanel.html.LoadPage('.\Help\index.html')
def _background(self, event):
htmlPanel.html.LoadPage('.\Help\background.html')
def _method(self, event):
htmlPanel.html.LoadPage('.\Help\method.html')
def _using(self, event):
htmlPanel.html.LoadPage('.\Help\use.html')
def _start(self, event):
htmlPanel.html.LoadPage('.\Help\start.html')
def _params(self, event):
htmlPanel.html.LoadPage('\Help\params.html')
def _results(self, event):
htmlPanel.html.LoadPage('\Help\results.html')
def _interp(self, event):
htmlPanel.html.LoadPage('\Help\interpretation.html')
if __name__ == "__main__":
app = wx.App(False)
frame = HelpMenu(None)
frame.Show()
app.MainLoop()
输出:
>>> Traceback (most recent call last):
File "c:\Python\testing\splitterwindow.py", line 100, in <module>
frame = HelpMenu(None)
File "c:\Python\testing\splitterwindow.py", line 13, in
__init__
window1 = NavBar(splitter)
File "c:\Python\testing\splitterwindow.py", line 60, in __init__
self.welcome.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._welcome)
AttributeError: 'TreeItemId' object has no attribute 'Bind'
>>> C:\Python\testing>
我暗暗怀疑 self.welcome
不是指节点本身,而是指其他东西,这就是错误的来源。我只是不太确定如何在 treecontrol 中引用实际的 node/text 以便能够将事件处理程序绑定到它。
编辑 Rolf 已经完成了 99% 的工作,除了这种奇怪的行为,其中只有根填充 -- none of the children .请参阅下面的屏幕截图。
这是您的代码模型,我已经对其进行了调整,以使用 treectrl 中的标签来决定要显示的内容。
import wx
import wx.html
class HelpMenu(wx.Frame):
def __init__(self, parent):
tstr = "Need help?"
super(HelpMenu, self).__init__(
parent, -1, title=tstr, size=wx.Size(800, 500), style=wx.CAPTION |
wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.RESIZE_BORDER)
splitter = wx.SplitterWindow(self)
window1 = NavBar(splitter)
window2 = htmlPanel(splitter)
splitter.SplitVertically(window1, window2)
splitter.SetSashGravity(0.5)
# splitter.SetMinimumPaneSize(20)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
self.Show()
class htmlPanel(wx.Panel):
def __init__(self, parent):
super(htmlPanel, self).__init__(parent)
self.html = wx.html.HtmlWindow(self)
if 'gtk2' in wx.PlatformInfo:
self.html.SetStandardFonts()
htmlszr = wx.BoxSizer(wx.VERTICAL)
htmlszr.Add(self.html, 1, wx.EXPAND)
self.html.LoadPage('index.html')
self.SetSizer(htmlszr)
class NavTree(wx.TreeCtrl):
def __init__(self, parent, id, pos, size, style):
super(NavTree, self).__init__(parent, id, pos, size, style)
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.parent = parent
self.root = self.tree.AddRoot('Help Contents')
self.welcome = self.tree.AppendItem(self.root, 'Start Page')
self.background = self.tree.AppendItem(self.root, 'Background')
self.method = self.tree.AppendItem(self.root, 'Calculation Method')
self.using = self.tree.AppendItem(self.root, 'Using the Calculator')
self.start = self.tree.AppendItem(self.using, 'Selecting Data Type')
self.params = self.tree.AppendItem(self.using, 'Setting Parameters')
self.results = self.tree.AppendItem(self.using, 'Viewing Results')
self.interp = self.tree.AppendItem(self.root, 'Interpreting Results')
# insert more children of interp here for various issues concerning
# interpretation
self.tree.ExpandAll()
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._click)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 1, wx.EXPAND)
self.SetSizer(self.treeszr)
def _click(self, event):
item = event.GetItem()
label = self.tree.GetItemText(item)
print(label)
if label == 'Help Contents':
self._welcome()
elif label == 'Background':
self._background()
elif label == 'Calculation Method':
self._method()
elif label == 'Start Page':
self._start()
elif label == 'Selecting Data Type':
self._using()
elif label == 'Setting Parameters':
self._params()
elif label == 'Viewing Results':
self._results()
elif label == 'Interpreting Results':
self._interp()
def _welcome(self):
self.parent.GetWindow2().html.LoadPage('index.html')
def _background(self):
self.parent.GetWindow2().html.LoadPage('background.html')
def _method(self):
self.parent.GetWindow2().html.LoadPage('method.html')
def _using(self):
self.parent.GetWindow2().html.LoadPage('use.html')
def _start(self):
self.parent.GetWindow2().html.LoadPage('index.html')
def _params(self):
self.parent.GetWindow2().html.LoadPage('params.html')
def _results(self):
self.parent.GetWindow2().html.LoadPage('results.html')
def _interp(self):
self.parent.GetWindow2().html.LoadPage('interp.html')
if __name__ == "__main__":
app = wx.App(False)
frame = HelpMenu(None)
frame.Show()
app.MainLoop()
这里是 NavBar
class 的变体,使用 lists
作为文本和相关的 html 文件,仅使用索引位置进行链接。
class NavBar(wx.Panel):
def __init__(self, parent):
super(NavBar, self).__init__(parent)
self.labs = ['Help Contents', 'Start Page', 'Background', 'Calculation Method', 'Using the Calculator',\
'Selecting Data Type', 'Setting Parameters', 'Viewing Results', 'Interpreting Results']
self.pages = ['index.html','index.html','background.html','method.html',None,'use.html',\
'params.html','results.html','interp.html']
self.tree = NavTree(
self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TR_HAS_BUTTONS)
self.parent = parent
self.root = self.tree.AddRoot(self.labs[0])
self.tree.AppendItem(self.root, self.labs[1])
self.tree.AppendItem(self.root, self.labs[2])
self.tree.AppendItem(self.root, self.labs[3])
self.using = self.tree.AppendItem(self.root, self.labs[4])
self.tree.AppendItem(self.using, self.labs[5])
self.tree.AppendItem(self.using, self.labs[6])
self.tree.AppendItem(self.using, self.labs[7])
self.tree.AppendItem(self.root, self.labs[8])
# insert more children of interp here for various issues concerning
# interpretation
self.tree.ExpandAll()
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self._click)
self.treeszr = wx.BoxSizer(wx.VERTICAL)
self.treeszr.Add(self.tree, 1, wx.EXPAND)
self.SetSizer(self.treeszr)
def _click(self, event):
item = event.GetItem()
label = self.tree.GetItemText(item)
if label:
pass
else:
return
index = self.labs.index(label)
if self.pages[index]:
self.parent.GetWindow2().html.LoadPage(self.pages[index])