Yuri R. Tonin
Yuri R. Tonin

Reputation: 49

Tkinter - Give name of variable option of a Scale through a class

I am starting to learn OOP and I've been struggling with some basic stuff.

In the code below, I have created a class Scales() that I want to use to create 2 very similar scales, with only their variable option being different.

How can I pass the name of these variables as a parameter when I call Scales() and make both of them a DoubleVar type?

from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
import numpy as np

class Scales(Frame):
    def __init__(self, parent, variable_name, label_text, initial_value,
                 final_value):

        self.parent        = parent
        self.bar_length    = 200
        self.variable_name = variable_name
        self.label_text    = label_text
        self.initial_value = initial_value
        self.final_value   = final_value

        # self.variable_name = DoubleVar()

        self.scale_name = Scale(self.parent, variable=self.variable_name,
                                orient=HORIZONTAL,
                                from_=self.initial_value,
                                to=self.final_value,
                                length=self.bar_length, cursor="hand",
                                label=self.label_text)


class MainApplication(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.slice_number_scale = Scales(self.parent, slice_number,
                                         "Slice Number", 1, 24)


if __name__ == '__main__':
    root = Tk()
    root.geometry("800x600")
    MainApplication(root)
    root.mainloop()

Upvotes: 0

Views: 836

Answers (2)

martineau
martineau

Reputation: 123481

Just create the variables in each Scale class instance that is created, then access them through the instance's name. Here's what I mean:

from tkinter import *
#from tkinter import ttk
#from PIL import Image, ImageTk
#import numpy as np

class Scale(Frame):
    """ Dummy version of class for testing and illustration. """
    def __init__(self, parent, orient=None, from_=None, to=None, length=None,
                 cursor=None, label=None):
        Frame.__init__(self, parent)  # initialize base class
        self.variable = DoubleVar()  # create variable and make attribute


class Scales(Frame):
    def __init__(self, parent, label_text, initial_value,
                 final_value):

        self.parent        = parent
        self.bar_length    = 200
#        self.variable_name = variable_name
        self.label_text    = label_text
        self.initial_value = initial_value
        self.final_value   = final_value

#        self.variable_name = DoubleVar()

        self.scale1 = Scale(self.parent,
#                            variable=self.variable_name,
                            orient=HORIZONTAL,
                            from_=self.initial_value,
                            to=self.final_value,
                            length=self.bar_length,
                            cursor="hand",
                            label=self.label_text)

        self.scale1.pack()


class MainApplication(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        slice_number = 42
        self.slice_number_scale = Scales(self.parent, slice_number, 1, 24)

root = Tk()
app = MainApplication(root)
app.mainloop()

After doing this you can access the variable for each Scale instance within a Scales instance as self.scale1.variable (and self.scale2.variable after you add it). Within the MainApplication instance they can be referred to as self.slice_number_scale.scale1.variable (and self.slice_number_scale2.variable).

For the latter you might want to add methods to class MainApplication to make such references more succinct, such as:

class MainApplication(Frame):
       ....
    def get_scale_var1(self):
        return self.slice_number_scale.scale1.variable.get()

Upvotes: 1

jasonharper
jasonharper

Reputation: 9597

If the variables are going to live as instance variables of your Scales class, then there's absolutely no reason to give them separate names; every reference to them is going to be in the context of some particular instance. You'd probably want to define a get() method that does something like return self.variable.get(), for the convenience of the class's user.

If the variables live somewhere outside the class, then Scales should not care what their names are; pass the variable itself as a parameter to the class constructor, and pass it on as the variable= option to Scale().

Upvotes: 2

Related Questions