代码之家  ›  专栏  ›  技术社区  ›  Allan

仅响应一次listcrl更改

  •  3
  • Allan  · 技术社区  · 14 年前

    我正在使用wxpython处理一个表单,在这里我希望ListCtrl的值列表根据另一个ListCtrl的选择进行更改。为此,我使用链接到控制对象的方法 EVT_LIST_ITEM_SELECTED EVT_LIST_ITEM_DESELECTED 事件调用 Publisher.sendMessage . 要更改的控件具有订阅该发布服务器的方法。这是有效的:单击第一个listcrl时,将刷新第二个listcrl。

    问题是必须从数据库中刷新数据,并为每次选择和取消选择发送消息。这意味着,即使我只是单击一个项目,数据库也会被查询两次(一次用于取消选择,然后再次用于选择)。如果我切换到多选5个项目,则会进行5个呼叫。有没有方法让listcrl响应集合,而不是单个选择?

    3 回复  |  直到 12 年前
        1
  •  4
  •   Allan    14 年前

    最好的解决方案似乎是使用 wx.CallAfter 带有一个标志,可以执行一次完全相同的后续过程:

    import wx
    
    class MyFrame(wx.Frame):
        def __init__(self, *args, **kwds):
            wx.Frame.__init__(self, *args, **kwds)
            self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
            sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
            sizer_1.Add(self.list_ctrl_1, 1, wx.EXPAND, 0)
            self.list_ctrl_1.InsertColumn(0,"1")
            self.list_ctrl_1.InsertStringItem(0,"HELLO1")
            self.list_ctrl_1.InsertStringItem(0,"HELLO2")
            self.list_ctrl_1.InsertStringItem(0,"HELLO3")
            self.list_ctrl_1.InsertStringItem(0,"HELLO4")
            self.list_ctrl_1.InsertStringItem(0,"HELLO5")
            self.list_ctrl_1.InsertStringItem(0,"HELLO6")
            self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list_ctrl_1)
            self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list_ctrl_1)
            self.dirty = False
        def Cleanup(self, StringToPrint):
            print 'No Longer Dirty!'
            self.dirty = False
    
        def OnItemSelected(self,event):
            print str(self.__class__) + " - OnItemSelected"
            if not self.dirty:
                self.dirty = True
                wx.CallAfter(self.Cleanup)
            event.Skip()
    
        def OnItemDeselected(self,event):
            print str(self.__class__) + " - OnItemDeselected"
            if not self.dirty:
                self.dirty = True
                wx.CallAfter(self.Cleanup)
            event.Skip()
    
    if __name__ == "__main__":
        app = wx.PySimpleApp(0)
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None, -1, "")
        app.SetTopWindow(frame_1)
        frame_1.Show()
        app.MainLoop()
    
        2
  •  0
  •   Mike Driscoll    14 年前

    您可以尝试evt_list_item_right_click。那应该管用。否则,您将希望每次触发选择事件时使用一个标志并检查所述标志,以查看它是否需要查询数据库。还有ultimatelistcrl,一个纯粹的python小部件,您也可以通过黑客来实现这一点。

        3
  •  0
  •   iondiode    14 年前

    可以推入自定义事件处理程序

    import wx
    
    class MyEventHandler(wx.PyEvtHandler):
            def __init__(self,target):
                self.target = target
                wx.PyEvtHandler.__init__(self)
    
            def ProcessEvent(self,event):
                # there must be a better way of getting the event type,
                # but I couldn't find it
                if event.GetEventType() == wx.EVT_LEFT_DOWN.evtType[0]:
                    print "Got Mouse Down event"
                    (item,where) = self.target.HitTest(event.GetPosition())
                    if item != -1:
                        print self.target.GetItem(item,0).GetText()
                        print where
                    else:
                        print "Not on list item though"
                    return True
                else:
                    return False
    
    class MyFrame(wx.Frame):
            def __init__(self, *args, **kwds):
               wx.Frame.__init__(self, *args, **kwds)
               self.list_ctrl_1 = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
               self.myevthandler = MyEventHandler(self.list_ctrl_1)
               sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
               sizer_1.Add(self.list_ctrl_1, 1, wx.EXPAND, 0)
               self.list_ctrl_1.InsertColumn(0,"1")
               self.list_ctrl_1.InsertStringItem(0,"HELLO1")
               self.list_ctrl_1.PushEventHandler(self.myevthandler)
    
    
    if __name__ == "__main__":
        app = wx.PySimpleApp(0)
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None, -1, "")
        app.SetTopWindow(frame_1)
        frame_1.Show()
        app.MainLoop()