尝试使用椭圆形画布作为状态指示器

时间:2019-07-18 01:35:44

标签: python python-3.x tkinter tkinter-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()

当前行为是该项目保持蓝色,并且完全没有变化。

1 个答案:

答案 0 :(得分:1)

您将对oval的引用保存为类属性。因此,您需要通过传递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?