2017-07-13 30 views
1

我有一个基于tkinter的图形用户界面,其中有许多类的实例组合成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() 

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

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

+2

其不值得回答'if isinstance(child,MyClass):'是你想要我想的 –

+0

替代方案是'getattr(child,“MyMethod”,lambda:1)()'实际上可能更好 –

+0

FWIW你可以做'self.winfo_name()'而不是'tk.Widget.winfo_name(self)' –

回答

2

这里的@Joran比斯利的评论,充实出:

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 
+1

感谢您撰写并充实它。你的“简洁”例子为我提供了很好的帮助。 :) – bitsmack

+0

bitsmack:很高兴听到它的帮助。注意,通过使用'all(child.MyMethod()is None for child in my_class_children)',事情可能会更加简洁,尽管忽略了all()的返回值,这有点让人误解。 – martineau

相关问题