我正在为自己创建一个修订程序,但无论何时调用fun1函数,它都会在先前执行的函数下打印出来。例如,标签将打印在最后一个标签下面而不是替换它,任何想法?任何帮助将不胜感激!!
#Imports moduals used
from tkinter import *
import time
import random
#Sets GUI
gui = Tk()
gui.geometry("500x500")
gui.maxsize(width=500, height=500)
gui.minsize(width=500, height=500)
#Sets list of facts
def t():
print("hi")
facts = ['fact one','true', 'fact two','abc']
#Defines random fact generator
def fun1():
r = random.randrange(len(facts))
lbl = Label(gui,text=facts[r]).pack()
btnt = Button(text="True", command=t).pack()
btnf = Button(text="False", command=t).pack()
gui.after(5000, fun1)
gui.after(5000, fun1)
mainloop()
答案 0 :(得分:0)
编写此类程序的最佳方法是仅创建一次标签或按钮,然后使用configure
方法更改标签的文本。
以下是基于原始代码的示例:
#Imports moduals used
from tkinter import *
import time
import random
#Sets GUI
gui = Tk()
gui.geometry("500x500")
gui.maxsize(width=500, height=500)
gui.minsize(width=500, height=500)
def t():
print("hi")
#Defines random fact generator
def fun1():
r = random.randrange(len(facts))
lbl.configure(text=facts[r])
gui.after(5000, fun1)
#Sets list of facts
facts = ['fact one','true', 'fact two','abc']
# create the widgets
lbl = Label(gui,text="")
btnt = Button(text="True", command=t)
btnf = Button(text="False", command=t)
# lay out the widgets
lbl.pack(side="top", fill="x", expand=True)
btnt.pack(side="left", fill="x")
btnf.pack(side="right", fill="y")
# show the first fact; it will cause other
# facts to show up every N seconds
fun1()
mainloop()
由于您刚刚开始使用,因此我建议您更好地组织代码。 Python本质上是面向对象的,因此将应用程序作为对象是有意义的。即使您可能不熟悉对象类,如果您从这个模式开始并遵循一些简单的规则,您可以毫不费力地获得面向对象的所有好处。
您唯一需要记住的是,在您的主类中,所有函数都需要self
作为第一个参数,并且在调用函数时使用self.function
和省略< / em> self
作为参数(python为你做了)。除此之外,您可以在类中正常编写代码。
以下是一个例子:
import tkinter as tk
import random
class Example(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.facts = ['fact one','true', 'fact two','abc', 'a long fact\non two lines']
self.label = tk.Label(self,text="", width = 40, height=4)
self.true_button = tk.Button(self, text="True", command=self.t)
self.false_button = tk.Button(self, text="False", command=self.t)
self.label.pack(side="top", fill="both", expand=True, pady=40)
self.true_button.pack(side="left", fill="x")
self.false_button.pack(side="right", fill="x")
self.fun1()
def t(self):
print("hi")
def fun1(self):
r = random.randrange(len(self.facts))
self.label.configure(text=self.facts[r])
self.after(5000, self.fun1)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
以下是一些需要注意的事项:
import tkinter as tk
这需要更多的输入,但它会使您的程序更加健壮。这种副作用(这是一个很好的副作用IMO)是所有tkinter命令现在都需要以tk
为前缀(例如:tk.Button
)。在我看来,这是一个更好的方式,而不是盲目地将tkinter中的所有内容导入为一堆全局变量和函数。我知道必须教程显示from tkinter import *
,但它们被误导了。
逻辑的主要部分是一个类。这样可以轻松避免使用全局变量。作为编程时的经验法则,您应该避免使用全局变量。
请注意self
如何成为t
,fun1
和__init__
的参数 - 这是python类的要求。这就是你如何做到的。另请注意,我们将其称为self.fun1
,而不仅仅是fun1
。这让python知道你想要调用与当前对象关联的函数。一旦您的程序变大,这就可以更容易地了解fun1
的定义位置。
我删除了强制GUI大小的代码。 Tkinter非常擅长计算尺寸应该是什么,所以让它做它的工作。此外,如果在布置窗口小部件时要小心,则在调整窗口大小时它们会正常增长和缩小。这意味着您不需要强制最小或最大尺寸到窗口。强制大小会带来糟糕的用户体验 - 用户应始终能够调整窗口大小以满足其需求。
我将窗口小部件的创建与窗口小部件的布局分开。例如,如果要保留对小部件的引用,则 将它们分开。这是因为:lbl=label(...).pack()
将lbl设置为None
。这就是python的工作方式 - 最后一个函数是保存到变量的函数,而pack
和grid
都不返回任何函数。第二个原因只是它使您的代码更容易编写和维护。组织小部件的所有代码都在一个地方,这样可以更容易地看到整体情况。