0

I am not sure what I am trying to do would be called so I am finding it difficult to find the answer to the following...

I am deleting the contents of a number of tkinter entry widgets. I have four lines that look like I could replace with one line using a loop. I tried ...

for x in range(1, 5):
    self.entryplot_valx.delete(0, tk.END)

but I do not know how to feed the value in... Below is my code - I apologise for stupidity of this question

    self.entryplot_val1.delete(0, tk.END)
    self.entryplot_val2.delete(0, tk.END)
    self.entryplot_val3.delete(0, tk.END)
    self.entryplot_val4.delete(0, tk.END)
Stuart L
  • 47
  • 1
  • 5
  • 6
    It's probably better to redesign your code and make ``self.entryplot_val`` a list or dict. Otherwise, if you always have 4 points, then just write it out as you did in the last code sample in your question and avoid building variable names from variables. [Related](https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) – Mike Scotty Jan 18 '19 at 08:46

4 Answers4

3

You can make this work by changing your loop iterable to a tuple of these four entries:

entries = (self.entryplot_val1,
           self.entryplot_val2,
           self.entryplot_val3,
           self.entryplot_val4)
for x in entries:
    x.delete(0, tk.END)

Since you don't want to create this tuple every time, let's move it into object initialization:

def __init__(self):
    # assuming you have a setup like the following
    master = Tk()
    self.entryplot_val1 = Entry(master)
    self.entryplot_val2 = Entry(master)
    self.entryplot_val3 = Entry(master)
    self.entryplot_val4 = Entry(master)
    # initialize your tuple to use in your for loop
    self.entries = (self.entryplot_val1,
                    self.entryplot_val2,
                    self.entryplot_val3,
                    self.entryplot_val4)
    # some further setup for entries
    self.entryplot_val1.pack()
    self.entryplot_val2.pack()
    self.entryplot_val3.pack()
    self.entryplot_val4.pack()

And then you can simplify this a bit further into:

def __init__(self):
    # assuming you have a setup like the following
    master = Tk()
    self.entries = (Entry(master), Entry(master), Entry(master), Entry(master))
    # some further setup for entries
    for x in self.entries:
        x.pack()

You can then use loops in the form of last example elsewhere in your class code.

Since you removed the previous identifiers for the entries, you would need to change your code to use the new tuple wherever they were used. That is, change references of self.entryplot_val1 to self.entries[0], self.entryplot_val2 to self.entries[1] and so on.

Tugrul Ates
  • 9,451
  • 2
  • 33
  • 59
  • Thanks everyone - I will go with what @Tugrul Ates suggests - it looks the neatest - I have seen the attr approach before and it doesnt sit right. Enjoy your weekends! – Stuart L Jan 18 '19 at 09:15
0

You could solve this creating the attribute name as a string and using getattr(obj, attrname), ie:

for x in range(1, 5):
    attrname = "entryplot_val{}".format(x)
    getattr(self, attrname).delete(0, tk.END)

But really when you find yourself using a "var1", "var2" (...) "varX" naming scheme you probably really want a list instead.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

You can use get_attr() like that:

for x in range(1, 5):
    get_attr(self, "entryplot_val{}".format(x)).delete(0, tk.END)

See this part of the doc.

Cyrlop
  • 1,894
  • 1
  • 17
  • 31
0

You can get the variable names using a string.

for x in range(1, 5):
    attr_name = f'entryplot_val{x}'
    getattr(self, attr).delete(0, tk.END)
John Go-Soco
  • 886
  • 1
  • 9
  • 20