如何pythonically传递参数到子类窗口小部件的方法?

时间:2014-07-18 15:43:21

标签: python tkinter

我将Label子类化为自动.pack()

import Tkinter as tk

class Label(tk.Label):
    def __init__(self, parent, *args, **kwargs):
        tk.Label.__init__(self, parent, *args, **kwargs)
        self.pack()

class App(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        l = Label(parent, text="word")

root = tk.Tk()
App(root).pack(side="top", fill="both", expand=True)
root.mainloop()

我希望能够在创建.pack()的实例时将参数传递给Label

如上所述,所有kwargs都会传递给父tk.Label,因此我无法将我的调用更新为l = Label(parent, text="word", side=tk.LEFT)(想法将**kwargs传递给{{ 1}}) - 由于.pack()tk.Frame.__init__)和side.pack())的未知选项,程序会崩溃。

我必须克服这一点的唯一想法是在调用它们之前手动将text中的参数发送到kwargstk.Frame.__init__

.pack()

它有效,但是有更好的(= pythonic)方法来实现这个目标吗?

1 个答案:

答案 0 :(得分:0)

如果你只是使用'text',那么每次都不需要列表。你可以这样做:

if 'text' in kwargs:
    initparms['text'] = kwargs['text']

使事情变得更好。

所以,如果你想一次做一大堆:

for param in ['text', 'another', 'option']:
    if param in kwargs:
        initparms[param] = kwargs[param]

此处不需要额外.get()次来电。

从Python 2.7开始,您可以使用以下方法实际创建列表:

{key:value for key,value in ...}

语法。所以:

initparms = {k:v for k,v in kwargs.items()
             if k in ['text','and','other','valid','params']}

然而,这有点难看,把这样的东西放在一个功能中间做其他事情有点不友好。

通常最好将事物分开以使功能变小。

VALID_LABEL_OPTIONS=['text', 'and', 'so', 'on']
VALID_PACK_OPTIONS = ['side', 'etc']

def extract_args(all_args, valid_keys):
    return {k:v for k,v in all_args.items()
            if k in valid_keys}

然后在__init__函数中执行以下操作:

initparms = extract_args(kwargs, VALID_LABEL_OPTIONS)
packparms = extract_args(kwargs, VALID_PACK_OPTIONS)

将逻辑的每个部分分开。

这有帮助吗?