'Error "takes 1 positional argument but 2 were given" when Tkinter slider callback

I am trying to use Tkinter sliders and buttons to adjust variables. Somehow when I move the slider, it gives this error message below. I have self on each of the callback functions. So, that can't be it.

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\aksk1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
TypeError: X_voltage_adjust() takes 1 positional argument but 2 were given

I don't know why this would happen. I tried everything I know how to. This is the code here. Thank you in advance.

class GalvoControlFrame(ttk.Labelframe):
    def __init__(self, parent):
        ttk.Labelframe.__init__(self, parent, text="Galvo Control")
        self.parent = parent
        self.master = parent.parent.master
        self.ao_found = self.master.ao_found
        # self.master.board_num

        ############ Voltage X ############
        Label(self, text="Galvo X").grid(row=0, column=1, columnspan=2)

        self.sliderX = Scale(self, orient=HORIZONTAL,
                    sliderlength=10, 
                    resolution=0.0001,
                    length=300,
                    from_=ULRange.BIP5VOLTS.range_min,
                    to=ULRange.BIP5VOLTS.range_max,
                    command=self.X_voltage_adjust)
        self.sliderX.grid(row = 1, column=1, columnspan=2)

        self.dec_button = Button(self, text="<---Decrease",
                                command=lambda:self.decrease_voltage(0))
        self.dec_button.grid(row=2, column=1)

        self.inc_button = Button(self, text="Increase--->", 
                                command=lambda:self.increase_voltage(0))
        self.inc_button.grid(row=2, column=2)

        ############ Voltage Y ############
        Label(self, text="Galvo Y").grid(row=3, column=1, columnspan=2)

        self.sliderY = Scale(self, orient=HORIZONTAL,
                    sliderlength=10, 
                    resolution=0.0001,
                    length=300,
                    from_=ULRange.BIP5VOLTS.range_min,
                    to=ULRange.BIP5VOLTS.range_max,
                    command=self.Y_voltage_adjust)
        self.sliderY.grid(row = 4, column=1, columnspan=2)

        self.dec_button = Button(self, text="<---Decrease", 
                                command=lambda:self.decrease_voltage(1))
        self.dec_button.grid(row=5, column=1)

        self.inc_button = Button(self, text="Increase--->", 
                                command=lambda:self.increase_voltage(1))
        self.inc_button.grid(row=5, column=2)

        VALUE_OPTIONS = [
            1,
            0.1,
            0.01,
            0.001,
            0.0001
        ]

        self.value_option = DoubleVar(self)
        self.value_option.set(0.0)
        options = OptionMenu(self, self.value_option, *VALUE_OPTIONS)
        options.config(width=20)
        options.grid(row=2, column=3, columnspan=2)

    def X_voltage_adjust(self):
        print(self.sliderX.get())
        if self.ao_found:
            dc.DAQ_AO_channel(self.master.DAQ_board_num, 0, self.sliderX.get() / 2.0)

    def Y_voltage_adjust(self):
        print(self.sliderY.get())
        if self.ao_found:
            dc.DAQ_AO_channel(self.master.DAQ_board_num, 1, self.sliderY.get() / 2.0)

    def decrease_voltage(self, number):
        if number == 0:
            new_val = self.sliderX.get() - self.value_option.get()
            if new_val < ULRange.BIP5VOLTS.range_min:
                new_val = ULRange.BIP5VOLTS.range_min
            self.sliderX.set(new_val)
            # if self.ao_found:
            #     dc.DAQ_AO_channel(self.master.DAQ_board_num, 0, self.sliderX.get() / 2.0)
        elif number == 1:
            new_val = self.sliderY.get() - self.value_option.get()
            if new_val < ULRange.BIP5VOLTS.range_min:
                new_val = ULRange.BIP5VOLTS.range_min
            self.sliderY.set(new_val)
            # if self.ao_found:
            #     dc.DAQ_AO_channel(self.master.DAQ_board_num, 1, self.sliderY.get() / 2.0)

    def increase_voltage(self, number):
        if number == 0:
            new_val = self.sliderX.get() + self.value_option.get()
            if new_val < ULRange.BIP5VOLTS.range_min:
                new_val = ULRange.BIP5VOLTS.range_min
            self.sliderX.set(new_val)
            # if self.ao_found:
            #     dc.DAQ_AO_channel(self.master.DAQ_board_num, 0, self.sliderX.get() / 2.0)
        else:
            new_val = self.sliderY.get() + self.value_option.get()
            if new_val < ULRange.BIP5VOLTS.range_min:
                new_val = ULRange.BIP5VOLTS.range_min
            self.sliderY.set(new_val)
            # if self.ao_found:
            #     dc.DAQ_AO_channel(self.master.DAQ_board_num, 1, self.sliderY.get() / 2.0)
    ```


Solution 1:[1]

A tkinter Scale can return its current value to the function called in the "command" kwarg. This is the second argument that python is getting confused about. You can add it to your function like so: def X_voltage_adjust(self, value): for example.

A simple example of this behavior:

from tkinter import Tk, DoubleVar, Scale, CENTER, Label
    
def sel(a):
    print(a)
    selection = "Value = " + str(var.get())
    label.config(text=selection)
    
root = Tk()
var = DoubleVar()
scale = Scale(root, variable=var, command=sel)
scale.pack(anchor=CENTER)

label = Label(root)
label.pack()

root.mainloop()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mandias