I have this skeleton of a game in two files.
First file mygui.py
:
from tkinter import Tk, Label, Button
from mygame import p1, play_game
def rungame():
play_game()
gui_widgets()
root = Tk()
def gui_widgets():
health_label = Label(root, text=f"health: {p1.health}")
health_label.grid(column=0, row=0)
mana_label = Label(root, text=f"mana: {p1.mana}")
mana_label.grid(column=0, row=1)
mybtn = Button(root, text="RUN GAME", command=rungame)
mybtn.grid(column=0, row=2)
gui_widgets()
root.mainloop()
Seccond file mygame
:
import time
class Player:
def __init__(self, health, mana):
self.health = health
self.mana = mana
def play_game():
p1.health -= 1
time.sleep(0.5)
p1.mana -= 3
time.sleep(0.5)
p1.mana = 1
p1 = Player(10, 15)
The game shows the begining statistic on gui and after clicking button it shows the end result. I want gui to show every p1
atribute change made in play_game()
as they are happening. How would I do this?
Edit: I am keen on keeping two seperate files so that program would be more scalable.
I am not sure if this is possible, but I would figure that if I could run gui_widgets()
continuosly (for example every 0,1 secconds) It would probalby work as intended. Still I understand that this may be impossible since tkinter seems to wait everytime when play_game()
is running, witch takes at least one seccond to finish. So in that case they should probalby run alongside each other (if that even is a thing).
CodePudding user response:
There maybe lot of ways for it.
Here's one way
- Define
__setattr__
method to send signal to buffer to update GUI. sleep
in main thread may block your GUI to update, so another thread used here.- A fixed and short timer to fresh/update GUI from the content of buffer.
# mygui.py
import threading
from tkinter import Tk, Label, Button
from mygame import p1, play_game, buffer
def rungame():
threading.Thread(target=play_game, args=(), daemon=True).start()
def update():
if buffer:
attribute, value = buffer.pop(0)
if attribute == 'health':
health_label.configure(text=f"health: {value}")
health_label.update()
elif attribute == 'mana':
mana_label.configure(text=f'mana: {value}')
mana_label.update()
root.after(100, update)
def gui_widgets():
health_label = Label(root, text=f"health:", width=20)
health_label.grid(column=0, row=0)
mana_label = Label(root, text=f"mana:", width=20)
mana_label.grid(column=0, row=1)
mybtn = Button(root, text="RUN GAME", command=rungame)
mybtn.grid(column=0, row=2)
return health_label, mana_label
root = Tk()
health_label, mana_label = gui_widgets()
root.after(100, update)
root.mainloop()
#my game.py
import time
class Player(object):
def __init__(self, health, mana):
self.health = health
self.mana = mana
def __setattr__(self, attribute, value):
super().__setattr__(attribute, value)
buffer.append((attribute, value))
def play_game():
for i in range(10):
p1.health = i
time.sleep(0.2)
p1.mana = 9 - i
time.sleep(0.2)
buffer = []
p1 = Player(10, 15)