python - 如何在 Tkinter 中显示对类对象的每一次更改?
问题描述
我在两个文件中有这个游戏的骨架。
第一个文件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()
第二个文件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)
游戏在 gui 上显示开始统计数据,单击按钮后显示最终结果。我希望 gui 显示p1
发生时所做的每一个属性更改play_game()
。我该怎么做?
编辑:我热衷于保留两个单独的文件,以便该程序更具可扩展性。
我不确定这是否可能,但我想如果我可以gui_widgets()
连续运行(例如每 0,1 秒)它可能会按预期工作。我仍然明白这可能是不可能的,因为 tkinter 似乎每次play_game()
运行时都在等待,女巫至少需要一秒钟才能完成。因此,在这种情况下,他们可能应该彼此并肩运行(如果那是一件事的话)。
解决方案
可能有很多方法。
这是一种方法
- 定义
__setattr__
向缓冲区发送信号以更新 GUI 的方法。 sleep
在主线程中可能会阻止您的 GUI 更新,所以这里使用了另一个线程。- 从缓冲区内容刷新/更新 GUI 的固定且短的计时器。
# 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)
推荐阅读
- python - 如何在 Python dict 中的值之前附加一个键?
- mysql - MySQL 需要 6 秒来计算 100k 条记录中的条件
- android - how to apply ripple effect on textview when already background set
- javascript - React: Mutating state through setTimeout return wrong results
- azure - 在 azure function app 中使用 c# 代码覆盖 host.json 文件的 functiontimeout
- kerberos - 使用空手道访问启用 keberos 的 Rest 服务
- ios - 在可访问性的智能反转模式中跳过特定颜色
- google-apps-script - 如何获取包含 A 列中文本的行的范围
- node.js - MongoDB合并两个相同的模式集合
- angular - 如何根据标头响应循环休息请求