Python Forum

Full Version: How to change a tkinter label with scale and how to save that new value for later?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I've been building and ROV for a while now and made a pretty sweet GUI first with Arduino IDE, then with MATLAB, everything worked great. I upgraded to a Raspberry Pi 5 and now I want to make the same GUI with python but I'm pretty new with python, so bear with me.

Here's what I want to do and nothing I can think of is fixing the problem, my code is below. I want to have a tkinter scale from 0 to 100, then I want to convert those values to a pwm signal, so 1100 to 1900. I have five sliders that all do the same thing, one light intensity, forward thrust, reverse thrust, ascend, and descend thrust. As you adjust the slider I want a label that notifies the user on how fast they are going. These values are meant to be limits for the thruster, so if you set the scale to 80 its converted to a pwm signal of 1740 and now the forward thrusters can only recieve a pwm signal of 1500 to 1740 . Hopefully all of that makes sense.

Here's the problem, I have my labels set to specific values of the slider, when I slide back and forth the labels show up but I cant them to go away when the value changes. Instead they overall and I cant figure out how to get rid of them. I'll figure out the rest of these things later. Any ideas? Thanks!

       def ascend_thruster_modification(self):
               thrust_mid = 1500
               thrust_ascend_var = round(ascend_scale_int.get())
               new_thrust_ascend_var = (thrust_ascend_var/100)*400
               final_thrust_forward_var = new_thrust_ascend_var + thrust_mid

              if thrust_ascend_var == 0:
                    forward_label1 = ttk.Label(vic_settings_frame, text = 'Off')
                    forward_label1.place(relx = .24, rely = .23)
         
              if 1 <= thrust_ascend_var <= 50:
                    forward_label1 = ttk.Label(vic_settings_frame, text = 'Low Speed')
                    forward_label1.place(relx = .24, rely = .23)

              if 51 <= thrust_ascend_var <= 75:
                    forward_label1 = ttk.Label(vic_settings_frame, text = 'High Speed')
                    forward_label1.place(relx = .24, rely = .23)

              if thrust_ascend_var >= 76:
                    forward_label1 = ttk.Label(vic_settings_frame, text = 'Maximum Speed')
                    forward_label1.place(relx = .24, rely = .23)

    forward_scale_int = tk.IntVar(value = 100)
    thrust_forward_scale = ttk.Scale(vic_settings_frame, from_ = 0, to = 100, length = 300, orient = 'horizontal', variable = forward_scale_int, command = forward_thruster_modification)
    
    forward_text = ttk.Label(vic_settings_frame, text = 'Forward Thruster Speed Settings')
    forward_label = ttk.Label(vic_settings_frame, text = 'Current Forward Thruster Speed: ')

    forward_text.place(relx = .03, rely = .16)
    forward_label.place(relx = .03, rely = .23)
    thrust_forward_scale.place(relx = .03, rely = .19)  
idk why but some of my indentations are weird and I cant figure out how to change them. The labels and scale bar are not part of the function. All of this is part of a larger function. Thanks!
Idk why this isnt working for me. My indentations keep reverting back to all the way left, the labels and scale are not part of the function, the scale calls the function.
A basic example of changing label text with a slider

import tkinter as tk

root = tk.Tk()

def show(event):
    value = slider.get()
    label.config(text=f'Speed: {value}')

label = tk.Label(root, text='Speed: 0', anchor='w')
label.pack(fill='x')

slider = tk.Scale(root, from_=0, to=100, orient='horizontal', command=show)
slider.pack()

root.mainloop()
I would make a new widget that combines the scale widget with the label. Something like this:
import tkinter as tk
 
 
class Slider(tk.Frame):
    """A Scale widget with a label that displays the power range of the slider. Also converts slider to PWM."""
  
    default_table = ((1, "Off"), (51, "Low Speed"), (76, "High Speed"), (0, "Maximum Speed"))

    def __init__(self, parent, title, width=200, command=None, table=None, rmin=1100, rmax=1900):
        super().__init__(parent, width=width)
        self.command = command
        self.table = table or default_table
        self._rmin = rmin
        self._rmax = rmax
        self._title = tk.Label(self, text=title)
        self._label = tk.Label(self, text=self.table[0][1])
        self._thrust = tk.DoubleVar(self, 0)
        self._slider = tk.Scale(
            self,
            variable=self._thrust,
            orient=tk.HORIZONTAL,
            from_=0,
            to=100,
            command=self._slider_changed,
            length=width,
        )
        self._title.grid(row=0, column=0, sticky="W")
        self._label.grid(row=0, column=1, sticky="E")
        self._slider.grid(row=1, column=0, columnspan=2, sticky="EW")
 
    def title(self):
        """Return title str."""
        return self._title["text"]

    def label(self):
        """Return label str."""
        return self._label["text"]

    @property
    def thrust(self):
        """Return thrust value for label."""
        return self._thrust.get()
 
    @thrust.setter
    def thrust(self, new_value):
        """Set thrust value."""
        self._thrust.set(new_value)
 
    def pwm(self):
        """Return thrust setting as PWM"""
        return int(self._rmin + self._rmax - self._rmin * self.thrust / 100)
 
    def _slider_changed(self, _):
        """Slider moved.  Update label and call callback."""
        thrust = self._thrust.get()
        for level, new_text in self.table:
            if thrust < level:
                break
        self._label["text"] = new_text
        if self.command is not None:
            self.command(self.pwm())
 
    def __str__(self):
        return f"<Slider {self.title()}, slider = {self.thrust}, power = {self.label()}, pwm = {self.pwm()}"
 
 
class MainWindow(tk.Tk):
    """Demonstrate making sliders."""
 
    def __init__(self):
        super().__init__()
        for name in ("light", "forward", "reverse", "ascend", "descend"):
            slider = Slider(self, name)
            slider.command = lambda x, y=slider: print(y)
            slider.pack(side=tk.TOP, padx=10, pady=10)
 
 
MainWindow().mainloop()