2011-04-18 95 views
2

如何创建一个事件,当一个框被选中/取消选中?在这个例子中我只是希望它打印有关被检查Python创建事件到ObjectListView复选框

注意对象中的数据:该代码http://www.blog.pythonlibrary.org/2009/12/23/wxpython-using-objectlistview-instead-of-a-listctrl/修改为一个学习的

import wx 
from ObjectListView import ObjectListView, ColumnDefn 

######################################################################## 
class Book(object): 
    """ 
    Model of the Book object 

    Contains the following attributes: 
    'ISBN', 'Author', 'Manufacturer', 'Title' 
    """ 
    #---------------------------------------------------------------------- 
    def __init__(self, title, author, isbn, mfg): 
     self.isbn = isbn 
     self.author = author 
     self.mfg = mfg 
     self.title = title 


######################################################################## 
class MainPanel(wx.Panel): 
    #---------------------------------------------------------------------- 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY) 
     self.products = [Book("wxPython in Action", "Robin Dunn", 
           "1932394621", "Manning"), 
         Book("Hello World", "Warren and Carter Sande", 
           "1933988495", "Manning") 
         ] 

     self.dataOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER) 
     self.setBooks() 
     self.dataOlv.CreateCheckStateColumn()   

     # Allow the cell values to be edited when double-clicked 
     self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK 

     # create an update button 
     updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV") 
     updateBtn.Bind(wx.EVT_BUTTON, self.updateControl) 

     # Create some sizers 
     mainSizer = wx.BoxSizer(wx.VERTICAL) 

     mainSizer.Add(self.dataOlv, 1, wx.ALL|wx.EXPAND, 5) 
     mainSizer.Add(updateBtn, 0, wx.ALL|wx.CENTER, 5) 
     self.SetSizer(mainSizer) 

    #---------------------------------------------------------------------- 
    def updateControl(self, event): 
     """ 

     """ 
     print "updating..." 
     product_dict = [Book("Core Python Programming", "Wesley Chun", 
         "0132269937", "Prentice Hall"), 
         Book("Python Programming for the Absolute Beginner", 
         "Michael Dawson", "1598631128", "Course Technology"), 
         Book("Learning Python", "Mark Lutz", 
         "0596513984", "O'Reilly") 
         ] 
     data = self.products + product_dict 
     self.dataOlv.SetObjects(data) 

    #---------------------------------------------------------------------- 
    def setBooks(self, data=None): 
     self.dataOlv.SetColumns([ 
      ColumnDefn("Title", "left", 220, "title"), 
      ColumnDefn("Author", "left", 200, "author"), 
      ColumnDefn("ISBN", "right", 100, "isbn"), 
      ColumnDefn("Mfg", "left", 180, "mfg") 
     ]) 

     self.dataOlv.SetObjects(self.products) 

######################################################################## 
class MainFrame(wx.Frame): 
    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, 
          title="ObjectListView Demo", size=(800,600)) 
     panel = MainPanel(self) 

######################################################################## 
class GenApp(wx.App): 

    #---------------------------------------------------------------------- 
    def __init__(self, redirect=False, filename=None): 
     wx.App.__init__(self, redirect, filename) 

    #---------------------------------------------------------------------- 
    def OnInit(self): 
     # create frame here 
     frame = MainFrame() 
     frame.Show() 
     return True 

#---------------------------------------------------------------------- 
def main(): 
    """ 
    Run the demo 
    """ 
    app = GenApp() 
    app.MainLoop() 

if __name__ == "__main__": 
    main() 

回答

4

ObjectListView似乎不包含该功能。在深入了解代码之后,我决定扩展它。

您可以从ObjectListView派生自己的班级并强制进行该活动。必须覆盖_HandleLeftDownOnImageSetCheckState方法。或者,如果你喜欢,你可以改变ObjectListView代码。我已经得出一个新的类:

import wx.lib.newevent 

