首页 > 解决方案 > 如何在类的递归方法中使用参数

问题描述

我正在尝试准备一个 tkinter 帧以显示不同传感器的一些值。我会使用 Class 对象来重用代码,放置每个传感器的特定参数。以下是我的部分代码:

代码有效,我得到一个标签,其值在常规基础上更新,但我只会创建类 LabelScreen 的实例,其中包含作为参数传递的不同文本和值。

class LabelScreen1():
    def __init__(self, parent, text_label, string_var):
        self.string_var = string_var
        larghezza_titolo = 19
        larghezza_labels = 5
        altezza_labels = 2        
        imb_pulsantey = int(1*h)        
        imb_pulsantex = int(1.5*w) 

        self.labelA = tk.Label(
            labels_frame,
            text = "fff",

            width = larghezza_labels,
            height = altezza_labels,
            highlightthickness=2,
            highlightcolor="DodgerBlue2",
            highlightbackground='DodgerBlue2',
            font= ('ObliviousFont',int(h*5)),
            fg="DodgerBlue2",
            background = "gray3",
            pady = imb_pulsantey,
            padx = imb_pulsantex
            )

        self.labelA.place(x=int(w*10), y=int(h*10))

        self.labelA_title = tk.Label(
            labels_frame,
            text = text_label,

            width = larghezza_titolo,
            font= ('ObliviousFont',int(h*1.5)),
            fg="DodgerBlue2",
            background = "gray3",
            )

        self.labelA_title.place(in_=self.labelA, relx=.5, y=int(h*2),anchor="c")        
        self.update_label()

    def update_label(self):        
        self.labelA.configure(text=self.string_var.get())#prex_hot)
        self.labelA.after(1000, self.update_label)

class LabelScreen2():
    def __init__(self, parent, text_label):
        larghezza_titolo = 19
        larghezza_labels = 5
        altezza_labels = 2        
        imb_pulsantey = int(1*h)        
        imb_pulsantex = int(1.5*w) 


        self.labelA = tk.Label(
            labels_frame,
            text = "fff",
            width = larghezza_labels,
            height = altezza_labels,
            highlightthickness=2,
            highlightcolor="DodgerBlue2",
            highlightbackground='DodgerBlue2',
            font= ('ObliviousFont',int(h*5)),
            fg="DodgerBlue2",
            background = "gray3",
            pady = imb_pulsantey,
            padx = imb_pulsantex
            )

        self.labelA.place(x=int(w*30), y=int(h*10))

        self.labelA_title = tk.Label(
            labels_frame,
            text = text_label,
            width = larghezza_titolo,
            font= ('ObliviousFont',int(h*1.5)),
            fg="DodgerBlue2",
            background = "gray3",
            )

        self.labelA_title.place(in_=self.labelA, relx=.5, y=int(h*2),anchor="c")        
        self.update_label()

    def update_label(self):        
        self.labelA.configure(text=temp1)
        self.labelA.after(1000, self.update_label)

class LabelScreen3():
    def __init__(self, parent, text_label):
        larghezza_titolo = 19
        larghezza_labels = 5
        altezza_labels = 2        
        imb_pulsantey = int(1*h)        
        imb_pulsantex = int(1.5*w) 


        self.labelA = tk.Label(
            labels_frame,
            text = "fff",
            borderwidth=int(h*0.3),            
            width = larghezza_labels,
            height = altezza_labels,
            highlightthickness=2,
            highlightcolor="DodgerBlue2",
            highlightbackground='DodgerBlue2',
            font= ('ObliviousFont',int(h*5)),
            fg="DodgerBlue2",
            background = "gray3",
            pady = imb_pulsantey,
            padx = imb_pulsantex
            )

        self.labelA.place(x=int(w*50), y=int(h*10))

        self.labelA_title = tk.Label(
            labels_frame,
            text = text_label,
            width = larghezza_titolo,
            font= ('ObliviousFont',int(h*1.5)),
            fg="DodgerBlue2",
            background = "gray3",
            )

        self.labelA_title.place(in_=self.labelA, relx=.5, y=int(h*2),anchor="c")        
        self.update_label()

    def update_label(self):        
        self.labelA.configure(text=temp2)
        self.labelA.after(1000, self.update_label)

