Python 当我从lambda调用tkSimpleDialog.askstring时,为什么Tkinter挂起?
我正在开发一个GUI应用程序来模拟一篇文章。除此之外,用户可以创建一个新主题,然后用注释填充该主题。目前,我有两种创建新主题的方法:通过菜单中的下拉选项(菜单命令)和主屏幕上的按钮(按钮命令)。按钮以文本“新主题”开始使用。当用户按下按钮时,程序生成一个新主题,要求用户使用Python 当我从lambda调用tkSimpleDialog.askstring时,为什么Tkinter挂起?,python,lambda,tkinter,Python,Lambda,Tkinter,我正在开发一个GUI应用程序来模拟一篇文章。除此之外,用户可以创建一个新主题,然后用注释填充该主题。目前,我有两种创建新主题的方法:通过菜单中的下拉选项(菜单命令)和主屏幕上的按钮(按钮命令)。按钮以文本“新主题”开始使用。当用户按下按钮时,程序生成一个新主题,要求用户使用tkSimpleDialog.askstring命名该主题,然后将按钮文本设置为该主题的名称和该主题中的注释数。然后,按钮的命令将更改为向该主题添加注释 在开发程序时,我首先验证了菜单命令是否有效。它成功地调用了askstri
tkSimpleDialog.askstring
命名该主题,然后将按钮文本设置为该主题的名称和该主题中的注释数。然后,按钮的命令将更改为向该主题添加注释
在开发程序时,我首先验证了菜单命令是否有效。它成功地调用了askstring
,创建了一个新的弹出窗口,以我想要的方式处理输入。但是,我一添加按钮命令,对askstring
的调用就失败了,即使是通过菜单命令调用。应该有askstring对话框的窗口变白,程序挂起。如果我注释掉按钮命令,它会再次工作。如果我注释掉菜单命令,它将挂起
下面是我将命令添加到菜单的代码:
TopicBtn.menu.add_command(label="New Topic", underline=0,
command=self.newTopic)
以下是newTopic()的代码:
以下是newTopicButton()的代码:
请注意,从
button.bind(“,(lambda e,s=self:s.newLabel())
切换到button=button(frame,text=“askstring”,command=(lambda s=self:s.newLabel())
修复了错误(但没有给我一个被按下的按钮的参考)。我认为问题与将事件捕获为lambda的输入之一有关。我找到了一个解决方法。从最简单的示例测试来看,问题似乎来自单独调用bind,从而接受事件作为lambda的输入。如果有人能解释为什么会发生这种情况,我会接受他们的答案,而不是我的答案,但我现在会接受这个答案
解决方法不是使用单独的绑定函数,而是创建一个按钮数组,然后将数组中的正确条目作为参数传递给lambda函数(不能传递按钮本身,因为它是在具有lambda函数的行中创建的)
代码如下:
from Tkinter import *
import tkSimpleDialog
class Min():
def __init__(self, master=None):
root = master
frame = Frame(root)
frame.pack()
buttons = [None] * 2
for i in range (2):
buttons[i] = Button(frame, text="askstring",
command=(lambda s=self, var=i: s.newLabel(buttons[var])))
buttons[i].grid()
def newLabel(self, button):
label = tkSimpleDialog.askstring("New Label", "What should the label be?")
button.config(text=label)
print label
root = Tk()
m = Min(root)
root.mainloop()
您在这里遇到的问题是由于您正在使用的对话框中调用了
wait\u window
(您自己从来没有调用过它,但实现该对话框的代码却调用了它)。例如,以下代码在(可能)两次单击按钮后复制了该问题:
import Tkinter
def test(event=None):
tl = Tkinter.Toplevel()
tl.wait_window(tl)
root = Tkinter.Tk()
btn = Tkinter.Button(text=u'hi')
btn.bind('<Button-1>', test)
btn.pack(padx=10, pady=10)
root.mainloop()
从所包含的来源很难判断。尝试用(新的)常规方法替换
lambda
express,看看情况是否发生了变化。解决这一问题的最佳方法是首先构造一个简化的示例,给出与您现在遇到的相同的问题。到那时,你可能会发现你的错误,否则就用它更新你的问题。谢谢,我想Tkinter机器中发生了一些我不理解的事情。与阵列相比,我更喜欢两步过程。我假设btn['command']=myCommand
等同于btn.config(command=myCommand)
,对吗?
for col in range(self.TOPICS_PER_ROW):
button = Button(self.topicFrame, text="New Topic")
button.bind("<Button-1>", (lambda e, s=self: s.newTopic(e.widget)))
button.grid(row=0, column=col, sticky=NSEW, padx=10, pady=10)
from Tkinter import *
import tkSimpleDialog
class Min():
def __init__(self, master=None):
root = master
frame = Frame(root)
frame.pack()
button = Button(frame, text="askstring")
button.bind("<Button-1>", (lambda e, s=self: s.newLabel()))
button.grid()
def newLabel(self):
label = tkSimpleDialog.askstring("New Label", "What should the label be?")
print label
root = Tk()
m = Min(root)
root.mainloop()
from Tkinter import *
import tkSimpleDialog
class Min():
def __init__(self, master=None):
root = master
frame = Frame(root)
frame.pack()
buttons = [None] * 2
for i in range (2):
buttons[i] = Button(frame, text="askstring",
command=(lambda s=self, var=i: s.newLabel(buttons[var])))
buttons[i].grid()
def newLabel(self, button):
label = tkSimpleDialog.askstring("New Label", "What should the label be?")
button.config(text=label)
print label
root = Tk()
m = Min(root)
root.mainloop()
import Tkinter
def test(event=None):
tl = Tkinter.Toplevel()
tl.wait_window(tl)
root = Tkinter.Tk()
btn = Tkinter.Button(text=u'hi')
btn.bind('<Button-1>', test)
btn.pack(padx=10, pady=10)
root.mainloop()
for i in range(X):
btn = Tkinter.Button(text=u'%d' % i)
btn['command'] = lambda button=btn: some_callback(button)