[英]Tkinter app does not respond immediately after execution
tryin to learn python right now.现在尝试学习 python。 Starting to build some gui's with tkinter.
开始使用 tkinter 构建一些 gui。 Right now I got the problem that immediately after I run my app, the program does not respond.
现在我遇到的问题是,在我运行我的应用程序后,程序没有响应。 No errors seen in the ide.
在 ide 中未发现任何错误。 I think the problem is somewhere in my function roll .
我认为问题出在我的 function卷中。 Deleting the command paramater from the rollbtn allows the gui to run.
从rollbtn中删除命令参数允许 gui 运行。 Any ideas would be appreciated.
任何想法,将不胜感激。
With kind regards DachsAdmin亲切的问候 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()
Your code got stuck in the while
loop.您的代码卡在了
while
循环中。 This happened because you tried to compare an integer
to string
.发生这种情况是因为您尝试将
integer
与string
进行比较。 Also, instead of forwarding a function ( dice_quantity.get, dict_type.get
), I change it for you.另外,我没有转发 function (
dice_quantity.get, dict_type.get
),而是为您更改它。 I forward the function address and then I called it inside the roll
function.我转发了 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()
Do this:做这个:
rollbtn = Button(
frameright, text="Roll!", width=100, bg="white",
command=roll
)
and this:和这个:
def roll():
dice_type = variable.get()
dice_quantity = dicequantity.get()
Ok, sorry did not look further.好的,抱歉没有进一步看。 Some changes:
一些变化:
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")
Remove:消除:
resultbox.configure(state="disabled")
Some clarifications (initially wanted to keep it short:):一些澄清(最初想保持简短:):
This was capturing the functions (function addresses) 'get',这是捕获函数(函数地址)'get',
of 'variable' and 'dicequantity': 'variable' 和 'dicequantity' 的:
command=roll(variable.get, dicequantity.get)
Could solve with a lambda expression:可以用 lambda 表达式解决:
command=lambda: roll(variable.get(), dicequantity.get())
For simplicity, just used roll directly + called get() there为简单起见,直接使用 roll + 调用 get()
command=roll
...
def roll():
... = variable.get()
... = dicequantity.get()
About roll() body: The issues were due to type mismatches:关于 roll() 正文:问题是由于类型不匹配造成的:
mixing int and string, expecting one but getting the other.混合 int 和 string,期待一个但得到另一个。
It's easy to get mixed up in a dynamic language.在动态语言中很容易混淆。
Hint: to see a variable's type (if not using IDEs etc.),提示:查看变量的类型(如果不使用 IDE 等),
try using: print(type(variable)).尝试使用:打印(类型(变量))。
Finally, disabling the Text widget disallows updates to it.最后,禁用 Text 小部件将禁止对其进行更新。
You may want to start it disabled, enable it before updates,您可能希望禁用它,在更新之前启用它,
and disable it again after (to avoid user modifications):并在之后再次禁用它(以避免用户修改):
def roll():
...
resultbox.configure(state="normal")
for x in dice_result:
resultbox.insert(END, str(x) + "\n")
resultbox.configure(state="disabled")
One hint: Run from command line (eg "python3./MyScript.py"),一个提示:从命令行运行(例如“python3./MyScript.py”),
and watch the error messages: they help a lot.并查看错误消息:它们有很大帮助。
There are two main issues causing the problem:导致该问题的主要问题有两个:
rollbtn = Button(frameright, text="Roll,", width=100, bg="white". command=roll(variable,get. dicequantity.get))
roll()
function will be executed immediately, not what you expect when the button is clicked. roll()
function 将立即执行,而不是单击按钮时的预期。
while counter:= dice_quantity:
inside roll()
function. while counter:= dice_quantity:
inside roll()
function。 As dice_quantity
is a reference of Spinbox.get()
, counter != dice_quantity
always evaluated as True.由于
dice_quantity
是Spinbox.get()
的引用,因此counter != dice_quantity
始终评估为 True。 So it is an infinite while loop.所以这是一个无限的while循环。
So to fix it:所以要修复它:
Use lambda
in command
option: command=lambda: roll(variable.get(), dicequantity.get())
在
command
选项中使用lambda
: command=lambda: roll(variable.get(), dicequantity.get())
update roll()
:更新
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.