从要位于框架内的条目中获取值

2024-10-02 12:38:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有自动生成的帧。这些框架包含标签等对象,并且仅包含一个条目。 我使用以下命令来识别条目:

          for widget in FrameCalc.winfo_children():
             print("widget.winfo_children()[4]", widget.winfo_children()[4])

这给了我这个

          .! toplevel.labels.! frame2.! entry

如何获取目标条目中包含的值? 提前感谢您抽出时间


Tags: 对象in命令框架forlabels条目标签
2条回答

欢迎来到Stack Overflow社区

在您的情况下,您可以根据需要使用SrtingVar()(holing string)、IntVar()(holing integer)、DoubleVar()(holding float)或BooleanVar()(holding boolean value)中的任何一种,并将textvariable分配给entry小部件。然后,您可以将这些变量附加到列表中,并在需要时使用.get()方法检索其内容。下面是一个示例,使用循环创建许多带有StringVar()的条目,然后获取它们的值

from tkinter import *

root = Tk()

def display(ent):
    global disp, var_list
    disp.set(var_list[ent].get())

var_list = []
for i in range (0, 5):
    var = StringVar()
    entry = Entry(root, textvariable = var)
    var_list.append(var)
    entry.pack()
    button = Button(root, text = "Show", command =  lambda ent = i: display(ent))
    button.pack()
    
disp = StringVar()
label = Label(root, textvariable = disp)
label.pack()

root.mainloop()

我相信这就是你想要的答案

  • 使用isinstance()检查小部件类型
  • 使用get()返回值

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()

这个概念也可以转化为一个实用程序,这样你就有了一个动态的系统,从你想要的任何地方开始寻找你想要的东西。我肯定会认为,每次需要找到特定的实例类型时,最好重写上面的多维循环(在孙子身上停止)。p>

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()

console output

相关问题 更多 >

    热门问题