Pregunta

Estoy trabajando en un formulario utilizando wxPython donde quiero lista de falta de listctrl de los valores a cambios basados ??en la selección de otro listctrl. Para hacer esto, estoy usando métodos vinculados a acontecimientos EVT_LIST_ITEM_SELECTED y EVT_LIST_ITEM_DESELECTED del objeto de control a Publisher.sendMessage llamada. El control que ser cambiado tiene un método que es un abonado al que el editor. Estos trabajos:. Cuando se hace clic la primera listctrl, el segundo se actualiza

El problema es que los datos se deben actualizar la base de datos y se envía un mensaje para cada selección y deselección. Esto significa que incluso si simplemente hacer clic en un elemento, la base de datos consultadas consigue dos veces (una vez para la anulación de la selección, luego de nuevo para la selección). Si la tecla Mayús para seleccionar varios artículos 5, a continuación, 5 llamadas se envían. ¿Hay alguna manera de recibir la respuesta del listctrl al conjunto, en lugar de las selecciones individuales?

¿Fue útil?

Solución

La mejor solución parece ser el uso de wx.CallAfter con una bandera para ejecutar el procedimiento de seguimiento exactamente una vez:

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

Otros consejos

Puede intentar EVT_LIST_ITEM_RIGHT_CLICK. Eso debería funcionar. De lo contrario, querrá usar una bandera y comprobar dicho indicador cada vez que se activa el evento de selección para ver si se necesita consultar la base de datos o no. También existe la UltimateListCtrl, un widget pura pitón, que es probable que pueda piratear a hacer esto también.

Se puede empujar en un controlador de eventos personalizado

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()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top