python - tkinter 实时数据标签更改(取决于用户输入)
问题描述
所以我正在尝试编写一个中世纪的 RPG,我正在使用 Tkinter 来显示用户的健康、耐力、控制等。我正在努力让用户的基本耐力为 50,如果他们按下点击“攻击”按钮,体力会减少5,随着时间的推移慢慢恢复,(如果当前STM低于50,它开始每毫秒增加1点,直到再次达到50)。每次按下“攻击”时,减法都会起作用,但我似乎根本无法让我的if (stamina < stmmax):
陈述起作用。有小费吗?
import time
import sys
import random as rand
from tkinter import *
# -----------------------------------Custom Functions---------------------------------------
def dramaticeffect():
time.sleep(2)
print("")
def delay_print(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.1)
time.sleep(1)
print("")
def die():
delay_print("Your adventure has ended, " + name + ".")
sys.exit()
def endprogress():
print("[This is the end of the game's current progress]")
die()
def actionlog():
global log
log = log + 1
action = True
print("\t inputlog#" + str(log))
logcheck.configure(text="*")
def attack():
global stamina
stamina = int(stamina - 5)
print(stamina)
stmcount = ("Stamina: " + str(stamina) + "/" + str(stmmax))
stmmeter.configure(text=stmcount)
live = True
actionlog()
'''
def uistart():
window = Tk()
window.title("Fate of all")
uidefault()
def uidefault():
label = Label(window, text="Testing")
entry = Entry(window)
button1 = Button(window, text="Enter")
button2 = Button(window, text="SB_1")
button3 = Button(window, text="SB_2")
def uihalt():
label.pack()
entry.pack()
button1.pack()
button2.pack()
button3.pack()
window.mainloop()
'''
# ---------------------------------------Gameplay-------------------------------------------
window = Tk()
window.title("Fate of all")
log = int(0)
live = False
stmmod = int(0)
stamina = int(50 + stmmod)
stmmax = int(50 + stmmod)
if (stamina < stmmax):
time.sleep(0.1)
stamina = stamina + 1
print(stamina)
stmcount = ("Stamina: " + str(stamina) + "/" + str(stmmax))
#damage
stmmeter = Label(window, text=stmcount)
entry = Entry(window)
button1 = Button(window, text="Enter", command=actionlog)
button2 = Button(window, text="Attack", command=attack)
button3 = Button(window, text="Defend", command=actionlog)
logcheck = Label(window, text="")
stmmeter.pack()
entry.pack()
button1.pack()
button2.pack()
button3.pack()
logcheck.pack()
window.mainloop()
#name = input("This is the tale of... ")
#dramaticeffect()
#delay_print('''
#Greetings, Sir ''' + name + ''', I am a humble traveler like you. Allow me to tell you a
#story, a tale of a friend or two.
#''')
#delay_print('''
#\t It is a desolate time, there are wars between sword and stone all
#across the land...and you were but a simple knight trying to survive,
#but everything changed once you entered the outer lands of Newlochia.
#''')
#delay_print("Fate of all is in your hands.")
#dramaticeffect()
解决方案
首先,当您在 Tk 实例中有 if 语句时,显然它只会运行一次,其次,time.sleep(some_num)
与 GUI 应用程序一起使用不是一个好主意,因此最好root.after(millis, func)
在函数中使用和使用它。它还取决于您希望何时何地运行您的函数。如果您希望它在角色受到攻击时运行,那么您可以执行以下操作并将其绑定到按钮或在已绑定到您的按钮的其他函数中调用它:
def regenerate():
global stamina
if stamina < stmmax:
stamina += 1
root.after(60, regenerate)
# root.after works with millis so it is better to use
# a bigger number like 60 rather than 1
更新:我尝试实现您的代码,我相信这更有可能是您想要的:
from tkinter import *
root = Tk()
root.title("Game!")
root.geometry("400x300")
stamina, stmmax = 50, 50
regenerating = False
lbl = Label(root, text=f"Stamina: {stamina}")
lbl.pack(pady=15)
def regenerate():
global regenerating
if not regenerating:
regenerating = True
def add_stamina():
global stamina, regenerating
if stamina < stmmax:
stamina += 1
lbl.config(text=f"Stamina: {stamina}")
root.after(100, add_stamina)
else:
regenerating = False
add_stamina()
def attack():
global stamina
stamina -= 15
lbl.config(text=f"Stamina: {stamina}")
regenerate()
Button(root, text="Attack!", command=attack).pack()
root.mainloop()
我还尝试使用while True: (smth)
循环编写函数并使用threading.Thread
不断检查当前耐力是否小于最大耐力,但似乎在每次试验中代码都失败并且 GUI 冻结。尽管仅使用普通功能是更好的方法。
更新:很抱歉有很多更新。考虑到代码我不满意,因为它不是很干净,所以为了优化我做了一个更好的版本。同样在您配置标签很多的情况下,我宁愿为标签设置一个文本变量。没有文本变量的代码:
from tkinter import *
root = Tk()
root.title("Game!")
root.geometry("400x300")
stamina, stmmax = 50, 50
regenerating = False
lbl = Label(root, text=f"Stamina: {stamina}")
lbl.pack(pady=15)
def add_stamina():
global stamina, regenerating
if stamina < stmmax:
stamina += 1
lbl.config(text=f"Stamina: {stamina}")
root.after(100, add_stamina)
else:
regenerating = False
def attack():
global stamina, regenerating
stamina -= 15
lbl.config(text=f"Stamina: {stamina}")
if not regenerating:
regenerating = True
add_stamina()
Button(root, text="Attack!", command=attack).pack()
root.mainloop()
与文本变量相同的代码:
from tkinter import *
root = Tk()
root.title("Game!")
root.geometry("400x300")
stamina, stmmax = 50, 50
regenerating = False
stm_var = StringVar()
stm_var.set(f"Stamina: {stamina}")
lbl = Label(root, textvariable=stm_var)
lbl.pack(pady=15)
def add_stamina():
global stamina, regenerating
if stamina < stmmax:
stamina += 1
stm_var.set(f"Stamina: {stamina}")
root.after(100, add_stamina)
else:
regenerating = False
def attack():
global stamina, regenerating
stamina -= 15
stm_var.set(f"Stamina: {stamina}")
if not regenerating:
regenerating = True
add_stamina()
Button(root, text="Attack!", command=attack).pack()
root.mainloop()
推荐阅读
- java - Java URL 检查 404 HTTP 响应代码
- sql - 如何根据同一个表中的外键将一个表与自身连接起来?
- powershell - powershell - 仅用目标目录中的新文件替换旧文件
- r - 用于匿名搜索的 YouTube 数据 API
- laravel - 在 laravel 7 中创建编辑模式
- javascript - 新窗口从第三方站点返回到我的站点后 PHP 会话发生变化
- ruby-on-rails - 嵌套关联不保存
- javascript - java脚本执行顺序
- html - 具有相同高度的子 div(inline-table 和 table-cell )
- arrays - 在 perl 中,如何提取一个已经存在于数组数组中的子数组?