Search code examples
pygobject

Get the change on value-changed (GTK.SpinButton)


Is there a way to see how much a SpinButton has changed when receiving the value-changed signal?

I'm trying to implement a linked set of SpinButtons, where a change in one will result in a change in all of them. I don't want them to be the same value, but to have the same delta (i.e. increment once on one SpinButton will result in an increment on the other SpinButtons).

I can't seem to come up with anything except possibly tracking the values in the background (perhaps triggered by a focus event or something), and then calculating the delta myself. Is that pretty much the only way?


Solution

  • The only way of doing this it is by calculating the delta as you said. Here you have an example:

    from gi.repository import Gtk
    
    class Spins(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self)
    
            self.connect("destroy", lambda q: Gtk.main_quit())
    
            box=Gtk.VBox()
    
            self.sp1_val=5
            self.sp2_val=15
    
            adjustment1 = Gtk.Adjustment(value=self.sp1_val, lower=-10, upper=2500, step_increment=5, page_increment=5, page_size=0)
            self.spinbutton1 = Gtk.SpinButton(adjustment=adjustment1)
            self.spinbutton1.connect('value-changed', self.on_spinbutton_1_changed)
    
            adjustment2 = Gtk.Adjustment(value=self.sp2_val, lower=-10, upper=2500, step_increment=15, page_increment=5, page_size=0)
            self.spinbutton2 = Gtk.SpinButton(adjustment=adjustment2)
            self.spinbutton2.connect('value-changed', self.on_spinbutton_2_changed)
    
            box.add(self.spinbutton1)
            box.add(self.spinbutton2)
            self.add(box)
            self.show_all()
    
    
        def on_spinbutton_1_changed(self, widget, data=None):
            current_value=self.spinbutton1.get_value()
            delta=(current_value-self.sp1_val)
            self.sp1_val=current_value
            self.sp2_val+=delta
            self.spinbutton2.set_value(self.sp2_val)
    
        def on_spinbutton_2_changed(self, widget, data=None):
            current_value=self.spinbutton2.get_value()
            delta=(current_value-self.sp2_val)
            self.sp2_val=current_value
            self.sp1_val+=delta
            self.spinbutton1.set_value(self.sp1_val)
    
    spins=Spins()
    Gtk.main()
    

    I believe that if you do it in any other way, you will enter trough infinite loop and you will always reach the maximum of the adjustments. Why? Because the value-changed signal tracks when a value have been changed whether it be the program or the user. So if you manually modify spinbutton1 you activateon_spinbutton_1_changed, so it modifies spinbutton2, and it activates on_spinbutton_2_changed that modifies spinbutton1. You see the infinite loop? This is why you need to store self.sp1_val and self.sp2_val.