0

Admittedly, I have a hard time with object oriented anything. So I don't quite understand the self declarations all over the place. That said, I have a panel with a number of the same types of widgets.

Is there a way to have a generic function receive a widget as an argument?

I'd like the function at the bottom to receive arguments from the self.Bind, specifically, can I pass self.sliderZone1 and self.tc_ZONEVOL1 into the def?

I'd like the def slider1Update to look something like this:

def sliderUpdate(self, event, slider, textctrl):
    textctrl.SetValue(str(slider.GetValue())

Is that possible?

Psuedo-code:

 self.ck_ZONE1 = wx.CheckBox(self, -1, zoneNAME[0])
    self.ck_ZONE1.SetToolTip(wx.ToolTip("Click here to monitor volume for this zone."))

    self.tc_ZONEVOL1 = wx.TextCtrl(panel, -1, "", (0,0), (30,21))
    self.tc_ZONEVOL1.SetToolTip(wx.ToolTip("Set max volume for the zone (0-100)"))

    self.sliderZone1 = wx.Slider(self, -1, 50, 0, 100, size=(400,10), style=wx.SL_HORIZONTAL)
    self.Bind(wx.EVT_SLIDER, self.slider1Update)

    sizer.Add(self.ck_ZONE1, pos=(xIndex,0), flag=wx.EXPAND|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=10)
    sizer.Add(self.sliderZone1, pos=(xIndex,1), flag=wx.EXPAND|wx.LEFT|wx.ALIGN_CENTER_VERTICAL, border=10)
    sizer.Add(self.tc_ZONEVOL1, pos=(xIndex,2), flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, border=10).SetMinSize((30,22))

    # Read in config
    if self.ck_ZONE1.Label == "":
        self.ck_ZONE1.Label = zoneNAME[0]

    if self.tc_ZONEVOL1.Value == "":
        self.tc_ZONEVOL1.SetValue(str(self.sliderZone1.GetValue()))

    xIndex +=1


    pub.subscribe(self.setVolumePanel, 'setVolumePanel')
    sizer.AddGrowableCol(1)
    panel.SetSizer(sizer)

def slider1Update(self, event):
    self.tc_ZONEVOL1.SetValue(str(self.sliderZone1.GetValue()))
chow
  • 484
  • 2
  • 8
  • 21
  • I don't quite have the energy to post a full answer, but check out [this answer](http://stackoverflow.com/questions/173687/is-it-possible-to-pass-arguments-into-event-bindings) for how to pass arguments into event bindings. You're going to need a lambda function. – dpwilson Apr 25 '16 at 19:50

2 Answers2

1

Actually, there's no need to pass those in if you make them class variables, which is what the self. means. The way you have it currently coded should work just fine:

def slider1Update(self, event):
    self.tc_ZONEVOL1.SetValue(str(self.sliderZone1.GetValue()))

That's actually the usual way of doing what you want to do. But if you want to pass them, you would do something like this:

self.tc_ZONEVOL1 = wx.TextCtrl(panel, -1, "", (0,0), (30,21))
self.sliderZone1 = wx.Slider(self, -1, 50, 0, 100, size=(400,10),
                         style=wx.SL_HORIZONTAL)

self.Bind(wx.EVT_SLIDER,lambda event: self.sliderUpdate(
     event, self.sliderZone1, self.tc_ZONEVOL1,), self.sliderZone1)

Then your event handler would look the same way you mentioned:

def sliderUpdate(self, event, slider, textctrl):
    textctrl.SetValue(str(slider.GetValue())

This is covered on the wxPython wiki here:

It actually mentions another good way to do this using functools.partial that you might like too.

Mike Driscoll
  • 32,629
  • 8
  • 45
  • 88
  • Awesome -- this works great -- thank you so much. It did work the way it was, but it is the same generic event across 9 sliders and 9 textctrls, so if I can have two functions to make that work, then it is easier for me to debug. – chow Apr 28 '16 at 00:48
0

To get the object that fired the event, you can also use event.GetObject(), like so:

def slider1Update(self, event):
    self.tc_ZONEVOL1.SetValue(str(event.GetObject().GetValue()))

The wx.EVT_SLIDER event also carries the value, so you can also use that.

def slider1Update(self, event):
    self.tc_ZONEVOL1.SetValue(str(event.GetInt()))
10se1ucgo
  • 71
  • 1
  • 9