[英]Tkinter app does not respond immediately after execution
现在尝试学习 python。 开始使用 tkinter 构建一些 gui。 现在我遇到的问题是,在我运行我的应用程序后,程序没有响应。 在 ide 中未发现任何错误。 我认为问题出在我的 function卷中。 从rollbtn中删除命令参数允许 gui 运行。 任何想法,将不胜感激。
亲切的问候 DachsAdmin
# Author: DachsAdmin
# ------------------------------------------------------------------------packages and variables
from tkinter import *
import random
app = Tk()
app.title("Dice Tool")
app.geometry("600x400+700+300")
app.resizable(width=False, height=False)
#app.iconbitmap("C:\PYTHON\Code\img\dice.ico")
# ----------------------------------------------------------------------------------------------------functions
def roll(dice_type, dice_quantity):
dice_result = []
print(dice_type)
dice_type = dice_type()[1:]
dice_type = int(dice_type)
counter = 0
while counter != dice_quantity:
dice_result.append(random.randrange(1, dice_type))
counter = counter + 1
for x in dice_result:
resultbox.insert(END, x + "\n")
resultbox.pack()
# ----------------------------------------------------------------------------------------------------coreWindow
frameleft = Frame(app, bg="grey")
frameleft.place(x=10, y=10, width=380, height=380)
resultbox = Text(frameleft)
resultbox.configure(state="disabled")
resultbox.place(x=10, y=10, width=360, height=360)
frameright = Frame(app, bg="grey")
frameright.place(x=410, y=10, width=180, height=380)
variable = StringVar(app)
variable.set("W6")
diceoptionmenu = OptionMenu(frameright, variable, "W3","W4","W6","W8","W10","W12")
diceoptionmenu.place(x=10, y=10, width=75, height=30)
dicequantity = Spinbox(frameright, from_=1, to=99)
dicequantity.place(x=95, y=10, width=75, height=30)
rollbtn = Button(frameright, text="Roll!", width=100, bg="white", command=roll(variable.get, dicequantity.get))
rollbtn.place(x=40, y=300, width=100, height=30)
exitbtn = Button(frameright, text="Exit", width=100, bg="white", command=app.quit)
exitbtn.place(x=40, y=340, width=100, height=30)
app.mainloop()
您的代码卡在了while
循环中。 发生这种情况是因为您尝试将integer
与string
进行比较。 另外,我没有转发 function ( dice_quantity.get, dict_type.get
),而是为您更改它。 我转发了 function 地址,然后我在roll
function 中调用了它。
import random
from tkinter import Tk, Frame, Text, StringVar, OptionMenu, Spinbox, Button, END
app = Tk()
app.title("Dice Tool")
app.geometry("600x400+700+300")
app.resizable(width=False, height=False)
def roll(dice_type, dice_quantity):
dice_result = []
dice_type = int(dice_type.get()[1:])
counter = 0
while counter != int(dice_quantity.get()):
dice_result.append(random.randrange(1, dice_type))
counter += 1
for x in dice_result:
resultbox.insert(END, x, "\n")
resultbox.pack()
frameleft = Frame(app, bg="grey")
frameleft.place(x=10, y=10, width=380, height=380)
resultbox = Text(frameleft)
resultbox.configure(state="disabled")
resultbox.place(x=10, y=10, width=360, height=360)
frameright = Frame(app, bg="grey")
frameright.place(x=410, y=10, width=180, height=380)
variable = StringVar(app)
variable.set("W6")
diceoptionmenu = OptionMenu(frameright, variable, "W3","W4","W6","W8","W10","W12")
diceoptionmenu.place(x=10, y=10, width=75, height=30)
dicequantity = Spinbox(frameright, from_=1, to=99)
dicequantity.place(x=95, y=10, width=75, height=30)
rollbtn = Button(frameright, text="Roll!", width=100, bg="white", command=roll(variable, dicequantity))
rollbtn.place(x=40, y=300, width=100, height=30)
exitbtn = Button(frameright, text="Exit", width=100, bg="white", command=app.quit)
exitbtn.place(x=40, y=340, width=100, height=30)
app.mainloop()
做这个:
rollbtn = Button(
frameright, text="Roll!", width=100, bg="white",
command=roll
)
和这个:
def roll():
dice_type = variable.get()
dice_quantity = dicequantity.get()
好的,抱歉没有进一步看。 一些变化:
def roll():
dice_type = variable.get()
dice_type = int(dice_type[1:])
dice_quantity = int(dicequantity.get())
dice_result = []
for i in range(dice_quantity):
dice_result.append(random.randrange(1, dice_type))
for x in dice_result:
resultbox.insert(END, str(x) + "\n")
消除:
resultbox.configure(state="disabled")
一些澄清(最初想保持简短:):
这是捕获函数(函数地址)'get',
'variable' 和 'dicequantity' 的:
command=roll(variable.get, dicequantity.get)
可以用 lambda 表达式解决:
command=lambda: roll(variable.get(), dicequantity.get())
为简单起见,直接使用 roll + 调用 get()
command=roll
...
def roll():
... = variable.get()
... = dicequantity.get()
关于 roll() 正文:问题是由于类型不匹配造成的:
混合 int 和 string,期待一个但得到另一个。
在动态语言中很容易混淆。
提示:查看变量的类型(如果不使用 IDE 等),
尝试使用:打印(类型(变量))。
最后,禁用 Text 小部件将禁止对其进行更新。
您可能希望禁用它,在更新之前启用它,
并在之后再次禁用它(以避免用户修改):
def roll():
...
resultbox.configure(state="normal")
for x in dice_result:
resultbox.insert(END, str(x) + "\n")
resultbox.configure(state="disabled")
一个提示:从命令行运行(例如“python3./MyScript.py”),
并查看错误消息:它们有很大帮助。
导致该问题的主要问题有两个:
rollbtn = Button(frameright, text="Roll,", width=100, bg="white". command=roll(variable,get. dicequantity.get))
roll()
function 将立即执行,而不是单击按钮时的预期。
while counter:= dice_quantity:
inside roll()
function。 由于dice_quantity
是Spinbox.get()
的引用,因此counter != dice_quantity
始终评估为 True。 所以这是一个无限的while循环。
所以要修复它:
在command
选项中使用lambda
: command=lambda: roll(variable.get(), dicequantity.get())
更新roll()
:
def roll(dice_type, dice_quantity):
print(dice_type, dice_quantity)
dice_type = int(dice_type[1:])
resultbox.config(state='normal')
for i in range(int(dice_quantity)):
x = random.randrange(1, dice_type)
resultbox.insert(END, str(x)+'\n')
resultbox.config(state='disabled')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.