tkinter中的变量跟踪不起作用

2024-10-03 06:30:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我不熟悉Python和所有这些东西,目前正试图编写一些代码来分析一些数据。 我已经被一项更大任务中“不重要”的部分困住了好几天。对于这一部分,我想创建三个输入字段,其中我声明了下限(mint)、上限(maxt)和间隔(ranget)。这些应通过“plot_range”进行处理,并在我键入数字时在标签“lb5”中给出结果“anz”,通过计算

根据我目前在google和stuff的研究,我应该使用“trace_add”和“textvariable”的组合来实现这一点,但当我在字段中键入时,回调函数不会执行。如果我在设置跟踪后手动设置变量,它就会工作。 这是简略的代码,我希望它能说明我的意思

... 
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):
...

如果您发现问题所在,非常感谢您的帮助

编辑:

下面是一些我想要的代码的缩写:

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()

编辑2:所以我认为代码的其余部分存在问题,现在也实现了:

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()


我希望这是有意义的,如图所示。与最小示例相比,它在写入条目时不调用方法,甚至不显示标签lb5。我有一种感觉,它必须与“mainlooping”有关,不过,如果我只是简单地使用textvariable将条目传输到一个标签上,它就会工作,所以这应该不是问题所在。 所以我很高兴,如果有人有任何想法,问题可能是什么


Tags: selfrangecolumnalllabelgriddatrow
1条回答
网友
1楼 · 发布于 2024-10-03 06:30:08

问题是由于创建了多个Tk实例。您几乎不应该创建Tk的第二个实例-在一个实例中创建的小部件和变量在任何其他实例中都不可见。第二个和后续窗口应使用Toplevel创建

此外,您不应该多次调用mainloop

有关更多信息,请参见Why are multiple instances of Tk discouraged?

相关问题 更多 >