如何在单个类的每个实例上使用方法?

时间:2017-07-13 23:47:56

标签: python class oop object tkinter

我有一个基于tkinter的GUI,其中许多类的实例被分组为ttk.LabelFrame。该类继承自ttk.Frame,并使用LabelFrame放置在.grid()中。 LabelFrame还包含ttk.Labels

请看这个非常简单的例子:

import tkinter as tk
from tkinter import ttk

class MyClass(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
    def MyMethod(self):
        print(tk.Widget.winfo_name(self))

root = tk.Tk()
frame = ttk.LabelFrame(root, text="frame")
label = ttk.Label(frame, text="label")
class1 = MyClass(frame)
class2 = MyClass(frame)

print("class.MyMethod() calls:")
class1.MyMethod()
class2.MyMethod()

print("\ntkinter.Widget.nwinfo_children(frame):")
childlist = tk.Widget.winfo_children(frame)
print(childlist)

输出如下:

class.MyMethod() calls:
49250736
49252752

tkinter.Widget.nwinfo_children(frame):
[<tkinter.ttk.Label object .49250672.49252880>,
<__main__.MyClass object .49250672.49250736>,
<__main__.MyClass object .49250672.49252752>]

我想这样做:

for child in childlist:
    child.MyMethod()

由于标签不起作用。或者也许:

for child in childlist:
    {if this is a MyClass instance}:
        child.MyMethod()

但我不知道这是否朝着正确的方向发展。

有没有一种干净的方法可以做我想要的事情?

1 个答案:

答案 0 :(得分:2)

这是@Joran Beasley的评论,充实:

import tkinter as tk
from tkinter import ttk

class MyClass(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
    def MyMethod(self):
        print(self.winfo_name())

root = tk.Tk()
frame = ttk.LabelFrame(root, text="frame")
label = ttk.Label(frame, text="label")
class1 = MyClass(frame)
class2 = MyClass(frame)

print("class.MyMethod() calls:")
class1.MyMethod()
class2.MyMethod()

print("\ntkinter.Widget.nwinfo_children(frame):")
childlist = tk.Widget.winfo_children(frame)
print(childlist)

for child in childlist:
    if isinstance(child, MyClass):
        child.MyMethod()

输出:

class.MyMethod() calls:
!myclass
!myclass2

tkinter.Widget.nwinfo_children(frame):
[<tkinter.ttk.Label object .!labelframe.!label>, <__main__.MyClass object .!labelframe.!myclass>, <__main__.MyClass object .!labelframe.!myclass2>]
!myclass
!myclass2

或者可能更简洁一点:

my_class_children = [child for child in tk.Widget.winfo_children(frame)
                        if isinstance(child, MyClass)]
print(my_class_children)
for child in my_class_children:
    child.MyMethod()

输出:

[<__main__.MyClass object .!labelframe.!myclass>, <__main__.MyClass object .!labelframe.!myclass2>]
!myclass
!myclass2