OvlCheckEvent, EVT_OVL_CHECK_EVENT = wx.lib.newevent.NewEvent() 

class MyOvl(ObjectListView): 
    def SetCheckState(self, modelObject, state): 
     """ 
     This is the same code, just added the event inside 
     """ 
     if self.checkStateColumn is None: 
      return None 
     else: 
      r = self.checkStateColumn.SetCheckState(modelObject, state) 

      # Just added the event here =================================== 
      e = OvlCheckEvent(object=modelObject, value=state) 
      wx.PostEvent(self, e) 
      # ============================================================= 

      return r 

    def _HandleLeftDownOnImage(self, rowIndex, subItemIndex): 
     """ 
     This is the same code, just added the event inside 
     """ 
     column = self.columns[subItemIndex] 
     if not column.HasCheckState(): 
      return 

     self._PossibleFinishCellEdit() 
     modelObject = self.GetObjectAt(rowIndex) 
     if modelObject is not None: 
      column.SetCheckState(modelObject, not column.GetCheckState(modelObject)) 

      # Just added the event here =================================== 
      e = OvlCheckEvent(object=modelObject, value=column.GetCheckState(modelObject)) 
      wx.PostEvent(self, e) 
      # ============================================================= 

      self.RefreshIndex(rowIndex, modelObject) 

然后我用的是类,而不是ObjectListView

self.dataOlv = MyOvl(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER) 

绑定事件:

self.dataOlv.Bind(EVT_OVL_CHECK_EVENT, self.HandleCheckbox) 

写下了处理:

def HandleCheckbox(self, e): 
    print(e.object.title, e.value) 

I我确信这不是如何做到这一点的最好方式,但它是简单而有效的破解:-D。


编辑:完整示例

import wx 
import wx.lib.newevent 
from ObjectListView import ObjectListView, ColumnDefn, OLVEvent 

OvlCheckEvent, EVT_OVL_CHECK_EVENT = wx.lib.newevent.NewEvent() 

class MyOvl(ObjectListView): 
    def SetCheckState(self, modelObject, state): 
     """ 
     This is the same code, just added the event inside 
     """ 
     if self.checkStateColumn is None: 
      return None 
     else: 
      r = self.checkStateColumn.SetCheckState(modelObject, state) 

      # Just added the event here =================================== 
      e = OvlCheckEvent(object=modelObject, value=state) 
      wx.PostEvent(self, e) 
      # ============================================================= 

      return r 

    def _HandleLeftDownOnImage(self, rowIndex, subItemIndex): 
     """ 
     This is the same code, just added the event inside 
     """ 
     column = self.columns[subItemIndex] 
     if not column.HasCheckState(): 
      return 

     self._PossibleFinishCellEdit() 
     modelObject = self.GetObjectAt(rowIndex) 
     if modelObject is not None: 
      column.SetCheckState(modelObject, not column.GetCheckState(modelObject)) 

      # Just added the event here =================================== 
      e = OvlCheckEvent(object=modelObject, value=column.GetCheckState(modelObject)) 
      wx.PostEvent(self, e) 
      # ============================================================= 

      self.RefreshIndex(rowIndex, modelObject) 

######################################################################## 
class Book(object): 
    """ 
    Model of the Book object 

    Contains the following attributes: 
    'ISBN', 'Author', 'Manufacturer', 'Title' 
    """ 
    #---------------------------------------------------------------------- 
    def __init__(self, title, author, isbn, mfg): 
     self.isbn = isbn 
     self.author = author 
     self.mfg = mfg 
     self.title = title 

