如何获取对实例属性的引用,以及如何从外部修改其值

时间:2018-11-19 22:29:09

标签: python oop reference

我正在使用tkinter中的应用程序。我在UI中有很多Entry窗口小部件,在App Engine中有一些类。我需要将这些条目的tkinter变量绑定到实例属性。

即:

class Pipe(Variable):
    """class for pipes"""

    def __init__(self):
        self.diameter = 0
        self.variables = {}

pipe1 = Pipe(self)
pipe2 = Pipe(self)

我想将一个条目的值绑定到pipe1.diameter,并将另一个条目的值绑定到pipe2.diameter。我正在通过trace函数执行操作,其中lambda语句指向一个函数,该函数标识条目,并使用适用于每个实例的字典将值从条目传递到字典值。像这样生成字典,然后将其作为实例属性传递:

def pipe1_vars(object_):
    variables = {
        'ui_variable_name_for_pipe1_diameter': [object_.diameter]
    }
    return variables

def pipe2_vars(object_):
    variables = {
        'ui_variable_name_for_pipe2_diameter': [object_.diameter]
    }
    return variables

pipe1.variables = pipe1_vars(pipe1)
pipe2.variables = pipe2_vars(pipe2)

很遗憾,Variable类方法(分配值)无法正常工作。

class Variable():
    def set_var_value(variable_name, value):
        ui_variable = tkinterbuilder.get_variable(variable_name)
        self.variables[variable_name][0] = value
        if ui_variable.get() != value:
            ui_variable.set(value)

很显然,self.variables[variable_name][0]self.diameter不同。字典值正在更改,但是instance.diameter保持不变。

如何将真实实例属性传递给此方法,而不是将其复制为字典值?

我假设对我的应用程序来说,构建类似于这些字典的内容很重要,因为我需要将不同管道的相似属性绑定到不同条目,因此必须在Pipe()外部进行定义类。我不知道是否应该将词典更改为其他内容,或者应该重新构建这些功能以构建词典。我用尽了所有的想法,问谷歌什么。

代码非常复杂,我只发布了最重要的元素,但是如果还有其他细节很重要,请在注释中注明。

1 个答案:

答案 0 :(得分:0)

如果Pipe属性的数量很少,请为其设置属性,并在创建Pipe对象时,将其对应的tk绑定变量传递给它:

import tkinter as tk
from tkinter import Tk, ttk

root = Tk()
var_e1 = tk.StringVar()

def print_e1():
    print(var_e1.get())

def inc_e1():
    var_e1.set(int(var_e1.get())+1)

class Pipe():
    def __init__(self, tkvar):
        self.tkvar = tkvar
        tkvar.set('')

    @property
    def diameter(self):
        return self.tkvar.get()

    @diameter.setter
    def diameter(self, value):
        self.tkvar.set(value)

e1 = tk.Entry(root, textvariable=var_e1)
b1 = tk.Button(root, text='Print e1', command=print_e1)
b2 = tk.Button(root, text='Increment e1', command=inc_e1)

e1.pack(side=tk.LEFT)
b1.pack()
b2.pack()

p1 = Pipe(var_e1)
p1.diameter = 200

root.mainloop()