我想要一个通用方法来改变tkinter变量的值。我希望能够从菜单选项中执行此操作,该选项会显示一个新对话框,该对话框来自可用于不同变量的通用方法。我到目前为止的代码如下:
import sys
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import sequencer as seq
class View(ttk.Frame):
"""Main Gui class"""
def __init__(self, master = None):
ttk.Frame.__init__(self, master, borderwidth=5, width=450, height=500)
self.master = master
self.grid(column=0, row=0, sticky=(N, S, E, W))
self.columnconfigure(0, weight=1)
###############################
### User editable variables ###
self.precision = IntVar(value=4, name='precision')
self.sensitivity = IntVar(value = 50, name='sensitivity')
### User editable variables ###
###############################
self.create_menus()
def create_menus(self):
"""Produces the menu layout for the main window"""
self.master.option_add('*tearOff', FALSE)
self.menubar = Menu(self.master)
self.master['menu'] = self.menubar
# Menu Variables
menu_file = Menu(self.menubar)
menu_edit = Menu(self.menubar)
# Add the menus to the menubar and assign their variables
self.menubar.add_cascade(menu=menu_file, label="File")
self.menubar.add_cascade(menu=menu_edit, label = "Edit")
### ADD COMMANDS TO THE MENUES ###
### File ###
menu_file.add_command(label="Quit", command=self.master.destroy)
### Edit ###
menu_edit.add_command(label="Backbone", command=lambda : self.edit_backbone())
menu_edit.add_command(label="Precision", command=lambda : self.precision.set(self.set_value_int("Precision")))
menu_edit.add_command(label="Sensitivity", command=lambda : self.sensitivity.set(self.set_value_int("Sensitivity")))
menu_edit.add_command(label="print precision", command=lambda : print(self.precision.get()))
menu_edit.add_command(label="print sensitivity", command=lambda : print(self.sensitivity.get()))
def set_value_int(self, name):
"""Standards dialog that return a user define value of a specific type"""
t = Toplevel(self)
t.title("Set " + name)
label = ttk.Label(t, text="Set "+name)
label.grid(row=0)
entry = ttk.Entry(t)
entry.grid(row=1)
cancel = ttk.Button(t, text="Cancel", command=lambda : t.destroy())
cancel.grid(column=0, row=2)
okey = ttk.Button(t, text="Okey", command=lambda : okey(entry.get()))
okey.grid(column=1, row=2)
def okey(value):
"""return value according to type"""
try:
t.destroy()
return int(value)
except:
self.error_box("value must be and integer")
def error_box(self, error_message="Unknown error"):
"""(Frame, String) -> None
Opens an window with an Okey button and a custom error message"""
t=Toplevel(self)
t.title("Error")
label = ttk.Label(t, text=error_message)
label.grid(row=0)
okey = ttk.Button(t, text="Okey", command=lambda : t.destroy())
okey.grid(row=1)
if __name__ == "__main__":
root = Tk()
root.title("Sequencer")
view = View(root)
root.mainloop()
print("End")
编辑 - > print xxxxxx命令纯粹用于测试目的,以检查值是否已更改。如果在尝试更改精度或灵敏度值之前执行这些操作,则它们按预期工作。
如果您尝试以我尝试的方式更改任何一个tkinter变量,它们将变为None类型,我无法理解为什么。我只能假设你不能以我的方式改变它们,但是如果没有为每个我想避免的变量分别设置方法,我就无法想到另一种方法。
Baicly我希望用户能够自定义变量的精度和灵敏度,并在代码中使用相同的方法来更改值。
额外但不一定至关重要: - 如果有一种方法可以定义变量应该在方法参数中的哪种类型,那将更好,因为我将有其他变量供用户稍后更改,它们将是不同类型。
非常感谢任何帮助。我试图尽可能地清楚,但如果没有,我会告诉我。
由于
答案 0 :(得分:1)
self.set_value_int
始终返回None,因此始终将变量设置为none。
不要尝试编写难以调试的复杂lambda,而是将所有逻辑放在函数中。有功能设置值。您需要做的就是告诉它要设置的变量:
menu_edit.add_command(label="Precision",
command=lambda name="Precision", var=self.precision: self.set_value_int(name, var))
...
def set_value_int(self, name, var):
...
def okey():
s = entry.get()
try:
var.set(int(s))
...