繁体   English   中英

Tkinter 应用程序在执行后没有立即响应

[英]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循环中。 发生这种情况是因为您尝试将integerstring进行比较。 另外,我没有转发 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_quantitySpinbox.get()的引用,因此counter != dice_quantity始终评估为 True。 所以这是一个无限的while循环。

所以要修复它:

  • command选项中使用lambdacommand=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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM