所以我使用的是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时,我只需更改字典中的键值!但是如果我将标签保留在功能之外,它就不会自动更新!
其他一切都很完美。我现在开始使代码更清洁了。
答案 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_choice
,status_disp
等应在该功能之外创建;可能与question
,rock
,paper
,scissors
等位置相同。您也可以将它们打包在函数之外。与.grid
内start
的所有调用相同;您不应该多次拨打pack
或grid
:在您创建窗口小部件时。
以下几行:
playframe.grid(row = 1, column = 0)
historyframe.grid(row = 2, column = 1)
status_disp.pack(fill=X)
也可以在功能之外完成;您在if
和elif
条件下执行这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()
方法将其销毁,但要实现这一点,您必须保留标签的全局引用。