0

Please help! I am writing a program in Python using the Spyder IDE. I am using tkinter. My program contains multiple Scale widgets that have been working fine and independently as I would like. However, two scales now seem to depend on each other since their var parameters (which are separate variables) are initialized to the same value.

I made a simplified tkinter program to illustrate the issue. This code is designed to mimic the structure of my actual project - so it may not look as efficient as it could. Two separate scales are made, with separate variables, and separate update commands. When the two global variables are both initialized as the same value, the scales depend on each other and both move when only one is manipulated. When the two global variables are initialized as different values, the scales work fine and as expected.

Why is this happening? I need both of the global variables in my actual project to be the same value. How can I make this work?

Here is the code:

import tkinter as tk
from tkinter import ttk

global firstvalue
global secondvalue

firstvalue = 1000
secondvalue = 1000

class ScaleTest(tk.Tk):

    def __init__(self, *args, **kwargs):

        # Creates tkinter window and container for frames
        tk.Tk.__init__(self, *args, **kwargs)  
        tk.Tk.wm_title(self, "Scale Test")     
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        # Add ScaleTestFrame frame to container and show the frame
        self.frames = {}
        frame = ScaleTestFrame(container, self)
        self.frames[ScaleTestFrame] = frame
        frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(ScaleTestFrame)

    # Method to show the input frame.
    def show_frame(self, cont):
        self.deiconify() # Show main tkinter window
        frame = self.frames[cont]
        frame.tkraise()

# Class that defines the frame to display the algorithm creation parameters.
class ScaleTestFrame(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        MakeFirstScale(self)
        MakeSecondScale(self)

# Methods for scales
def FirstScaleUpdate(event):
    global firstvalue
    firstvalue = int(float(event))  

def MakeFirstScale(self):    
    self.first_scale = tk.Scale(self, from_=0, to=5000, resolution = 10, var = firstvalue, orient=tk.HORIZONTAL, length = 360, label = "First Scale", command = FirstScaleUpdate)
    self.first_scale.grid(row = 1, rowspan = 2, column=0, columnspan=10, sticky='wes', padx = 10, pady = (0,10))
    self.first_scale.set(1000)

def SecondScaleUpdate(event):
    global secondvalue
    secondvalue = int(float(event))  

def MakeSecondScale(self):    
    self.second_scale = tk.Scale(self, from_=0, to=2000, resolution = 10, var = secondvalue, orient=tk.HORIZONTAL, label = "Second Scale", command = SecondScaleUpdate)
    self.second_scale.grid(row = 3, rowspan = 2, column=0, columnspan=4, sticky='wes', padx = 10, pady = (0,10))
    self.second_scale.set(1000)

app = ScaleTest()
app.resizable(0,0)
app.mainloop()
Susi
  • 63
  • 7
  • 1
    The `variable=` or similar options of various Tkinter widgets *must* be one of the specific Tkinter variable types: `IntVar`, `StringVar`, etc. Ordinary Python variables do not have the needed ability to trigger actions when they are changed. – jasonharper Jun 11 '20 at 14:19
  • @jasonharper Oh okay, thank you. Why do the ordinary python variables work when they are set to different values? – Susi Jun 11 '20 at 14:22
  • 1
    Ordinary Python variables don't actually work - if you pass one where a Var is needed, its *value* at that moment in time gets interpreted as the name of a variable in the Tcl environment where the GUI actually lives. If two variables had the same value, they are treated as referring to the same Var, and the widgets are stuck together, as you saw. If they had different values, they refer to separate Vars, and the widgets can be operated independently - but this isn't actually *working*, as you have no way to set or get the values of those Vars. – jasonharper Jun 11 '20 at 14:33
  • @jasonharper That is very helpful! Thank you for the explanation. How do I mark it as you answering the question? – Susi Jun 11 '20 at 15:42

0 Answers0