为什么清除和重写此tkinter帧会使其重复?

时间:2015-02-04 11:14:16

标签: python tkinter frames

我正在使用Python中的tkinter模块开发RPG风格的游戏,我有一个带有随机生成的统计数据的角色创建屏幕。使用random模块生成6个统计信息。

我遇到的问题是,当我清除屏幕以将数字重新打包到专用于它们的帧中时,它首次工作,数字清晰并出现一组新数字,但第二和第三时间(等等)我按下按钮它只是在框架内生成一组新的数字而前一个数字仍然存在,重复数字的数量。

我尝试过运行从此网站看到的各种不同方法,例如.pack_forget并从屏幕上删除,我甚至将用于存储标签的变量设置为None但我没有尝试似乎工作。

我发布下面的代码,程序是几百行,如果我错过了与问题相关的任何内容,请原谅我。

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)

1 个答案:

答案 0 :(得分:1)

您遇到的问题是转让,例如函数中的StrengthValue = Label(...)不会影响传入的对象,它只是在函数中为该名称​​分配一个新对象。因此,当您第一次调用该函数时,原始对象按预期destroy编辑,但您不会保留对新对象的引用(因为它们不是return来自功能)所以后续调用似乎表现不正确。

一种解决方案是传递可变参数,例如:包含相关对象的列表:

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(...)

(请参阅zipenumerate上的文档。)。这将被称为例如:

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作为textvariable的{​​{1}}并更新或执行基于类的操作,以便您访问例如Label无处不在。


我还建议您查看style guide,它提供函数和变量名等约定。