1

Python is my first language so please understand me if it doesn't make sense. I'm making a virtual pet in python. I'm using Tkinter for GUI. I want to run the display method in Action class every 5 seconds. But, if I use threading, sched, or time and place the code right before the buttons, it froze and just run the display method. How can I run display method for every 5 seconds while it doesn't interrupt the buttons and other parts?

class Pet:    
def __init__(self, name, hunger=0, boredom=0, tiredness=0, sickness=False,
             age=0, waste=0):
    self.__name = name
    self.hunger = hunger
    self.boredom = boredom
    self.tiredness = tiredness
    self.sickness = sickness
    self.age = age
    self.waste = waste
    self.choice = choice

class Action(Pet):
    def __init__(self, name):
        Pet.__init__(self, name, hunger=0, boredom=0, tiredness=0,
                 sickness=False, age=0, waste=0)
        self.name = name

    def display(self):
        print("------------")
        print("hunger", self.hunger)
        print("boredom", self.boredom)
        print("tiredness", self.tiredness)
        print("sickness", self.sickness)
        print("age", self.age)
class Window(Frame):
    def openmenu(self):
        petname = self.petnameEntry.get()
        user_pet = Action(petname)
        print("I am your pet,", petname)
        window = tk.Toplevel(root)
        w = Label(window, text="What would you like to do?")
        w.pack()

        btFeed = Button(window, text="Feed", command=lambda: user_pet.eat())
        btFeed.pack(pady=3)
        btPlay = Button(window, text="Play", command=lambda: 
        user_pet.play())
        btPlay.pack(pady=3)
BeginCs123
  • 41
  • 1
  • 4

2 Answers2

0

You can use the After method.

import tkinter as tk
root = tk.Tk()

class Pet:
    def __init__(self, name, hunger=0, boredom=0, tiredness=0, sickness=False,
                 age=0, waste=0):
        self.__name = name
        self.hunger = hunger
        self.boredom = boredom
        self.tiredness = tiredness
        self.sickness = sickness
        self.age = age
        self.waste = waste

class Action(Pet):
    def __init__(self, name):
        Pet.__init__(self, name, hunger=0, boredom=0, tiredness=0,
                 sickness=False, age=0, waste=0)
        self.name = name

    def display(self):
        print("------------")
        print("hunger", self.hunger)
        print("boredom", self.boredom)
        print("tiredness", self.tiredness)
        print("sickness", self.sickness)
        print("age", self.age)
        root.after(5000,self.display)

root.after(5000,Action(Pet).display)

root.mainloop()
Henry Yik
  • 22,275
  • 4
  • 18
  • 40
0

Suggest to define a new function in class Window(Frame):

def show_pet_status(self, pet):
    # show the pet status only if the 'toplevel' still exists
    if Toplevel.winfo_exists(self.window):
        pet.display()
        root.after(5000, self.show_pet_status, pet)

Then modify openmenu(...) as below:

def openmenu(self):
    petname = self.petnameEntry.get()
    user_pet = Action(petname)
    print("I am your pet,", petname)
    self.window = Toplevel(root)   # save the window object to be used by new function
    w = Label(self.window, ...)
    w.pack()
    btFeed = Button(self.window, text="Feed", ...)
    btFeed.pack(pady=3)
    btPlay = Button(self.window, text="Play", ...)
    btPlay.pack(pady=3)
    # start showing the pet status
    self.show_pet_status(user_pet)
acw1668
  • 40,144
  • 5
  • 22
  • 34