エッセイをモデル化したGUIアプリケーションを開発しています。特に、ユーザーは新しいトピックを作成してから、そのトピックにメモを入力できます。現在、新しいトピックを作成する方法は2つあります。メニューのドロップダウンオプション(menuコマンド)とメイン画面のボタン(buttonコマンド)です。ボタンは「新しいトピック」というテキストで始まります。ユーザーがボタンを押すと、プログラムは新しいトピックを作成し、を使用してトピックに名前を付けるようにユーザーに求め、tkSimpleDialog.askstring
ボタンのテキストをトピックの名前とそのトピックのメモの数に設定します。次に、ボタンのコマンドが変更され、そのトピックにメモが追加されます。
プログラムの開発中に、私は最初にメニューコマンドが機能することを確認しました。正常に呼び出さaskstring
れ、入力を希望どおりに処理する新しいポップアップウィンドウが作成されます。ただし、ボタンコマンドを追加するとすぐにaskstring
、メニューコマンドを使用して呼び出しても、への呼び出しは失敗しました。askstringダイアログが表示されているはずのウィンドウが白く塗りつぶされ、プログラムがハングします。ボタンコマンドをコメントアウトすると、再び機能します。メニューコマンドをコメントアウトすると、ハングします。
メニューにコマンドを追加するコードは次のとおりです。
TopicBtn.menu.add_command(label="New Topic", underline=0,
command=self.newTopic)
newTopic()のコードは次のとおりです。
def newTopic(self, button=None):
""" Create a new topic. If a Button object is passed, associate that Button
with the new topic. Otherwise, create a new Button for the topic. """
topicPrompt = "What would you like to call your new topic?"
topicName = tkSimpleDialog.askstring("New Topic", topicPrompt)
if topicName in self.topics.keys():
print "Error: topic already exists"
else:
newTopic = {}
newTopic["name"] = topicName
newTopic["notes"] = []
newTopic["button"] = self.newTopicButton(newTopic, button)
self.topics[topicName] = newTopic
self.addToTopicLists(newTopic)
newTopicButton()のコードは次のとおりです。
def newTopicButton(self, topic, button=None):
""" If a Button object is passed, change its text to display the topic name.
Otherwise, create and grid a new Button with the topic name. """
if button is None:
button = Button(self.topicFrame)
index = len(self.topics)
button.grid(row=index/self.TOPICS_PER_ROW, column=(index %
self.TOPICS_PER_ROW), sticky=NSEW, padx=10, pady=10)
else:
button.unbind("<Button-1>")
buttonText = "%s\n0 notes" % topic["name"]
button.config(text=buttonText)
button.config(command=(lambda s=self, t=topic: s.addNoteToTopic(t)))
return button
そして最後に、ボタンコマンドのコードは次のとおりです。
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)
askstring
ラムダ式をボタンにバインドするとハングする理由を誰かが知っていますか?
編集:コメントをありがとう。動作を示す最小限の例を次に示します。
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()
button.bind("<Button-1>", (lambda e, s=self: s.newLabel()))
からに切り替えるbutton = Button(frame, text="askstring", command=(lambda s=self: s.newLabel()))
とバグが修正されることに注意してください(ただし、押されたボタンへの参照は表示されません)。この問題は、ラムダへの入力の1つとしてイベントをキャプチャすることに関係していると思います。