使用通用set_value()方法设置tkinter变量

时间:2014-01-12 13:28:25

标签: python variables types tkinter

我想要一个通用方法来改变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我希望用户能够自定义变量的精度和灵敏度,并在代码中使用相同的方法来更改值。

额外但不一定至关重要: - 如果有一种方法可以定义变量应该在方法参数中的哪种类型,那将更好,因为我将有其他变量供用户稍后更改,它们将是不同类型。

非常感谢任何帮助。我试图尽可能地清楚,但如果没有,我会告诉我。

由于

1 个答案:

答案 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))

        ...