I'm new to Python and all that stuff and currently trying to write some code to analyse some data. I have been stuck for days with a "unimportant" part of a bigger task. For this part I wanted to make three entry fields, where I state the lower (mint), upper bounds(maxt) and an interval(ranget). These should be processed by "plot_range" and give me the result "anz" in Label "lb5" AS I type the numbers how many list entities I would get with these parameters through a calculation of the
I should, according to my current research with google and stuff, use a combination of "trace_add" and "textvariable" to do that, but as I type inside the fields, the callback function is not executed. If I manually set the variables after the tracing is set, it works. Here is the abridged code, I hope it shows what I mean.
...
class RangeWindow:
def __init__(self, data):
self.rw = Tk()
rw = self.rw
self.all_dat = data.copy()
self.mod_dat = []
self.mint = DoubleVar()
self.maxt = DoubleVar()
self.ranget = IntVar()
self.mint.set(self.all_dat[0][1])
self.maxt.set(self.all_dat[-1][1])
self.ranget.set(1)
self.mint.trace_add("write", self.plot_range)
self.maxt.trace_add("write", self.plot_range)
self.ranget.trace_add("write", self.plot_range)
lb1 = Label(rw, text='%s \u00b0C to %s \u00b0C with %s meassurements' % (self.all_dat[0][1], self.all_dat[-1][1], len(self.all_dat)))
lb2 = Label(rw, text="from temp [\u00b0C]")
lb3 = Label(rw, text="to temo [\u00b0C]")
lb4 = Label(rw, text="in range of.")
lb1.grid(row=0, column=1)
lb2.grid(row=1, column=1)
lb3.grid(row=2, column=1)
lb4.grid(row=3, column=1)
self.e1 = Entry(rw, textvariable=self.mint)
self.e2 = Entry(rw, textvariable=self.maxt)
self.e3 = Entry(rw, textvariable=self.ranget)
self.e1.grid(row=1, column=2)
self.e2.grid(row=2, column=2)
self.e3.grid(row=3, column=2)
self.anz = StringVar()
lb5 = Label(self.rw, textvariable=self.anz)
lb5.grid(row=4, column=1)
self.mint.set(100)
rw.mainloop()
def plot_range(self,n, m, o):
...
Thank you very much for any help if you see what the problem is/might be.
Edit:
Shortened code, which somewhat works as I intended is here:
from tkinter import *
# some example-data, which has the same structure as real-data, which is imported beforehand ([[[xdata],[ydata]],temperature] as fat as I know)
def exampledata(cnt):
a = []
b = [[1, 2], [3, 4], [5, 6]]
c = 10
for x in range(cnt):
t = c * (x + 1)
d = [[[j*(x+1) for j in i] for i in b], t]
a.append(d)
return a
class RangeWindow:
def __init__(self):
self.rw = Tk()
rw = self.rw
self.all_dat = exampledata(10)
self.mod_dat = []
self.mint = DoubleVar()
self.maxt = DoubleVar()
self.ranget = IntVar()
self.mint.set(self.all_dat[0][1])
self.maxt.set(self.all_dat[-1][1])
self.ranget.set(1)
self.mint.trace_add("write", self.plot_range)
self.maxt.trace_add("write", self.plot_range)
self.ranget.trace_add("write", self.plot_range)
lb1 = Label(rw, text='%s \u00b0C to %s \u00b0C with %s meassurements' % (self.all_dat[0][1], self.all_dat[-1][1], len(self.all_dat)))
lb2 = Label(rw, text="from temp [\u00b0C]")
lb3 = Label(rw, text="to temo [\u00b0C]")
lb4 = Label(rw, text="in range of.")
lb1.grid(row=0, column=1)
lb2.grid(row=1, column=1)
lb3.grid(row=2, column=1)
lb4.grid(row=3, column=1)
self.e1 = Entry(rw, textvariable=self.mint)
self.e2 = Entry(rw, textvariable=self.maxt)
self.e3 = Entry(rw, textvariable=self.ranget)
self.e1.grid(row=1, column=2)
self.e2.grid(row=2, column=2)
self.e3.grid(row=3, column=2)
self.anz = StringVar()
lb5 = Label(self.rw, textvariable=self.anz)
lb5.grid(row=4, column=1)
self.mint.set(100)
rw.mainloop()
def plot_range(self,n, m, o): # potentially easily doable with list comprehension, but works somewhat as intended, so a third priority
print("started") # something I used to check, if the methode is called, which was only via manual setting of the variables
t1 = self.mint.get()
t2 = self.maxt.get()
n = self.ranget.get()
if not t1 or not t2 or not n:
return
self.mod_dat.clear()
startindex = -1
for i in range(0, len(self.all_dat)):
if t1 <= self.all_dat[i][1] <= t2:
startindex = i
break
if startindex == -1:
return
for i in range(startindex, len(self.all_dat), n):
if t1 <= self.all_dat[i][1] <= t2:
self.mod_dat.append(self.all_dat[i])
else:
break
self.anz.set("Count of measurements will be %s with Tmin %s \u00b0C and Tmax %s \u00b0C " % (len(self.mod_dat), self.mod_dat[0][1], self.mod_dat[-1][1]))
print("done")
gui = RangeWindow()
Edit 2: So I think now that there is the problem with the rest of the code, which is now implemented too:
from tkinter import *
# some hopefully representative example-data, although for this part of the program I only look at t
def exampledata(cnt):
a = []
b = [[1, 2], [3, 4], [5, 6]]
c = 10
for x in range(cnt):
t = c * (x + 1)
d = [[[j*(x+1) for j in i] for i in b], t]
a.append(d)
return a
class MainWindow:
def __init__(self):
self.mw = Tk()
mw = self.mw
mw.geometry("100x100")
openbut = Button(mw, text='Open', command=self.openfile)
openbut.grid(row=0, column=0, sticky=W, pady=4)
self.mess_dat = []
mw.mainloop()
def openfile(self): # shortened with the example-data
self.mess_dat = exampledata(10)
rangegui = RangeWindow(self.mess_dat)
class RangeWindow:
def __init__(self,data):
self.rw = Tk()
rw = self.rw
self.all_dat = data
self.mod_dat = []
self.mint = DoubleVar()
self.maxt = DoubleVar()
self.ranget = IntVar()
self.mint.set(self.all_dat[0][1])
self.maxt.set(self.all_dat[-1][1])
self.ranget.set(1)
self.mint.trace_add("write", self.plot_range)
self.maxt.trace_add("write", self.plot_range)
self.ranget.trace_add("write", self.plot_range)
lb1 = Label(rw, text='%s \u00b0C to %s \u00b0C with %s meassurements' % (self.all_dat[0][1], self.all_dat[-1][1], len(self.all_dat)))
lb2 = Label(rw, text="from temp [\u00b0C]")
lb3 = Label(rw, text="to temo [\u00b0C]")
lb4 = Label(rw, text="in range of.")
lb1.grid(row=0, column=1)
lb2.grid(row=1, column=1)
lb3.grid(row=2, column=1)
lb4.grid(row=3, column=1)
self.e1 = Entry(rw, textvariable=self.mint)
self.e2 = Entry(rw, textvariable=self.maxt)
self.e3 = Entry(rw, textvariable=self.ranget)
self.e1.grid(row=1, column=2)
self.e2.grid(row=2, column=2)
self.e3.grid(row=3, column=2)
self.anz = StringVar()
lb5 = Label(self.rw, textvariable=self.anz)
lb5.grid(row=4, column=1)
self.mint.set(100)
rw.mainloop()
def plot_range(self,n, m, o):
print("started")
t1 = self.mint.get()
t2 = self.maxt.get()
n = self.ranget.get()
if not t1 or not t2 or not n:
return
self.mod_dat.clear()
startindex = -1
for i in range(0, len(self.all_dat)):
if t1 <= self.all_dat[i][1] <= t2:
startindex = i
break
if startindex == -1:
return
for i in range(startindex, len(self.all_dat), n): # neue Liste mit den Werten im Bereich wird erstellt
if t1 <= self.all_dat[i][1] <= t2:
self.mod_dat.append(self.all_dat[i])
else:
break
self.anz.set("Count of measurements will be %s with Tmin %s \u00b0C and Tmax %s \u00b0C " % (len(self.mod_dat), self.mod_dat[0][1], self.mod_dat[-1][1]))
print("done")
gui = MainWindow()
I hope it makes sense, as shown here. In comparison to the minimal example it doesn't call the method when writing in the entries and it doesn't even show the label lb5. I have a feeling it has to do something with the "mainlooping" although, if I simply use textvariable to transfer the entries to a lable it works, so that should not be the problem. So I would be happy, if anyone has any ideas, what the problem might be.