Как получить ссылку на атрибут экземпляра и изменить его значение извне - PullRequest
0 голосов
/ 20 ноября 2018

Я работаю над приложением в tkinter. У меня есть много виджетов Entry в пользовательском интерфейсе и несколько классов в движке приложения. Мне нужно связать переменные 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 голосов
/ 21 ноября 2018

Если количество атрибутов 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...