2014-05-14 31 views
0

我已经反复尝试并且无法理解我应该在下面的代码中定义文本变量“die”的位置和方式。注释行是我尝试赋值的地方,但仍然出现各种值或名称错误,这使我相信我不知道如何正确初始化它的值。在tkinter的自引用实现中定义'textvariable'时遇到问题

from random import * 
from tkinter import * 
from tkinter import ttk 
import tkinter as tk 

#die = StringVar() # 1 

def roll (int): 
    try: 
     die.set(randrange(1,int)) 
    except ValueError: 
     pass 

class Application(ttk.Frame): 

    #die = StringVar() # 2 

    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     #self.die = StringVar() # 3 
     self.createWidgets() 

    def createWidgets(self): 
     #self.die = StringVar() # 4 
     self.d_twoButton = ttk.Button(self, text='d2', command=roll(2)).grid() 
     self.d_threeButton = ttk.Button(self, text='d3', command=roll(3)).grid() 
     self.d_fourButton = ttk.Button(self, text='d4', command=roll(4)).grid() 
     self.d_sixButton = ttk.Button(self, text='d6', command=roll(6)).grid() 
     self.d_eightButton = ttk.Button(self, text='d8', command=roll(8)).grid() 
     self.d_tenButton = ttk.Button(self, text='d10', command=roll(10)).grid() 
     self.d_twelveButton = ttk.Button(self, text='d12', command=roll(12)).grid() 
     self.d_twentyButton = ttk.Button(self, text='d20', command=roll(20)).grid() 
     self.d_onehundredButton = ttk.Button(self, text='d100', command=roll(100)).grid() 
     self.resultLabel = ttk.Label(self, textvariable=die) 
     self.resultLabel.grid()   

app = Application()      
app.master.title('Die Roller') 
#app.die = StringVar() # 5 
app.mainloop() 

(我曾试图添加标签textvariable和stringval更容易识别,但我至今不能的。如果有人能这样的标签添加到这个帖子,请随时自由地这样做。 )

+0

您所有的按钮变量('self.d_twoButton'等)将被设置为'None',因为你在同一个属性中调用'grid'在此创建小部件。您应该分离小部件的创建和布局,或者摆脱变量。 –

回答

1

现货#3可能是最好的地方。不过,您需要进行一些额外的修改。

  • 您必须明确引用roll中的应用程序对象以访问其die属性。或者,roll应该是Application类的一个方法;看第二个代码块。
  • command如果您要为要调用的函数提供参数,则参数必须包含在lambda中。
  • 可选:删除所有self.d_someNumberButton =赋值位,因为它们都是None,并且您不会在任何地方使用它们。 (提示:my_thing = Button()使得my_thing成一个按钮my_thing = Button().grid()使得my_thingNone。)

实现用尽可能少的修改原密码:

from random import * 
from tkinter import * 
from tkinter import ttk 
import tkinter as tk 

#die = StringVar() # 1 

def roll (int): 
    try: 
     app.die.set(randrange(1,int)) 
    except ValueError: 
     pass 

class Application(ttk.Frame): 

    #die = StringVar() # 2 

    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     self.die = StringVar() # 3 
     self.createWidgets() 

    def createWidgets(self): 
     #self.die = StringVar() # 4 
     self.d_twoButton = ttk.Button(self, text='d2', command=lambda: roll(2)).grid() 
     self.d_threeButton = ttk.Button(self, text='d3', command=lambda: roll(3)).grid() 
     self.d_fourButton = ttk.Button(self, text='d4', command=lambda: roll(4)).grid() 
     self.d_sixButton = ttk.Button(self, text='d6', command=lambda: roll(6)).grid() 
     self.d_eightButton = ttk.Button(self, text='d8', command=lambda: roll(8)).grid() 
     self.d_tenButton = ttk.Button(self, text='d10', command=lambda: roll(10)).grid() 
     self.d_twelveButton = ttk.Button(self, text='d12', command=lambda: roll(12)).grid() 
     self.d_twentyButton = ttk.Button(self, text='d20', command=lambda: roll(20)).grid() 
     self.d_onehundredButton = ttk.Button(self, text='d100', command=lambda: roll(100)).grid() 
     self.resultLabel = ttk.Label(self, textvariable=self.die) 
     self.resultLabel.grid()   

app = Application()      
app.master.title('Die Roller') 
#app.die = StringVar() # 5 
app.mainloop() 

结果:

enter image description here

在这里,我只点击了“d100”按钮,并成功显示了一个数字在预期范围内。


替代实现,用roll作为一个类的方法:

from random import * 
from tkinter import * 
from tkinter import ttk 
import tkinter as tk 

class Application(ttk.Frame): 
    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     self.die = StringVar() 
     self.createWidgets() 

    def createWidgets(self): 
     ttk.Button(self, text='d2', command=lambda: self.roll(2)).grid() 
     ttk.Button(self, text='d3', command=lambda: self.roll(3)).grid() 
     ttk.Button(self, text='d4', command=lambda: self.roll(4)).grid() 
     ttk.Button(self, text='d6', command=lambda: self.roll(6)).grid() 
     ttk.Button(self, text='d8', command=lambda: self.roll(8)).grid() 
     ttk.Button(self, text='d10', command=lambda: self.roll(10)).grid() 
     ttk.Button(self, text='d12', command=lambda: self.roll(12)).grid() 
     ttk.Button(self, text='d20', command=lambda: self.roll(20)).grid() 
     ttk.Button(self, text='d100', command=lambda: self.roll(100)).grid() 
     self.resultLabel = ttk.Label(self, textvariable=self.die) 
     self.resultLabel.grid()   

    def roll(self, max_value): 
     app.die.set(randrange(1,max_value)) 

app = Application()      
app.master.title('Die Roller') 
app.mainloop() 

替代的替代实现,它使用一个for循环来创建按钮:

from random import * 
from tkinter import * 
from tkinter import ttk 
import tkinter as tk 

class Application(ttk.Frame): 
    def __init__(self, master=None): 
     ttk.Frame.__init__(self, master) 
     self.grid() 
     self.die = StringVar() 
     self.createWidgets() 

    def createWidgets(self): 
     for num_sides in [2, 3, 4, 6, 8, 10, 12, 20, 100]: 
      ttk.Button(self, text="d{}".format(num_sides), command=lambda value=num_sides: self.roll(value)).grid() 
     self.resultLabel = ttk.Label(self, textvariable=self.die) 
     self.resultLabel.grid()   

    def roll(self, max_value): 
     app.die.set(randrange(1,max_value)) 

app = Application()      
app.master.title('Die Roller') 
app.mainloop() 
+0

谢谢。我知道我错过了初始化变量的几个步骤。你的替代品对我来说也是很好的资源,因为我想知道动态创建按钮的方法,但是我认为我应该先学习简单的案例。 –

相关问题