wx.Checkbox - 使用复选框关联数据

时间:2011-11-05 00:23:05

标签: wxpython

我一直试图弄清楚如何将数据与正在检查复选框的事件相关联。问题是我的数据被困在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())])

2 个答案:

答案 0 :(得分:2)

在您的事件处理程序中,您可以执行以下操作:

checkbox = event.GetEventObject()

然后你可以使用普通方法拉出触发事件的复选框的名称或id(例如checkbox.GetId()或checkbox.GetName()或checkbox.GetLabel())一旦你有了,你就可以通过那些信息到你的字典里。

您也可以像提到的其他人一样派生一个类,只需添加某种数据结构来保存它。

答案 1 :(得分:1)

您可以做的是在绑定事件时使用您可以获得的信息。为此,您可以使用partial from functools

from functools import partial

def OnTimer(self, event, label):
    pass

然后,您将使用如下部分绑定事件:

    wx.EVT_CHECKBOX(self, self.cb.GetId(), partial(self.OnTimer, label=ssslabel)

你有很多不同的密钥,所以你可以在OnTimer函数中使用** kwargs,并迭代:

def OnTimer(self, event, **kwargs):
    for key, value in kwargs.items():
        pass

使用此方法,您可以在创建控件绑定时将可用的任何内容传递给将处理绑定事件的代码。这对于动态创建带有绑定的控件特别有用。

你也可以完全按照Mike所说,并从传递给OnTimer处理程序的事件变量中使用GetEventObject()或EventObject。这将完全满足您的要求;

chboxvaldict[label][slabel][sslabel][ssslabel]