<p>我相信这就是你想要的答案</p>
<ul>
<li>使用<code>isinstance()</code>检查小部件类型</li>
<li>使用<code>get()</code>返回值</li>
</ul>
<hr/>
<pre><code>import tkinter as tk
#a dummy widget for example purposes
class DummyWidget(tk.Frame):
def __init__(self, master, t, e, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text=t).grid(row=0, column=0)
ent = tk.Entry(self)
ent.grid(row=0, column=1)
ent.insert(0, e)
#extend root
class App(tk.Tk):
#application constants
TITLE = 'Application'
WIDTH, HEIGHT, X, Y = 800, 600, 50, 50
def __init__(self):
tk.Tk.__init__(self)
DummyWidget(self, "label 1", "entry 1").grid(row=0, column=0)
DummyWidget(self, "label 2", "entry 2").grid(row=1, column=0)
DummyWidget(self, "label 3", "entry 3").grid(row=2, column=0)
#this is the answer portion of the example
for widget in self.winfo_children():
for i, subwidget in enumerate(widget.winfo_children()):
if isinstance(subwidget, tk.Entry):
print(f'child {i} of widget', subwidget.get())
#properly initialize your app
if __name__ == '__main__':
app = App()
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}+{App.X}+{App.Y}')
#app.resizable(width=False, height=False)
app.mainloop()
</code></pre>
<p>这个概念也可以转化为一个实用程序,这样你就有了一个动态的系统,从你想要的任何地方开始寻找你想要的东西。我肯定会认为,每次需要找到特定的实例类型时,最好重写上面的多维循环(在孙子身上停止)。p>
<pre><code>import tkinter as tk
from dataclasses import dataclass
from typing import Type
#a dummy widget for example purposes
class DummyWidget(tk.Frame):
def __init__(self, master, t, e, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text=t).grid(row=0, column=0)
ent = tk.Entry(self)
ent.grid(row=0, column=1)
ent.insert(0, e)
#to illustrate inheritance
class DummyEntry(tk.Entry):
def __init__(self, master, text, **kwargs):
tk.Entry.__init__(self, master, **kwargs)
self.insert(0, text)
#used in Utils.GetInstancesAsDataFrom(...) to store individual widget data
@dataclass
class WidgetData_dc:
type: Type
parent: tk.Widget
childindex: int
path: str
class Utils:
""" GetInstancesFrom
deep search of every child, grandchild, etc.. for a specific widget type
@start ~ parent widget to start the search from
@wtype ~ the type of widget to find
@inst ~ used internally to pass the dictionary to this method's internal calls of itself
returns a dictionary of all found instances
"""
@staticmethod
def GetInstancesFrom(start, wtype, inst=None):
instances = dict() if inst is None else inst
for widget in start.winfo_children():
if isinstance(widget, wtype):
instances[f'{widget}'] = widget
Utils.GetInstancesFrom(widget, wtype, instances)
return instances
""" GetInstancesAsDataFrom
deep search of every child, grandchild, etc.. for a specific widget type
@start ~ parent widget to start the search from
@wtype ~ the type of widget to find
@inst ~ used internally to pass the dictionary to this method's internal calls of itself
returns a dictionary of all found instances
"""
@staticmethod
def GetInstancesAsDataFrom(start, wtype, inst=None):
instances = dict() if inst is None else inst
for i, widget in enumerate(start.winfo_children()):
if isinstance(widget, wtype):
instances[widget] = WidgetData_dc(type(widget), start, i, f'{widget}')
Utils.GetInstancesAsDataFrom(widget, wtype, instances)
return instances
#extend root
class App(tk.Tk):
#application constants
TITLE = 'Application'
WIDTH, HEIGHT, X, Y = 800, 600, 50, 50
def __init__(self):
tk.Tk.__init__(self)
#a bunch of junk instances for example purposes
DummyWidget(self, "label 1", "entry 1").grid(column=0)
DummyWidget(self, "label 2", "entry 2").grid(column=0)
DummyWidget(self, "label 3", "entry 3").grid(column=0)
DummyEntry(self, text='entry 4').grid(column=0) #this extends tk.Entry so it qualifies as a tk.Entry
#answer portion of the example
for path, widget in Utils.GetInstancesFrom(self, tk.Entry).items():
print(f'{path}: {widget.get()}')
print('') #skip a line
#alternate implementation
for widget, data in Utils.GetInstancesAsDataFrom(self, tk.Entry).items():
print(f'{data.parent}[{data.childindex}]:{data.type} has value "{widget.get()}"')
#properly initialize your app
if __name__ == '__main__':
app = App()
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}+{App.X}+{App.Y}')
#app.resizable(width=False, height=False)
app.mainloop()
</code></pre>
<p><a href="https://i.stack.imgur.com/5zLT5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5zLT5.png" alt="console output"/></a></p>