尝试使用 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 tk
和 from tkinter import *
。这通常被认为是不好的做法——如果需要,简单地使用 import tkinter as tk
更合理,这样您就可以知道哪些小部件属于 tk
,哪些属于 ttk
。另请阅读 Why is “import *” bad?
我正在尝试为 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 tk
和 from tkinter import *
。这通常被认为是不好的做法——如果需要,简单地使用 import tkinter as tk
更合理,这样您就可以知道哪些小部件属于 tk
,哪些属于 ttk
。另请阅读 Why is “import *” bad?