【问题标题】:How to create and display multiple widgets using a loop (Tkinter)如何使用循环创建和显示多个小部件(Tkinter)
【发布时间】:2018-02-14 21:48:35
【问题描述】:

我正在创建一个在一个窗口中包含两个框架的程序。第一个有输入字段,第二个将创建一个图表。 我找到了一种从列表动态创建输入字段并相应地获取它们的值的方法,但我无法让它们显示在窗口上。当我运行程序时,它会显示一个空窗口。

我应该怎么做才能让标签和输入小部件显示在第一帧 (InputPage) 上?我尝试将“父母”更改为“自我”,但没有任何区别。我不太了解多框架应用程序中小部件的结构。

这是我的代码:

from tkinter import *

namesInput = ["first", "second", "third", "fourth", "fifth"]
entryInput = {}
labelInput = {}

root = Tk()

class ZorgplanGrafiek(Tk):

def __init__(self, *args, **kwargs):

    Tk.__init__(self, *args, **kwargs)
    container = Frame(self)

    container.pack(side="top", fill="both", expand = True)

    container.grid_rowconfigure(0, weight=1)
    container.grid_columnconfigure(0, weight=1)

    self.frames = {}

    for F in (InputPage, GraphPage):

        frame = F(container, self)

        self.frames[F] = frame

        frame.grid(row=0, column=0, sticky="nsew")

    self.show_frame(InputPage)

def show_frame(self, cont):

    frame = self.frames[cont]
    frame.tkraise()


class InputPage(Frame):

def __init__(self, parent, controller):
    Frame.__init__(self,parent)        
    label = Label(self, text="Zorgplan input")
    label.pack(pady=10,padx=10)        

    i = 0
    for name in namesInput:
        e = Entry(self)        
        entryInput[name] = e
        lb = Label(self, text=name)
        labelInput[name] = lb
        i += 1

    #def print_all_entries():
     #   for name in namesInput:
      #      print( entryInput[name].get())


class GraphPage(Frame):

def __init__(self, parent, controller):
    Frame.__init__(self, parent)
    label = Label(self, text="The graph will show here")
    label.pack(pady=10,padx=10)

    button = Button(self, text="Back to Home",
                        command=lambda: controller.show_frame(InputPage))
    button.pack()

app = ZorgplanGrafiek()
app.mainloop()

【问题讨论】:

  • 您正在创建两个窗口。一不为空。你问的是哪一个?

标签: python python-3.x tkinter widget


【解决方案1】:

首先删除您正在创建 2 个窗口的代码顶部的 root = Tk()。其次,您创建条目和标签小部件的循环不正确,因此它们不会显示在框架上,这就是为什么它们不会显示的答案。

试试这个:

class InputPage(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self,parent)        

        label = Label(self, text="Zorgplan input")
        label.grid(row=0, column=0, sticky ='n', columnspan =2)

        # i brought your variable in the class for example sake 

        namesInput = ["First:", "second:", "Third:", "Fourth:", "Fifth:"]

        self.entryWidgets = [] # we want to call this in another function so we assign it as self.variableName

        labelWidgets = []

        #LOOP TO CREATE WIDGETS
        for i in range(0, len(namesInput)):
            labelWidgets.append(Label(self, text = namesInput[i]))
            self.entryWidgets.append(Entry(self))
            labelWidgets[-1].grid(row= i+1, column =0, sticky='e')
            self.entryWidgets[-1].grid(row= i+1, column = 1, sticky='w')

        submit = Button(self, text = "Submit", command = self.getEntries)
        submit.grid(row = 6, column =0, columnspan =2)

    def getEntries(self):
        results = []

        for x in self.entryWidgets: # i.e for each widget in entryWidget list
            results.append(x.get())
        print(results)

代码说明:

我们正在迭代地为 namesInput 列表中的元素数量创建小部件。每次我们创建一个小部件时,我们都会将它添加到它们各自的列表中。例如,对于条目小部件,我们创建了一个名为 entryWidgets 的列表。我们将它们附加到一个列表中,以便我们以后想要对它们做某事时可以单独引用它们。

此外,我将 pack() 更改为 grid()。在我看来,网格方法更简洁,让我们可以更好地控制窗口的布局。

注意 - 如果您正在努力理解我是如何以我的方式“网格化”小部件的,我只是画了一个小部件的快速草图,其中的坐标代表它们的行和列,然后从那里开始很容易看出如何在 for 循环中操作网格设置。

截图:

【讨论】:

    猜你喜欢
    • 2015-06-04
    • 2020-11-19
    • 2015-01-19
    • 2014-04-18
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多