无法了解课堂上制作的tkinter中的内容

时间:2018-08-25 15:02:48

标签: python tkinter

我是Python新手,目前正在尝试将tkinter用作第一个GUI。我习惯了不上课。这是我第一次使用import tkinter as tk而不是import *

import tkinter as tk

def update():
    pass

#Game.statsFrame #doesn't work Game.statsFrame.stat1_amountLabel too
#Game.stat1_amountLabel #doesnt work < want to use update_idletasks() or 
#just type new cofnig...
#just errors like: "Game' has no attribute 'statsFrame" etc   #Game


class character:
    name = ""
    experience = 0
    level = 0
    gold = 0
    stat1 = 0
    stat2 = 0
    stat3 = 0
    stat4 = 0
    stat5 = 0
    avaiblePoints = 0
    def add_stat1(self):
        if self.avaiblePoints >= 1:
            self.stat1 += 1
            self.avaiblePoints -= 1
            update()
        else:
            pass
    def add_stat2(self):
        if self.avaiblePoints >= 1:
            self.stat2 += 1
            self.avaiblePoints -= 1
            update()
 [...]

myChar = character()
myChar.avaiblePoints = 3

class Game:
    def __init__(self, parent):
    self.myParent = parent
    self.myGame = tk.Frame(parent)
    self.myGame.grid()

    self.statsFrame = tk.Frame(self.myGame).grid()

    self.stat1Label = tk.Label(self.statsFrame)
    self.stat1Label.config(text="Strength:")
    self.stat1Label.grid(column=1, row=1)

    self.stat1_amountLabel = tk.Label(self.statsFrame)
    self.stat1_amountLabel.config(text=myChar.stat1)
    self.stat1_amountLabel.grid(column=2, row=1)

    self.add_stat1Button = tk.Button(self.statsFrame)
    self.add_stat1Button.config(text="+", command=myChar.add_stat1)
    self.add_stat1Button.grid(column=3, row=1)

root = tk.Tk()
myapp = Game(root)
root.mainloop()

但是我无法进入(例如)stat1Label并在其中使用update_idletasks()更改文本。就像它不存在。错误表明Game没有像stat1Label这样的属性。

我想使用它,因为我已经读过__init__方法更好,并且我想在页面之间切换。我不知道,当我不在tkinter中使用类时,某些事情(像这样)更容易并且没有问题。我很困惑。

1 个答案:

答案 0 :(得分:2)

使用import tkinter as tk代替可怕的“ star”导入,并尝试使用类来组织代码,这是非常好的。刚开始时可能会有些混乱,但是它会使您的代码更具模块化,这将极大地帮助您,尤其是在GUI很大时。

您的代码有一些问题。最重要的是这一行:

self.statsFrame = tk.Frame(self.myGame).grid()

.grid方法(以及.pack.place)都返回None。因此,该行将None保存到self.statsFrame,而不是Frame小部件。因此,当您以后尝试使用self.statsFrame做某事时,它不会做您期望的事。

另一个问题是您的text的{​​{1}}属性无法跟踪self.stat1_amountLabel的值,因此,当您更改myChar.stat1的值时,您需要明确用新值更新标签。另外,您可以使用myChar.stat1属性和IntVar来保存角色的属性。有关信息,请参见Label config docstextvariable的条目。

您的textvariable类具有一堆属性,例如charactername等作为类属性。这不是一个好主意,因为类属性由类的所有实例共享。但是您可能希望每个字符实例都具有自己的实例属性。因此,应为experience提供一个character方法,以在其中设置这些属性。 OTOH,可以将类属性用于默认值,这些默认值会被实例属性覆盖。

无论如何,这是您的代码的经过修复的版本,其中包含一个用于更新强度统计信息的按钮。我将统计信息放在列表中,而不是拥有一堆必须单独管理的独立命名统计信息。而且我为__init__提供了一种Game方法,因此您可以轻松地为其他统计信息添加行。

make_stat

此代码仍不理想,但它是一个改进。 ;)例如,最好给import tkinter as tk class Character: def __init__(self, availablePoints=0): self.name = "" self.experience = 0 self.level = 0 self.gold = 0 self.stats = [0] * 5 self.availablePoints = availablePoints def add_stat(self, idx): if self.availablePoints >= 1: self.stats[idx] += 1 self.availablePoints -= 1 class Game: def __init__(self, parent): self.myParent = parent self.myGame = tk.Frame(parent) self.myGame.grid() self.statsFrame = tk.Frame(self.myGame) self.statsFrame.grid() self.make_stat("Strength:", 0, 0) def make_stat(self, text, idx, row): label = tk.Label(self.statsFrame, text=text) label.grid(column=1, row=row) amount = tk.Label(self.statsFrame, text=myChar.stats[idx]) amount.grid(column=2, row=row) def update(): myChar.add_stat(idx) amount["text"] = myChar.stats[idx] button = tk.Button(self.statsFrame, text="+", command=update) button.grid(column=3, row=row) myChar = Character(3) root = tk.Tk() myapp = Game(root) root.mainloop() 一种创建新字符的方法,而不是在全局上下文中创建它们。您可以使用角色名称作为键,将它们存储在Game的{​​{1}}属性中。


这是一个新版本,可用于单独的名为dict的属性。正如我在评论中说的那样,与使用列表保存统计信息相比,以这种方式进行操作更为复杂(效率更低)。

Game