标签不断出现

时间:2015-06-18 18:54:29

标签: python-3.x tkinter

所以我使用的是Python 3.4和tkinter。

当我再次再次调用一个包含标签的函数时,标签会一直显示在窗口中,但之前的标签不会消失?

如果在调用函数后立即从GUI窗口中删除任何打印的标签,然后显示新标签?

以下是代码: -

#def prestart():
    #here I check if number of match is okay, if not, user is redirected to setting else, I call start()

def start():

    #CPU Choice
    cpu_choice = Label(historyframe, text = "CPU Choosed: {}".format(dict['cpu_choice']))

    #Played Match
    #played_num_of_match = Label(scoreframe, text = "Number of Matches Played: {}".format(int(dict['match_played'])))

    #Display Status
    status_disp = Label(scoreframe, text = "Current Status: {}".format(dict['status']))

    if(int(dict['match_played']) < int(dict['num_of_match'])):
        playframe.grid(row = 1, column = 0)
        historyframe.grid(row = 2, column = 1)
        status_disp.pack(fill=X)
    elif(int(dict['match_played']) == int(dict['num_of_match'])):
        playframe.grid(row = 1, column = 0)
        historyframe.grid(row = 2, column = 1)
        status_disp.pack(fill=X)
        cp = dict['cpu_point']
        up = dict['user_point']
        result(cp, up)
    cpu_choice.pack(fill = X)
    scoreframe.grid(row = 2, column = 0)

此功能只是更新显示!

def send_value(x):
    #Here I run logic of game and change value of key in dictionary and call start() at end of change.

现在,选择按钮没有任何定义,因为它们不需要再次调用n。我只是让playframe消失了! 这是他们的代码: -

#Display Question
question = Label(playframe, text = "Rock? Paper? Scissor?")

#Rock
rock = Button(playframe, text = "Rock!", command = lambda: send_value("ROCK"))

#Paper
paper = Button(playframe, text = "Paper!", command = lambda: send_value("PAPER"))

#Scissor
scissor = Button(playframe, text = "Scissor!", command = lambda: send_value("SCISSOR"))

因此,当用户点击Rock / Paper / Scissor时,我只需更改字典中的键值!但是如果我将标签保留在功能之外,它就不会自动更新!

其他一切都很完美。我现在开始使代码更清洁了。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情,而不是每次都创建一个新标签:

import Tkinter as tk

class Window():

    def __init__(self, root):

        self.frame = tk.Frame(root)
        self.frame.pack()

        self.i = 0
        self.labelVar = tk.StringVar()
        self.labelVar.set("This is the first text: %d" %self.i) 

        self.label = tk.Label(self.frame, text = self.labelVar.get(), textvariable = self.labelVar)
        self.label.pack(side = tk.LEFT)

        self.button = tk.Button(self.frame, text = "Update", command = self.updateLabel)
        self.button.pack(side = tk.RIGHT)

    def updateLabel(self):

        self.i += 1
        self.labelVar.set("This is new text: %d" %self.i)


root = tk.Tk()
window = Window(root)
root.mainloop()

要点:

1)使用类,因为当所有Tkinter对象和变量都是成员变量时,可以更容易地传递值,可以从所有GUI函数访问。

2)updateLabel不会创建新标签。它只是更新StringVar()对象以在每次调用函数时保存新文本。这是在创建Label小部件时使用textvariable = self.labelVar关键字完成的。

PS :这是在 Python 2.5 中完成的,因此要让此代码适合您,请将Tkinter更改为tkinter

编辑06/19/2015

如果你想实现与我的代码相似的东西,没有使用类,你需要传递对变量的引用。

1)更改start

您的标签cpu_choicestatus_disp等应在该功能之外创建;可能与questionrockpaperscissors等位置相同。您也可以将它们打包在函数之外。与.gridstart的所有调用相同;您不应该多次拨打packgrid:在您创建窗口小部件时。

以下几行:

    playframe.grid(row = 1, column = 0)
    historyframe.grid(row = 2, column = 1)
    status_disp.pack(fill=X)

也可以在功能之外完成;您在ifelif条件下执行这3个语句。这意味着它们不是真正有条件的陈述;无论条件的有效性如何,都可以完成。

2)为StringVar和{}创建cpu_choice status_disp&amp;编辑标签如下(记住,在功能之外):

    cpu_choice_text = StringVar()
    cpu_choice_text.set("Set this to whatever is shown at the start of the game")
    cpu_choice = Label(historyframe, text = cpu_choice_text.get(), textvariable = cpu_choice_text)
    cpu_choice.pack(fill = X)

    # And do this same thing for status_disp

3)当您致电start时,您现在将其传递给cpu_choice_text&amp; status_disp_text(或其他任何名称)。您现在可以在text上使用set调用而不是尝试更改标签框架的StringVar字段,该 def start(cpu_choice_text, status_disp_text): cpu_choice.set(text = "CPU Choice: {}".format(dict['cpu_choice'])) ... 调用连接到标签&amp;标签将自动更新。例如:

self

或者,将它全部包装在一个类中,并通过在每个Tkinter变量&amp;上使用self.i使自己更容易。小部件。通过这种方式,您不需要将变量传递给函数,只需像我的self.labelVar stage.addEventListener(KeyboardEvent.KEY_DOWN,playerOneKeyDownHandler); stage.addEventListener(KeyboardEvent.KEY_DOWN,playerOneKeyUpHandler); // this is for type KEY_DOWN, but the handler is "Up" stage.addEventListener(KeyboardEvent.KEY_UP,playerTwoKeyDownHandler); //that looks suspicious, too stage.addEventListener(KeyboardEvent.KEY_UP,playerTwoKeyUpHandler); 那样直接访问成员变量。

答案 1 :(得分:0)

每次拨打start时,您都会创建新标签并使用grid将它们放在与旧标签相同的位置。最佳解决方案是仅创建一次标签,但如果您每次调用start时坚持创建新标签,则需要先删除旧标签。

您可以使用标签的destroy()方法将其销毁,但要实现这一点,您必须保留标签的全局引用。