wx.Checkbox - 将数据与复选框关联
我一直在试图弄清楚如何将数据与选中复选框的事件关联起来。问题是我的数据被困在 5 个键深的字典 (dict{dict{dict{dict{dict{}}}}}) 中。我曾尝试在父母中爬行并获取他们的标签,因为它们是从按键创建的,但由于我嵌套笔记本的方式而没有太多运气。代码如下所示:
#!/usr/bin/env python
import os
import sys
import datetime
import numpy as np
from readmonifile import MonitorFile
from sortmonifile import sort
import wx
class NestedPanelOne(wx.Panel):
#----------------------------------------------------------------------
# First notebook that creates the tab to select the component number
#----------------------------------------------------------------------
def __init__(self, parent, label, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
#Loop creating the tabs according to the component name
nestedNotebook = wx.Notebook(self, wx.ID_ANY)
for slabel in sorted(data[label].keys()):
tab = NestedPanelTwo(nestedNotebook, label, slabel, data)
nestedNotebook.AddPage(tab,slabel)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(nestedNotebook, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
class NestedPanelTwo(wx.Panel):
#------------------------------------------------------------------------------
# Second notebook that creates the tab to select the main monitoring variables
#------------------------------------------------------------------------------
def __init__(self, parent, label, slabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
nestedNotebook = wx.Notebook(self, wx.ID_ANY)
for sslabel in sorted(data[label][slabel].keys()):
tab = NestedPanelThree(nestedNotebook, label, slabel, sslabel, data)
nestedNotebook.AddPage(tab, sslabel)
sizer.Add(nestedNotebook, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def GetPage(self):
return nestedNotebook.GetPage()
class NestedPanelThree(wx.Panel):
#-------------------------------------------------------------------------------
# Third notebook that creates checkboxes to select the monitoring sub-variables
#-------------------------------------------------------------------------------
def __init__(self, parent, label, slabel, sslabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.labels=[]
self.chbox=[]
if label not in chboxdict.keys():
chboxdict[label]={}
chboxvaldict[label]={}
if slabel not in chboxdict[label].keys():
chboxdict[label][slabel]={}
chboxvaldict[label][slabel]={}
if sslabel not in chboxdict[label][slabel].keys():
chboxdict[label][slabel][sslabel]={}
chboxvaldict[label][slabel][sslabel]={}
for ssslabel in sorted(data[label][slabel][sslabel].keys()):
self.cb=wx.CheckBox(self, -1, ssslabel)
chboxdict[label][slabel][sslabel][ssslabel]=self.cb
chboxvaldict[label][slabel][sslabel][ssslabel]=self.cb.GetValue()
wx.EVT_CHECKBOX(self, self.cb.GetId(), self.OnTimer)
self.chbox.append(self.cb)
self.labels.append(ssslabel)
gridSizer = wx.GridSizer(np.shape(list(set(self.labels)))[0],3, 5, 5)
gridSizer.AddMany(self.chbox)
self.SetSizer(gridSizer)
def OnTimer(self, event):
#print "OnTimer Update..."
# before we get data, do we have to bother?
isVisible = self.IsShown()
child = self
parent = self.GetParent()
while(parent!=None and not parent.IsTopLevel()):
if(parent.IsShown() and isinstance(parent, wx.BookCtrlBase)):
if(parent.IsShown()):
selectionPage = parent.GetPage(parent.GetSelection())
pageselected = parent.GetParent().GetPage()
print selectionPage, pageselected, 'test2'
if(selectionPage!=child):
isVisible=False
break
else:
if(not parent.IsShown()):
isVisible=False
break
child = parent
parent = parent.GetParent()
def ShowParents(self, event):
if self.cb.GetValue():
print label, slabel, sslabel, self.cb.GetLabel()
else:
print 'Please select'
########################################################################
class NestedNotebook(wx.Notebook):
#---------------------------------------------------------------------------------
# Main notebook creating tabs for the monitored components
#---------------------------------------------------------------------------------
def __init__(self, parent, data):
wx.Notebook.__init__(self, parent, id=wx.ID_ANY, style=
wx.BK_DEFAULT
)
for label in sorted(data.keys()):
tab = NestedPanelOne(self,label, data)
self.AddPage(tab, label)
########################################################################
class mainFrame(wx.Frame):
#----------------------------------------------------------------------
# Putting it all together
#----------------------------------------------------------------------
def __init__(self,data):
wx.Frame.__init__(self, None, wx.ID_ANY,
"pDAQ monitoring plotting tool",
size=(800,400)
)
panel = wx.Panel(self)
notebook = NestedNotebook(panel, data)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
panel.SetSizer(sizer)
self.Layout()
#Menu Bar to be added later
'''
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(1, '&Quit', 'Exit Tool')
menubar.Append(file, '&File')
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnClose, id=1)
'''
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
if len(sys.argv) == 1:
raise SystemExit("Please specify a file to process")
for f in sys.argv[1:]:
data=sort.sorting(f)
print 'test'
chboxdict={}
chboxvaldict={}
app = wx.PySimpleApp()
frame = mainFrame(data)
app.MainLoop()
print 'testend'
在 NestedPanelThree
类中,我将复选框与数据关联起来,并尝试爬过面板。
有没有一种方法可以将复选框与数据关联起来,这样如果选中该复选框,就会检索用于创建它的密钥?或者有没有办法更新 chboxvaldict[label][slabel][sslabel][ssslabel] 的值,而不必循环遍历所有键?
提前非常感谢
解决方案:
class NestedPanelThree(wx.Panel):
###
# Third notebook that creates checkboxes to select the monitoring sub-variables
###
def __init__(self, parent, label, slabel, sslabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.chbox=[]
for ssslabel in sorted(data[label][slabel][sslabel].keys()):
self.cb=wx.CheckBox(self, -1, ssslabel)
chboxdict[str(self.cb.GetId())]=[label,slabel,sslabel,ssslabel]
wx.EVT_CHECKBOX(self, self.cb.GetId(), self.OnClick)
self.chbox.append(self.cb)
gs = wx.GridSizer(0,3)
gs.AddMany(self.chbox)
self.SetSizer(gs)
def OnClick(self, event):
if chboxdict[str(event.GetEventObject().GetId())] not in clicked:
clicked.append(chboxdict[str(event.GetEventObject().GetId())])
else:
clicked.remove(chboxdict[str(event.GetEventObject().GetId())])
I have been trying to figure out how to associate data with the event of checkbox being checked. The problem is that my data is stuck in a 5 keys deep dictionary (dict{dict{dict{dict{dict{}}}}}). I have tried crawling through the parents and getting their labels since they are created from the keys, but havent had much luck because of how I nested the notebooks. The code looks a follows:
#!/usr/bin/env python
import os
import sys
import datetime
import numpy as np
from readmonifile import MonitorFile
from sortmonifile import sort
import wx
class NestedPanelOne(wx.Panel):
#----------------------------------------------------------------------
# First notebook that creates the tab to select the component number
#----------------------------------------------------------------------
def __init__(self, parent, label, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
#Loop creating the tabs according to the component name
nestedNotebook = wx.Notebook(self, wx.ID_ANY)
for slabel in sorted(data[label].keys()):
tab = NestedPanelTwo(nestedNotebook, label, slabel, data)
nestedNotebook.AddPage(tab,slabel)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(nestedNotebook, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
class NestedPanelTwo(wx.Panel):
#------------------------------------------------------------------------------
# Second notebook that creates the tab to select the main monitoring variables
#------------------------------------------------------------------------------
def __init__(self, parent, label, slabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
nestedNotebook = wx.Notebook(self, wx.ID_ANY)
for sslabel in sorted(data[label][slabel].keys()):
tab = NestedPanelThree(nestedNotebook, label, slabel, sslabel, data)
nestedNotebook.AddPage(tab, sslabel)
sizer.Add(nestedNotebook, 1, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
def GetPage(self):
return nestedNotebook.GetPage()
class NestedPanelThree(wx.Panel):
#-------------------------------------------------------------------------------
# Third notebook that creates checkboxes to select the monitoring sub-variables
#-------------------------------------------------------------------------------
def __init__(self, parent, label, slabel, sslabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.labels=[]
self.chbox=[]
if label not in chboxdict.keys():
chboxdict[label]={}
chboxvaldict[label]={}
if slabel not in chboxdict[label].keys():
chboxdict[label][slabel]={}
chboxvaldict[label][slabel]={}
if sslabel not in chboxdict[label][slabel].keys():
chboxdict[label][slabel][sslabel]={}
chboxvaldict[label][slabel][sslabel]={}
for ssslabel in sorted(data[label][slabel][sslabel].keys()):
self.cb=wx.CheckBox(self, -1, ssslabel)
chboxdict[label][slabel][sslabel][ssslabel]=self.cb
chboxvaldict[label][slabel][sslabel][ssslabel]=self.cb.GetValue()
wx.EVT_CHECKBOX(self, self.cb.GetId(), self.OnTimer)
self.chbox.append(self.cb)
self.labels.append(ssslabel)
gridSizer = wx.GridSizer(np.shape(list(set(self.labels)))[0],3, 5, 5)
gridSizer.AddMany(self.chbox)
self.SetSizer(gridSizer)
def OnTimer(self, event):
#print "OnTimer Update..."
# before we get data, do we have to bother?
isVisible = self.IsShown()
child = self
parent = self.GetParent()
while(parent!=None and not parent.IsTopLevel()):
if(parent.IsShown() and isinstance(parent, wx.BookCtrlBase)):
if(parent.IsShown()):
selectionPage = parent.GetPage(parent.GetSelection())
pageselected = parent.GetParent().GetPage()
print selectionPage, pageselected, 'test2'
if(selectionPage!=child):
isVisible=False
break
else:
if(not parent.IsShown()):
isVisible=False
break
child = parent
parent = parent.GetParent()
def ShowParents(self, event):
if self.cb.GetValue():
print label, slabel, sslabel, self.cb.GetLabel()
else:
print 'Please select'
########################################################################
class NestedNotebook(wx.Notebook):
#---------------------------------------------------------------------------------
# Main notebook creating tabs for the monitored components
#---------------------------------------------------------------------------------
def __init__(self, parent, data):
wx.Notebook.__init__(self, parent, id=wx.ID_ANY, style=
wx.BK_DEFAULT
)
for label in sorted(data.keys()):
tab = NestedPanelOne(self,label, data)
self.AddPage(tab, label)
########################################################################
class mainFrame(wx.Frame):
#----------------------------------------------------------------------
# Putting it all together
#----------------------------------------------------------------------
def __init__(self,data):
wx.Frame.__init__(self, None, wx.ID_ANY,
"pDAQ monitoring plotting tool",
size=(800,400)
)
panel = wx.Panel(self)
notebook = NestedNotebook(panel, data)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
panel.SetSizer(sizer)
self.Layout()
#Menu Bar to be added later
'''
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(1, '&Quit', 'Exit Tool')
menubar.Append(file, '&File')
self.SetMenuBar(menubar)
self.Bind(wx.EVT_MENU, self.OnClose, id=1)
'''
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
if len(sys.argv) == 1:
raise SystemExit("Please specify a file to process")
for f in sys.argv[1:]:
data=sort.sorting(f)
print 'test'
chboxdict={}
chboxvaldict={}
app = wx.PySimpleApp()
frame = mainFrame(data)
app.MainLoop()
print 'testend'
The NestedPanelThree
class is where I associate the checkboxes with the data and tried to crawl up through the panels.
Is there a way to associate the checkbox with data, such that if the checkbox is checked, the keys that were being used to create it are retrieved? Or is there a way to update the values of chboxvaldict[label][slabel][sslabel][ssslabel]
without having to loop through all the keys?
Thanks a bunch in advance
Solution:
class NestedPanelThree(wx.Panel):
###
# Third notebook that creates checkboxes to select the monitoring sub-variables
###
def __init__(self, parent, label, slabel, sslabel, data):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.chbox=[]
for ssslabel in sorted(data[label][slabel][sslabel].keys()):
self.cb=wx.CheckBox(self, -1, ssslabel)
chboxdict[str(self.cb.GetId())]=[label,slabel,sslabel,ssslabel]
wx.EVT_CHECKBOX(self, self.cb.GetId(), self.OnClick)
self.chbox.append(self.cb)
gs = wx.GridSizer(0,3)
gs.AddMany(self.chbox)
self.SetSizer(gs)
def OnClick(self, event):
if chboxdict[str(event.GetEventObject().GetId())] not in clicked:
clicked.append(chboxdict[str(event.GetEventObject().GetId())])
else:
clicked.remove(chboxdict[str(event.GetEventObject().GetId())])
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在事件处理程序中,您可以执行以下操作:
然后,您可以使用其常规方法(即 checkbox.GetId() 或 checkbox.GetName() 或 checkbox.GetLabel() 提取触发事件的复选框的名称或 id) )一旦获得,您可以将该信息传递到您的字典中。
您还可以像其他人提到的那样派生一个类,然后添加某种数据结构来保存它。
In your event handler, you can do something like this:
Then you can pull the name or id of the checkbox that fired the event using its normal methods (i.e. checkbox.GetId() or checkbox.GetName() or checkbox.GetLabel()) Once you have that, you can pass that information to your dictionary.
You could also derive a class as the other guy mentioned and just add some kind of data structure to hold it.
您可以做的是使用绑定事件时可用的信息。为此,您可以使用来自 functools 的部分。
然后,您将使用像这样的部分绑定事件:
您有很多不同的可用键,因此您可以在 OnTimer 函数中使用 **kwargs,并迭代它:
使用此方法,您可以将可用的任何内容传递给当您为控件创建绑定时,您将绑定到将处理您绑定到的事件的代码。当您动态创建带有绑定的控件时,这尤其有用。
您也可以完全按照 Mike 所说的操作,并使用传递给 OnTimer 处理程序的事件变量中的 GetEventObject() 或 EventObject。这将为您提供您所要求的内部信息;
What you could do is to use the information you have available to you when you are binding the event. To do this, you could use partial from functools.
You then would bind the event using partial like this:
You have a lot of different keys available, so you could just use **kwargs in the OnTimer function, and iterate through that:
With this method, you can pass anything you had available to you at the time you created a binding for the control, to the code that will handle the event that you are binding to. This is especially great for when you create controls with bindings dynamically.
You could also just do exactly what Mike said, and use GetEventObject() or EventObject from the event variable passed to the OnTimer handler. This will give you exactly what you asked for inside;