【问题标题】:How can I use a method on every instance of a single class?如何在单个类的每个实例上使用方法?
【发布时间】:2017-12-18 22:33:48
【问题描述】:

我有一个基于 tkinter 的 GUI,其中包含一个类的许多实例,这些实例被分组到一个 ttk.LabelFrame 中。该类继承自ttk.Frame,并使用.grid() 放置在LabelFrame 中。 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()

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

有没有一种干净的方式来做我想做的事?

【问题讨论】:

  • 它不值得回答if isinstance(child,MyClass):是你想要的我认为
  • 另一种选择是getattr(child,"MyMethod",lambda:1)(),实际上可能更好
  • FWIW 你可以使用self.winfo_name() 而不是tk.Widget.winfo_name(self)
  • @martineau:你说得对,我在处理动态库加载和类实例化时遇到困难时正在考虑其他事情......我将相应地编辑我的评论。
  • 谢谢,@JoranBeasley!这正是我正在寻找的。当我错过简单的时候我讨厌它:)

标签: python class oop object tkinter


【解决方案1】:

这是@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

【讨论】:

  • 感谢您撰写并充实它。您的“简洁”示例非常适合我。 :)
  • bitsmack:很高兴听到它有帮助。还要注意,使用all(child.MyMethod() is None for child in my_class_children) 可能会更简洁,尽管由于all() 的返回值被忽略了,所以会有些误导。
猜你喜欢
  • 1970-01-01
  • 2013-09-19
  • 2011-09-03
  • 2010-10-22
  • 2014-11-21
  • 2012-01-04
  • 2011-12-18
  • 2014-02-26
  • 1970-01-01
相关资源
最近更新 更多