尝试使用 canvas 椭圆形项目作为状态指示器

Trying to use a canvas oval item as a status indicator

我正在尝试为 canvas 椭圆形项目着色,以指示程序何时忙(状态指示器)。预期的行为是在单击复选按钮时将 canvas 椭圆形变为红色,并在功能完成时将其关闭(变为蓝色)。

这是我目前的代码

class App(tk.Tk):
    def __init__(self):  
        tk.Tk.__init__(self)
        self.entryframe = Frame(self, width=800, height=500)
        self.entryframe.pack(fill=X, padx=8, pady=8)
        self.canvas = Canvas(self.entryframe, width=30, height=30)
        # change fill color of the status oval
        self.status = self.canvas.create_oval(10, 10, 30, 30, fill="blue", tags="state")
        self.canvas.grid(row=0, column=1)
        self.label = Label(self.entryframe, text="Enter your sentence:").grid(row=3, column=0, sticky=W)
        self.text = Text(self.entryframe, wrap=WORD, width=70, height=10)
        self.text.grid(row=4, column=0, sticky=W)
        self.btn_h = Button(self.entryframe, text="Check", width="15", command=self.check_input).grid(row=5, column=0, padx=8, pady=8)

    def check_input(self):
        #change status oval color to red
        self.canvas.itemconfig(status, fill='red')

        # after the function is complete turn it back off
        canvas.itemconfig(light_1, fill='blue')

root = App()
root.mainloop()

当前行为是项目保持蓝色,根本没有改变。

您将对 oval 的引用保存为 class 属性。因此,您需要通过传递 self:

以相同的方式访问它
import tkinter as tk
from threading import Thread
import time

class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.entryframe = tk.Frame(self, width=800, height=500)
        self.entryframe.pack(fill=tk.X, padx=8, pady=8)
        self.canvas = tk.Canvas(self.entryframe, width=30, height=30)
        # change fill color of the status oval
        self.status = self.canvas.create_oval(10, 10, 30, 30, fill="blue", tags="state")
        self.canvas.grid(row=0, column=1)
        self.label = tk.Label(self.entryframe, text="Enter your sentence:").grid(row=3, column=0, sticky=tk.W)
        self.text = tk.Text(self.entryframe, wrap=tk.WORD, width=70, height=10)
        self.text.grid(row=4, column=0, sticky=tk.W)
        self.btn_h = tk.Button(self.entryframe, text="Check", width="15", command=self.check_input).grid(row=5, column=0, padx=8, pady=8)

    def check_input(self):
        #change status oval color to red
        self.canvas.itemconfig(self.status, fill='red') #use self.status instead
        t = Thread(target=self.lengthy_process,args=("Arg1","Arg2"))
        t.start()

    def lengthy_process(self,param1,param2):
        print (param1, param2)
        time.sleep(10) #simulate the time taken for processing
        print ("Finished!")
        self.canvas.itemconfig(self.status, fill='blue')

root = App()
root.mainloop()

此外,从您如何继承 tk 实例并创建其余小部件的方式来看,您似乎混合了 import tkinter as tkfrom tkinter import *。这通常被认为是不好的做法——如果需要,简单地使用 import tkinter as tk 更合理,这样您就可以知道哪些小部件属于 tk,哪些属于 ttk。另请阅读 Why is “import *” bad?