def change_value_randomly(string_var):
    import time
    import random

    while True:
        #string_var.set(random.randint(-10, 10))
        string_var.set(prex_hot)
        time.sleep(1)

radice = tk.Tk()

H=int(radice.winfo_screenheight())
W=int(radice.winfo_screenwidth())
h=int(H/100)
w=int(W/100)
prex_hot=tk.StringVar()

t = threading.Thread(target=change_value_randomly, args=(prex_hot,))
t.start()
screen_resolution = str(W)+'x'+str(H)
radice.geometry(screen_resolution)
labels_frame = tk.Frame(
            radice, background = "black")

labels_frame.pack(fill=tk.BOTH, expand=True)
#labels_frame.pack_propagate(0)
#radice.overrideredirect(1)
label1 = LabelScreen1(radice, "PRESSURE HOT WATER", prex_hot)
label2 = LabelScreen2(radice, "TEMP. EXTERNAL NH")
label3 = LabelScreen3(radice, "TEMP. BOILER")

radice.mainloop()

问题在于我用来更新屏幕上的文本(传感器的值)的方法 update_label(self)。在此方法中,您会看到我将作为类参数放入的变量 prex_hot。我尝试过: def update_label(self, parameter) 但由于它是递归的,我得到递归错误。我会将参数传递给类对象,但我尝试了不同的方法,但从未奏效。可能原因是由于参数本身是一个变量,或者我可能在其他地方错了。任何帮助(请原谅我的初学者错误)?

标签: pythontkinter

解决方案


此示例使用StringVar.

Thread运行string_var.set(value)用于设置随机值的代码StringVar

同时LabelScreen用于string_var.get()从中获取值StringVar并将其显示在标签中。

import tkinter as tk
import threading

class LabelScreen():

    def __init__(self, parent, text_label, string_var):
        self.string_var = string_var

        larghezza_titolo = 19
        larghezza_labels = 5
        altezza_labels = 2        
        imb_pulsantey = int(1*h)        
        imb_pulsantex = int(1.5*w) 
        screen_resolution = str(W)+'x'+str(H)
        parent.geometry(screen_resolution)
        self.labels_frame = tk.Frame(parent, background="black")

        self.labels_frame.pack(fill=tk.BOTH, expand=True)
        self.labels_frame.pack_propagate(0)

        self.labelA = tk.Label(
            self.labels_frame,
            text = "fff",
            borderwidth=int(h*0.3),
            width = larghezza_labels,
            height = altezza_labels,
            relief="raised",
            font= ('ObliviousFont',int(h*5)),
            fg="SteelBlue1",
            background = "gray7",
            pady = imb_pulsantey,
            padx = imb_pulsantex
        )

        self.labelA.place(x=int(w*10), y=int(h*10))

        self.labelA_title = tk.Label(
            self.labels_frame,
            text = text_label,
            borderwidth=int(h*0.3),
            width = larghezza_titolo,
            font= ('ObliviousFont',int(h*1.5)),
            fg="SteelBlue1",
            background = "gray7",
        )

        self.labelA_title.place(in_=self.labelA, relx=.5, y=int(h*2),anchor="c")        
        self.update_label()

    def update_label(self):        
        self.labelA.configure(text=self.string_var.get())
        self.labelA.after(1000, self.update_label)

# ---------------------------------------------------------

def change_value_randomly(string_var):
    import time
    import random

    while True:
        string_var.set(random.randint(-10, 10))
        time.sleep(1)


radice = tk.Tk()

H=int(radice.winfo_screenheight())
W=int(radice.winfo_screenwidth())
h=int(H/100)
w=int(W/100)
#radice.overrideredirect(1)

prex_hot = tk.StringVar() # after creating `tk.Tk()`

# after creating `StringVar()` but before `mainloop()`
t = threading.Thread(target=change_value_randomly, args=(prex_hot,))
t.start()

label1 = LabelScreen(radice, "PRESSURE HOT WATER", prex_hot)


radice.mainloop()

推荐阅读