######################################################################## 
class MainPanel(wx.Panel): 
    #---------------------------------------------------------------------- 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY) 
     self.products = [Book("wxPython in Action", "Robin Dunn", 
           "1932394621", "Manning"), 
         Book("Hello World", "Warren and Carter Sande", 
           "1933988495", "Manning") 
         ] 

     self.dataOlv = MyOvl(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER) 
     self.setBooks() 
     self.dataOlv.CreateCheckStateColumn() 
     self.dataOlv.Bind(EVT_OVL_CHECK_EVENT, self.HandleCheckbox) 

     # Allow the cell values to be edited when double-clicked 
     self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK 

     # create an update button 
     updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV") 
     updateBtn.Bind(wx.EVT_BUTTON, self.updateControl) 

     # Create some sizers 
     mainSizer = wx.BoxSizer(wx.VERTICAL) 

     mainSizer.Add(self.dataOlv, 1, wx.ALL|wx.EXPAND, 5) 
     mainSizer.Add(updateBtn, 0, wx.ALL|wx.CENTER, 5) 
     self.SetSizer(mainSizer) 

    def HandleCheckbox(self, e): 
     print(e.object.title, e.value) 

    #---------------------------------------------------------------------- 
    def updateControl(self, event): 
     """ 

     """ 
     print "updating..." 
     product_dict = [Book("Core Python Programming", "Wesley Chun", 
         "0132269937", "Prentice Hall"), 
         Book("Python Programming for the Absolute Beginner", 
         "Michael Dawson", "1598631128", "Course Technology"), 
         Book("Learning Python", "Mark Lutz", 
         "0596513984", "O'Reilly") 
         ] 
     data = self.products + product_dict 
     self.dataOlv.SetObjects(data) 

    #---------------------------------------------------------------------- 
    def setBooks(self, data=None): 
     self.dataOlv.SetColumns([ 
      ColumnDefn("Title", "left", 220, "title"), 
      ColumnDefn("Author", "left", 200, "author"), 
      ColumnDefn("ISBN", "right", 100, "isbn"), 
      ColumnDefn("Mfg", "left", 180, "mfg") 
     ]) 

     self.dataOlv.SetObjects(self.products) 

######################################################################## 
class MainFrame(wx.Frame): 
    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, 
          title="ObjectListView Demo", size=(800,600)) 
     panel = MainPanel(self) 

######################################################################## 
class GenApp(wx.App): 

    #---------------------------------------------------------------------- 
    def __init__(self, redirect=False, filename=None): 
     wx.App.__init__(self, redirect, filename) 

    #---------------------------------------------------------------------- 
    def OnInit(self): 
     # create frame here 
     frame = MainFrame() 
     frame.Show() 
     return True 

#---------------------------------------------------------------------- 
def main(): 
    """ 
    Run the demo 
    """ 
    app = GenApp() 
    app.MainLoop() 

if __name__ == "__main__": 
    main() 
+0

Im的用户一个非常基本的/新的水平。你能告诉我如何应用你的解决方案与上面的例子吗? – ccwhite1 2011-04-21 18:26:10

+0

@ ccwhite1 - 新增完整示例。 – Fenikso 2011-04-21 19:46:28

+0

谢谢,那就是我需要的 – ccwhite1 2011-04-25 11:56:51

0

的ObjectListView文档似乎没有任何关于这个问题的数据,除了以下两个清单:

http://objectlistview.sourceforge.net/python/recipes.html#data-based-checkboxes

http://objectlistview.sourceforge.net/python/recipes.html#how-do-i-use-checkboxes-in-my-objectlistview

第一个可以通过checkStateGetter参数帮助您。我怀疑ObjectListView中包含CheckListCtrlMixin。如果是这样,那么你可以继承你的ObjectListView类并覆盖OnCheckItem方法,如CheckListCtrlMixin的wxPython演示所示。

我最后想到的是,当您选择行时,您可能必须执行adhoc事件绑定。我的意思是,在该行的选择事件中,尝试获取事件对象(希望是一个ListItem实例)并将该对象绑定到EVT_CHECKBOX。

如果没有这些工作,然后转到官方wxPython邮件列表,并在那里问。这就是大多数wxPython用户的地方。