Python: как установить параметры функции по имени со строкой

Я создаю основу для создания приложений с графическим интерфейсом пользователя с tkinter, и в моем коде есть класс Scene с функцией add(widget,params), которая создает виджет tkinter и добавляет его в словарь виджетов Scenes. Но я могу добавить только виджет, для которого я создал функцию add(), потому что разные виджеты имеют разные именованные параметры.

как мне сделать функцию, которая принимает словарь в форме {paramName,value}, который затем передал бы его функции виджета

Например

scene.add(button, {'command':Click, "text":"click me"} )

мой текущий код

import tkinter as tk

class scene():
    def __init__(self, title, width, height):
        self.widgets = {}
        self.title = title
        self.width = width
        self.height = height

    def add(self, name, type, widget, root, params):
        if name in self.widgets.keys():
            return
        else:
            if type == "button":
                width = params[0]
                height = params[1]
                text = params[2]
                self.widgets[name] = [widget(root,width=width, height=height,text=text),params[2:]]

    def get(self,name):
        if name in self.widgets.keys():
            return self.widgets[name][0]

person blankettripod    schedule 25.07.2020    source источник
comment
Возможно, вы захотите взглянуть на подход 4 принятого ответа здесь stackoverflow.com/questions/62050496/   -  person Atlas435    schedule 25.07.2020
comment
Вы знаете о **kwargs?   -  person MisterMiyagi    schedule 25.07.2020
comment
Не могли бы вы уточнить, какие из ваших кодов или описаний верны? В описании указано, что у вас есть Scene.add(self, widget, params), в коде указано, что у вас есть Scene.add(self, name, type, widget, root, params). В описании говорится, что вы хотите передать словарь {paramName,value}, который является набором, но код показывает правильный словарь.   -  person MisterMiyagi    schedule 25.07.2020
comment
Надеюсь, я правильно понял ваш вопрос. Если дубликат не отвечает на то, что вы пытались спросить, пожалуйста, отредактируйте, чтобы уточнить, и пингуйте меня (например, @tripleee), чтобы получить дубликат удален.   -  person tripleee    schedule 25.07.2020
comment
извините за дубликат, я не смог его найти при поиске ответа   -  person blankettripod    schedule 25.07.2020
comment
также ответ на этой странице заключался в том, как получить их из dict (name = thing). Я спрашивал его другим способом, например, diction = {name: thing} foo (diction), который вернет name = 'thing'   -  person blankettripod    schedule 25.07.2020
comment
dict(name="thing") и {"name" : "thing"} производят точно такое же значение.   -  person MisterMiyagi    schedule 25.07.2020
comment
я имел в виду, что этот ответ пошел от dict (name = thing) к {name: thing}, тогда как мой должен был перейти от {name: thing} к name = thing not dict (name = thing)   -  person blankettripod    schedule 25.07.2020


Ответы (1)


Вы можете использовать setattr. См. Пример ниже, где я определил предложение if для общей строки:

from tkinter import Tk, Button

class scene():
    def __init__(self, title, width, height):
        self.widgets = {}
        self.title = title
        self.width = width
        self.height = height

    def add(self, name, type, widget, root, params, attributes={}):
        if name in self.widgets.keys():
            return
        else:
            if type == "button":
                width = params[0]
                height = params[1]
                text = params[2]
                self.widgets[name] = [widget(root,width=width, height=height,text=text),params[2:]]
            elif type == "generic":
                width = params[0]
                height = params[1]
                text = params[2]
                widget_obj = widget(root,width=width, height=height,text=text)
                for key, val in attributes.items():
                    setattr(widget_obj, key, val)
                self.widgets[name]=[widget_obj,params[2:]]

    def get(self,name):
        if name in self.widgets.keys():
            return self.widgets[name][0]

# Create intance of tkinter
root = Tk(className = 'Python Examples - Window 0')
root.geometry("600x700")
root.resizable(0,0)

# Call class
sc=scene("Some title", 100, 100)
sc.add("button_widget", "button", Button, root, [10, 10, "some text"])
sc.add("button_widget2", "generic", Button, root, [10, 10, "some text"], {"command": "click", "text": "click me"})
person David Duran    schedule 25.07.2020