停止标签更换

时间:2014-01-04 04:24:02

标签: python user-interface tkinter label

我正在为自己创建一个修订程序,但无论何时调用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()

1 个答案:

答案 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()

以下是一些需要注意的事项:

  1. import tkinter as tk这需要更多的输入,但它会使您的程序更加健壮。这种副作用(这是一个很好的副作用IMO)是所有tkinter命令现在都需要以tk为前缀(例如:tk.Button)。在我看来,这是一个更好的方式,而不是盲目地将tkinter中的所有内容导入为一堆全局变量和函数。我知道必须教程显示from tkinter import *,但它们被误导了。

  2. 逻辑的主要部分是一个类。这样可以轻松避免使用全局变量。作为编程时的经验法则,您应该避免使用全局变量。

  3. 请注意self如何成为tfun1__init__的参数 - 这是python类的要求。这就是你如何做到的。另请注意,我们将其称为self.fun1,而不仅仅是fun1。这让python知道你想要调用与当前对象关联的函数。一旦您的程序变大,这就可以更容易地了解fun1的定义位置。

  4. 我删除了强制GUI大小的代码。 Tkinter非常擅长计算尺寸应该是什么,所以让它做它的工作。此外,如果在布置窗口小部件时要小心,则在调整窗口大小时它们会正常增长和缩小。这意味着您不需要强制最小或最大尺寸到窗口。强制大小会带来糟糕的用户体验 - 用户应始终能够调整窗口大小以满足其需求。

  5. 我将窗口小部件的创建与窗口小部件的布局分开。例如,如果要保留对小部件的引用,则 将它们分开。这是因为:lbl=label(...).pack()将lbl设置为None。这就是python的工作方式 - 最后一个函数是保存到变量的函数,而packgrid都不返回任何函数。第二个原因只是它使您的代码更容易编写和维护。组织小部件的所有代码都在一个地方,这样可以更容易地看到整体情况。