为什么清除和重写此 tkinter 框架会使其重复?
Why does clearing and rewriting this tkinter frame make it duplicate?
我正在使用 Python 中的 tkinter
模块开发 RPG 风格的游戏,我有一个角色创建屏幕,其中包含随机生成的统计数据。这 6 个统计数据是使用 random
模块生成的。
我遇到的问题是,当我清除屏幕以将数字重新打包到专用于它们的框架中时,它第一次起作用了,数字被清除并出现了一组新数字,但是第二个和第三个时间(等等)我按下按钮它只会在框架内生成一组新的数字,而以前的数字仍然存在,复制数字的数量。
我尝试了 运行 从该站点看到的各种不同方法,例如 .pack_forget
和从屏幕上删除,我什至将用于存储标签的变量设置为 None
但我似乎没有任何尝试。
我会post下面的代码,程序有几百行,如果我遗漏了与问题相关的任何内容,请原谅我。
def CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright):
StrengthValue.destroy()
DexterityValue.destroy()
ConstitutionValue.destroy()
WisdomValue.destroy()
IntelligenceValue.destroy()
CharismaValue.destroy()
StrNumber = randrange(3, 18)
DexNumber = randrange(3, 18)
ConNumber = randrange(3, 18)
WisNumber = randrange(3, 18)
IntNumber = randrange(3, 18)
ChaNumber = randrange(3, 18)
StrengthValue = Label(statframebottomleftright, text=StrNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
DexterityValue = Label(statframebottomleftright, text=DexNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
ConstitutionValue = Label(statframebottomleftright, text=ConNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
WisdomValue = Label(statframebottomrightright, text=WisNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
IntelligenceValue = Label(statframebottomrightright, text=IntNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
CharismaValue = Label(statframebottomrightright, text=ChaNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
StrengthValue.pack(fill="both", expand=True)
DexterityValue.pack(fill="both", expand=True)
ConstitutionValue.pack(fill="both", expand=True)
WisdomValue.pack(fill="both", expand=True)
IntelligenceValue.pack(fill="both", expand=True)
CharismaValue.pack(fill="both", expand=True)
您遇到的问题是作业,例如StrengthValue = Label(...)
函数内部 不会 影响传入的对象,它只是将新对象分配给该名称 函数内部 .因此,您第一次调用该函数时,原始对象会按预期进行 destroy
ed,但您不会保留对新对象的引用(因为它们不是从函数中 return
ed)所以后续调用似乎行为不正确。
一种解决方案是传递可变参数,例如包含相关对象的列表:
def CharManage2Option3Command(label_lists, stat_frames):
for label_list, stat_frame in zip(label_lists, stat_frames):
for index, label in enumerate(label_list):
number = randrange(3, 18)
label.destroy()
label_list[index] = Label(stat_frame, text=number, ...)
label_list[index].pack(...)
(请参阅 zip
and enumerate
上的文档。)。这将被称为例如:
CharManage2Option3Command([[StrengthValue, DexterityValue, ConstitutionValue],
[WisdomValue, IntelligenceValue, CharismaValue]],
[statframebottomleftright, statframebottomrightright]):
请注意,这具有减少函数重复的便利副作用。您还可以从一开始就将 Label
个实例保存在一个列表中,而不是对每个实例单独进行引用。
其他解决方案包括显式 return
从函数中获取新标签并重新分配给原始名称:
def CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright):
...
return StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue
然后调用它:
StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue = CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright)
(这显然很尴尬),使用 IntVar
作为 Label
的 textvariable
并更新它或做一些基于 class 的事情,这样你访问例如self.StrengthValue
无处不在。
我还建议您看一下 style guide,它提供了函数和变量名称等方面的约定。
我正在使用 Python 中的 tkinter
模块开发 RPG 风格的游戏,我有一个角色创建屏幕,其中包含随机生成的统计数据。这 6 个统计数据是使用 random
模块生成的。
我遇到的问题是,当我清除屏幕以将数字重新打包到专用于它们的框架中时,它第一次起作用了,数字被清除并出现了一组新数字,但是第二个和第三个时间(等等)我按下按钮它只会在框架内生成一组新的数字,而以前的数字仍然存在,复制数字的数量。
我尝试了 运行 从该站点看到的各种不同方法,例如 .pack_forget
和从屏幕上删除,我什至将用于存储标签的变量设置为 None
但我似乎没有任何尝试。
我会post下面的代码,程序有几百行,如果我遗漏了与问题相关的任何内容,请原谅我。
def CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright):
StrengthValue.destroy()
DexterityValue.destroy()
ConstitutionValue.destroy()
WisdomValue.destroy()
IntelligenceValue.destroy()
CharismaValue.destroy()
StrNumber = randrange(3, 18)
DexNumber = randrange(3, 18)
ConNumber = randrange(3, 18)
WisNumber = randrange(3, 18)
IntNumber = randrange(3, 18)
ChaNumber = randrange(3, 18)
StrengthValue = Label(statframebottomleftright, text=StrNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
DexterityValue = Label(statframebottomleftright, text=DexNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
ConstitutionValue = Label(statframebottomleftright, text=ConNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
WisdomValue = Label(statframebottomrightright, text=WisNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
IntelligenceValue = Label(statframebottomrightright, text=IntNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
CharismaValue = Label(statframebottomrightright, text=ChaNumber, fg=DefaultColour, bg=WhiteBackgroundColour, font=DefaultFont)
StrengthValue.pack(fill="both", expand=True)
DexterityValue.pack(fill="both", expand=True)
ConstitutionValue.pack(fill="both", expand=True)
WisdomValue.pack(fill="both", expand=True)
IntelligenceValue.pack(fill="both", expand=True)
CharismaValue.pack(fill="both", expand=True)
您遇到的问题是作业,例如StrengthValue = Label(...)
函数内部 不会 影响传入的对象,它只是将新对象分配给该名称 函数内部 .因此,您第一次调用该函数时,原始对象会按预期进行 destroy
ed,但您不会保留对新对象的引用(因为它们不是从函数中 return
ed)所以后续调用似乎行为不正确。
一种解决方案是传递可变参数,例如包含相关对象的列表:
def CharManage2Option3Command(label_lists, stat_frames):
for label_list, stat_frame in zip(label_lists, stat_frames):
for index, label in enumerate(label_list):
number = randrange(3, 18)
label.destroy()
label_list[index] = Label(stat_frame, text=number, ...)
label_list[index].pack(...)
(请参阅 zip
and enumerate
上的文档。)。这将被称为例如:
CharManage2Option3Command([[StrengthValue, DexterityValue, ConstitutionValue],
[WisdomValue, IntelligenceValue, CharismaValue]],
[statframebottomleftright, statframebottomrightright]):
请注意,这具有减少函数重复的便利副作用。您还可以从一开始就将 Label
个实例保存在一个列表中,而不是对每个实例单独进行引用。
其他解决方案包括显式 return
从函数中获取新标签并重新分配给原始名称:
def CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright):
...
return StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue
然后调用它:
StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue = CharManage2Option3Command(StrengthValue, DexterityValue, ConstitutionValue, WisdomValue, IntelligenceValue, CharismaValue, statframebottomleftright, statframebottomrightright)
(这显然很尴尬),使用 IntVar
作为 Label
的 textvariable
并更新它或做一些基于 class 的事情,这样你访问例如self.StrengthValue
无处不在。
我还建议您看一下 style guide,它提供了函数和变量名称等方面的约定。