Question

Je travaille sur un formulaire en utilisant wxPython où je veux la liste des valeurs besoin listctrl changer en fonction de la sélection d'un autre listctrl. Pour ce faire, je suis en utilisant des méthodes liées à l'EVT_LIST_ITEM_SELECTED de l'objet de contrôle et les événements EVT_LIST_ITEM_DESELECTED à l'appel Publisher.sendMessage. Le contrôle à modifier a une méthode qui est un abonné à cet éditeur. Cela fonctionne. Lorsque le premier listctrl est cliqué, le second est rafraîchi

Le problème est que les données doivent être mises à jour de la base de données et un message est envoyé pour chaque désélection et sélection. Cela signifie que même si je vous suffit de cliquer sur un élément, la base de données est deux fois interrogés (une fois pour la désélection, puis de nouveau pour la sélection). Si je touche Maj enfoncée pour sélectionner plusieurs éléments 5, puis 5 appels sont faits. Est-il possible d'avoir la listctrl répondent à l'ensemble, plutôt que les sélections individuelles?

Était-ce utile?

La solution

La meilleure solution semble être d'utiliser wx.CallAfter avec un drapeau pour exécuter exactement une fois la procédure de suivi:

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()

Autres conseils

Vous pouvez essayer EVT_LIST_ITEM_RIGHT_CLICK. Cela devrait fonctionner. Sinon, vous voudriez utiliser un drapeau et vérifier ledit drapeau chaque fois que l'événement se déclenche de sélection pour voir si elle a besoin d'interroger la base de données ou non. Il y a aussi le UltimateListCtrl, un widget pur python, que vous pouvez probablement pirater le faire aussi.

Vous pouvez pousser dans un gestionnaire d'événements personnalisé

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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top