我正在將 Python/tkinter 用于 GUI,但我發現了一個奇怪的行為。
我正在構建一個非常小的對話框來為我的應用程式選擇語言。然后在關閉它時,我發現對話框中的“結果”變數消失了。
這是片段:
import tkinter as tk
from tkinter.simpledialog import Dialog
from tkinter import ttk, LEFT, ACTIVE
from tkinter.ttk import Button, Frame
class LanguageDialog(Dialog):
lang_dict = {
'italiano': 'it',
'espa?ol': 'es',
'english': 'en',
'galego': 'gl',
}
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.selected_language = tk.StringVar()
self.result = 'en' # default value
def _on_cmb_change(self, event):
"""
Keeps updated the result variable with the code I want in the end
"""
print(self.lang_dict[self.selected_language.get()])
self.result = self.lang_dict[self.selected_language.get()]
def body(self, master):
self.selected_language = tk.StringVar()
ops = tuple(self.lang_dict.keys())
cmb_lang = ttk.Combobox(self, values=ops, state='readonly',
textvariable=self.selected_language)
cmb_lang.pack(side=tk.TOP)
cmb_lang.bind('<<ComboboxSelected>>', self._on_cmb_change)
def buttonbox(self):
"""add standard button box.
override if you do not want the standard buttons
"""
box = Frame(self)
w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
self.bind("<Return>", self.ok)
box.pack()
if __name__ == '__main__':
root = tk.Tk()
d = LanguageDialog(root)
print(f'After the dialog, {d.result}')
root.mainloop()
我相信我對如何使用對話框有一些誤解。在除錯時,我看到對話框觸發了一些 destroy() 方法,但似乎它可能再次來到初始化程式并執行
self.result = 'en'
行,即使我沒有通過 LanguageDialog() 再次創建或呼叫對話框。
我在網上搜索了類似的示例,發現它們以相同的方式使用對話框,例如,here
uj5u.com熱心網友回復:
請和 root.mainloop 到您的代碼末尾。
if __name__ == '__main__':
root = tk.Tk()
d = LanguageDialog(root)
print(f'After the dialog, {d.result}')
root.mainloop()
uj5u.com熱心網友回復:
我用全域變數解決了這個問題,這不是最好的方法,但這就是我現在能想到的,下面的代碼。希望它對你有所幫助。
import tkinter as tk
from tkinter.simpledialog import Dialog
from tkinter import ttk, LEFT, ACTIVE
from tkinter.ttk import Button, Frame
value_global = 'en'
class LanguageDialog(Dialog):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.selected_language = tk.StringVar()
self.result = value_global # default value
lang_dict = {
'italiano': 'it',
'espa?ol': 'es',
'english': 'en',
'galego': 'gl',
}
def _on_cmb_change(self, event):
"""
Keeps updated the result variable with the code I want in the end
"""
print(self.lang_dict[self.selected_language.get()])
self.result = self.lang_dict[self.selected_language.get()]
global value_global
value_global= self.result
def body(self, master):
self.selected_language = tk.StringVar()
ops = tuple(self.lang_dict.keys())
cmb_lang = ttk.Combobox(self, values=ops, state='readonly',
textvariable=self.selected_language)
cmb_lang.pack(side=tk.TOP)
cmb_lang.bind('<<ComboboxSelected>>', self._on_cmb_change)
def buttonbox(self):
"""add standard button box.
override if you do not want the standard buttons
"""
box = Frame(self)
w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
self.bind("<Return>", self.ok)
box.pack()
if __name__ == '__main__':
root = tk.Tk()
d = LanguageDialog(root)
print(f'After the dialog, {d.result}')
root.mainloop()
uj5u.com熱心網友回復:
如果您查看simpledialog.Dialog類的源代碼,您會發現wait_window()在其末尾執行時Dialog.__init__()試圖使視窗像一個模態對話框。
所以super().__init__(...)里面LanguageDialog.__init__()不會回傳,直到對話框關閉。當對話框關閉時,self.result重置為“en”。
您應該將該行移動到(就像)self.result = 'en'的開頭,然后洗掉該功能。body()self.selected_language__init__()
下面是修改后的代碼:
import tkinter as tk
from tkinter.simpledialog import Dialog
from tkinter import ttk, LEFT, ACTIVE
from tkinter.ttk import Button, Frame
class LanguageDialog(Dialog):
lang_dict = {
'italiano': 'it',
'espa?ol': 'es',
'english': 'en',
'galego': 'gl',
}
def _on_cmb_change(self, event):
"""
Keeps updated the result variable with the code I want in the end
"""
print(self.lang_dict[self.selected_language.get()])
self.result = self.lang_dict[self.selected_language.get()]
def body(self, master):
self.selected_language = tk.StringVar()
# initial self.result to 'en' here
self.result = 'en' # default value
ops = tuple(self.lang_dict.keys())
cmb_lang = ttk.Combobox(self, values=ops, state='readonly',
textvariable=self.selected_language)
cmb_lang.pack(side=tk.TOP)
cmb_lang.bind('<<ComboboxSelected>>', self._on_cmb_change)
def buttonbox(self):
"""add standard button box.
override if you do not want the standard buttons
"""
box = Frame(self)
w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
self.bind("<Return>", self.ok)
box.pack()
if __name__ == '__main__':
root = tk.Tk()
root.withdraw() # hide the root window
d = LanguageDialog(root)
print(f'After the dialog, {d.result}')
#root.mainloop() # don't need to call mainloop()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497214.html
標籤:Python python-3.x tkinter 对话
