Tkinter Python:如何使用框架小部件将我的标签彼此对齐?

问题描述 投票:0回答:2

我是编程新手。我在 Python 中使用 Tkinter。我试图做到这一点,以便我的程序中的标签将彼此并排(之间有一点空间,可能像 50 像素)。我想要并排的两个标签是:“成分”和“步骤”。我尝试创建一个框架,以便它们可以彼此相邻,但成分始终位于台阶上方,而不是并排。我查看了 StackOverflow 上的其他问题,但我无法安静地将它们应用到我的程序中。那么我可以让我的两个标签、步骤和成分并排放置,中间有一些空间吗?我会继续使用框架还是使用 .grid 或其他东西?

非常感谢任何帮助!如果您可以在代码中添加注释,以便我知道您在做什么,那就太好了!谢谢!

import Tkinter
class Cookbook(Tkinter.Tk):
    def __init__(self):
        Tkinter.Tk.__init__(self)
        self.title("Cookbook")
        self.geometry("500x500+0+0")

        self.button = []
        for r in range(1):
            for c in range(1):
                b = Button(self).grid(row=r,column=c)
                self.button.append(b)

class Button(Tkinter.Button):
    def __init__(self,parent):
        b = Tkinter.Button.__init__(self, parent, text="Add A New Recipie", height=8, width=15, command=self.make_window)

    def make_window(self):
        popwindow = IngredientAdder()
        popwindow.title_box()
        popwindow.ingredients_box()
        popwindow.steps_box()
        popwindow.init_gui()

class IngredientAdder(Tkinter.Tk):
    def __init__(self):
        Tkinter.Tk.__init__(self)
        self.title("Recipie")
        self.geometry("550x500")

    def title_box(self):
        #Frame for the Title Label and the Title Entry Box
        test = Tkinter.Frame(self, height=100, relief=Tkinter.SUNKEN)
        test.pack(anchor=Tkinter.NW,side=Tkinter.TOP)

        #putting in a Title LABEL and ENTRY BOX
        Tkinter.Label(test,text="Title:").pack(anchor=Tkinter.NW,side=Tkinter.LEFT)
        self.entry1 = Tkinter.Entry(test,width=450)
        self.entry1.pack(anchor=Tkinter.NW,side=Tkinter.TOP)

    def ingredients_box(self):
        #Frame for the Ingredients Label and the Ingredients Entry Boxes
        self.test2 = Tkinter.Frame(self, height=100,width=20, relief=Tkinter.SUNKEN)
        self.test2.pack(anchor=Tkinter.NW,side=Tkinter.TOP)

        #Put an Ingredients label at the top of the window and anchor it there
        Tkinter.Label(self.test2,text="Ingredients:").pack(anchor=Tkinter.NW,side=Tkinter.TOP)

    def steps_box(self):
        #Frame for the Steps Label and the Steps Textbox
        test3 = Tkinter.Frame(self, height=100,width=50, relief=Tkinter.SUNKEN)
        test3.pack(anchor=Tkinter.NE,side=Tkinter.RIGHT)

        #putting in an entry box and Steps label for the steps of the recepie
        Tkinter.Label(test3,text="Steps:").pack(anchor=Tkinter.N,side=Tkinter.TOP)
        self.entry2 = Tkinter.Text(test3,width=40,height=33,font="helvetica 12",padx=5,pady=5).pack(anchor=Tkinter.NE,side=Tkinter.TOP)

    def title_save(self):
         self.title_entries.append(self.entry1)

    def text_box(self):
         self.text_entries.append(self.entry2)

    # function to add new ingredients
