1

It's my understanding that the class DiceRoller should be inheriting from the class die, however every time I run I get the error:

self.display.config(text = str(self.value))  
AttributeError: 'DiceRoller' object has no attribute 'display'  

The value of self.value is updating, but the Tkinter label is not.

import Tkinter
import random

class die(object):
    def __init__(self,value,display):
        self.value = random.randint(1,6)
        self.display = Tkinter.Label(display,
          text = str(self.value),
          font = ('Garamond', 56),
          bg = 'white',
          relief = 'ridge',
          borderwidth = 5)
        self.display.pack(side = 'left')

class DiceRoller(die):
    def __init__(self):
        self.gameWin = Tkinter.Tk()
        self.gameWin.title('Dice Roller')
        self.gameFrame = Tkinter.Frame(self.gameWin)
        self.dice = []
        self.Row1 = Tkinter.Frame(self.gameWin)
        for i in range(1,4):
            self.dice.append(die(i,self.Row1))  
        self.topFrame = Tkinter.Frame(self.gameWin)
        self.rollBtn = Tkinter.Button(self.topFrame,
            text = 'Roll Again',
            command = self.rollDice,
            font = ('Garamond', 56))
        self.rollBtn.pack(side = 'bottom')

        self.gameFrame.pack()
        self.Row1.pack()
        self.topFrame.pack()
        self.gameWin.mainloop()
    def rollDice(self):
        self.value = random.randint(1,6)
        print self.value  #to show value is in fact changing
        self.display.config(text = str(self.value))

varName = DiceRoller()
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
B.Gra
  • 13
  • 2
  • You're setting `text = str(self.value)` - that's a one-off, it's not some kind of binding that will get updated when `self.value` changes. Set `textvariable=self.value`, a direct reference. – jonrsharpe Nov 10 '16 at 17:49
  • Possible duplicate of [Making python/tkinter label widget update?](http://stackoverflow.com/questions/1918005/making-python-tkinter-label-widget-update) – jonrsharpe Nov 10 '16 at 17:51

1 Answers1

1

You get that

AttributeError: 'DiceRoller' object has no attribute 'display' 

error because DiceRoller doesn't actually have a .display attribute.

You may expect it to have one because the die class has a .display attribute, but that attribute gets created when die.__init__ gets called, and DiceRoller won't automatically call die.__init__ because you've overridden that method with DiceRoller's own .__init__ method.

If you want to call die.__init__ inside DiceRoller.__init__ you can do that, the suggested way is to use the super function. But you have to be careful to call die.__init__ with the correct arguments!

However, there's no need for DiceRoller to inherit from die. I've moved DiceRoller's old rollDice method to die & created a new rollDice method for DiceRoller. So when the 'Roll Again' button is pressed all the dice in DiceRoller.dice get rolled.

import Tkinter as tk
import random

class die(object):
    def __init__(self, value, display):
        self.value = random.randint(1,6)
        self.display = tk.Label(display,
          text = str(self.value),
          font = ('Garamond', 56),
          bg = 'white',
          relief = 'ridge',
          borderwidth = 5)
        self.display.pack(side = 'left')

    def rollDice(self):
        self.value = random.randint(1,6)
        print self.value  #to show value is in fact changing
        self.display.config(text = str(self.value))

class DiceRoller(object):
    def __init__(self):
        self.gameWin = tk.Tk()
        self.gameWin.title('Dice Roller')
        self.gameFrame = tk.Frame(self.gameWin)
        self.dice = []
        self.Row1 = tk.Frame(self.gameWin)
        for i in range(1,4):
            self.dice.append(die(i, self.Row1))  
        self.topFrame = tk.Frame(self.gameWin)
        self.rollBtn = tk.Button(self.topFrame,
            text = 'Roll Again',
            command = self.rollDice,
            font = ('Garamond', 56))
        self.rollBtn.pack(side = 'bottom')

        self.gameFrame.pack()
        self.Row1.pack()
        self.topFrame.pack()
        self.gameWin.mainloop()

    def rollDice(self):
        for die in self.dice:
            die.rollDice()

DiceRoller()
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182