def add_ingredient_entry(self):
        entry = Tkinter.Entry(self.test2)
        entry.pack(anchor=Tkinter.NW,side=Tkinter.TOP)
        self.ingredient_entries.append(entry)

    # get contents of all entry boxes
    def save_recipe(self):
        for words in self.title_entries:
            print words.get()
        for ingredient in self.ingredient_entries:
            print ingredient.get()
        for text in self.text_entries:
            print text.get('1.0','end')
       print "[Recipie saved]"

    # build initial widgets 
    def init_gui(self):
        # title saved in this array
        self.title_entries = []     

        # this is a list of ingredients entry boxes
        self.ingredient_entries = []

        #this saves the list in this array, hopefully
        self.text_entries = []

        #Making a frame at the bottom to put both buttons in line
        self.test4 = Tkinter.Frame(self,height=10, relief=Tkinter.SUNKEN)
        self.test4.pack(side=Tkinter.BOTTOM)

        #Put these two buttons at the bottom of the window and anchor them there
        Tkinter.Button(self.test4,text="Save recipe",command=self.save_recipe, width=15).pack(anchor=Tkinter.SE,side=Tkinter.RIGHT)
        Tkinter.Button(self.test4,text="Add ingredient",command=self.add_ingredient_entry, width=15).pack(anchor=Tkinter.NW,side=Tkinter.LEFT)

        #New ingredients will be added between the label and the buttons 
        self.add_ingredient_entry()

top = Cookbook()
top.mainloop()
python tkinter frame label
2个回答
0
投票

如果您希望两个标签并排放置,您可以简单地使用包管理器将它们打包到同一侧,如下所示:

testlabel.pack(side=Tkinter.LEFT)
testlabel2.pack(side=Tkinter.LEFT)

但是,首选方法是使用网格管理器来完成此类操作。要对齐两个标签,您可以执行以下操作:

testlabel.grid(row=0, column=0)
testlabel2.grid(row=0, column=1)

如果你正在谈论如何将它们与框架一起使用,那么会是这样的:

labelframe = Tkinter.Frame()
testlabel = Tkinter.Label(labelframe)
testlabel2 = Tkinter.Label(labelframe)
testlabel.grid(row=0, column=0)
testlabel2.grid(row=0, column=1)
labelframe.pack()

这会将两个标签组合在该框架内,然后您可以在主窗口中对齐。但是,如果您有一堆标签并且都希望它们像表格一样并排,您可能可以在主窗口中使用网格。当您想要将小部件分组在一起并将它们移动到与其他小部件相关的特定位置时,您倾向于使用框架。


0
投票

您需要做的第一件事是稍微改变您的编程风格。您将要求将一个小部件打包到创建该小部件的函数中,这使得管理您的代码变得非常困难。相反,创建小部件的函数的调用者应该负责打包(放置、网格化)它。

例如,代替:

def make_window(self):
    ...
    popwindow.ingredients_box()
    popwindow.steps_box()
    ...

def steps_box(self):
    #Frame for the Steps Label and the Steps Textbox
    test3 = Tkinter.Frame(self, height=100,width=50, relief=Tkinter.SUNKEN)
    test3.pack(anchor=Tkinter.NE,side=Tkinter.RIGHT)

你应该做这样的事情:

def make_window(self):
    ...
    ingredients_box = popwindow.ingredients_box(self)
    steps_box = popwindow.steps_box(self)
    ...
    ingredients_box.pack(side="left")
    steps_box.pack(side="right")

def ingredients_box(self, parent):
    #Frame for the Steps Label and the Steps Textbox
    test3 = Tkinter.Frame(parent, height=100,width=50, relief=Tkinter.SUNKEN)
    test3.pack(anchor=Tkinter.NE,side=Tkinter.RIGHT)
    return test3

这本身并不能解决你的问题,但它会让问题更容易解决。下一步是查看您的整体布局,并意识到使用网格是比使用包更自然的布局。

当您这样做时,只更改负责布局 GUI 的一个函数就变得非常简单,而不是更改尝试创建小部件并布局它们的无数函数。

这样,您就可以执行以下操作:

def make_window(self):
    ingredients_box = ...
    steps_box = ...
    ...

    ingredients_box.grid(row=1, column=0, sticky="nsew")
    steps_box.grid(row=1, column=1, sticky="nsew")
    ...

整体布局变得更容易在代码中可视化,并且更容易重新配置(这是不可避免的)

注释

您有一个错误,因为您正在创建多个

Tk
实例。如果您需要创建弹出窗口,请创建
Toplevel
的实例。
Tk
应保留给根窗口,并且仅保留给根窗口。

你的这个说法也有一个错误:

self.entry2 = Tkinter.Text(test3,...).pack(...)

在Python中,当你执行

x=y().z()
时,
x
会获取
.z()
的值。在 Tkinter 中,
pack
始终返回
None
,因此
self.entry2
将被设置为
None

© www.soinside.com 2019 - 2024. All rights reserved.