【问题标题】:How align Optionmenu using grid in centre of window in tkinter?如何在 tkinter 的窗口中心使用网格对齐 Optionmenu?
【发布时间】:2018-05-26 11:08:47
【问题描述】:

我正在尝试将 Optionmenu 居中并排对齐,但每当我取消注释 .grid() 语句时,窗口中不会显示任何内容,它会变为空白。

import tkinter as tk
from utils import editionMap, topicMap, langMap

class OptionMenu(tk.Frame):

    def __init__(self, master, status, *options):
        self.frame = tk.Frame(master)
        self.frame.pack()

        self.status = tk.StringVar()
        self.status.set(status)

        self.dropdown = tk.OptionMenu(self.frame, self.status, *options)
        self.dropdown.pack()


def main():
    root = tk.Tk()
    Edition_Filter = OptionMenu(root, "Edition", *editionMap.keys())
    #Edition_Filter.grid(row=0, column=0)  <---Uncomment
    Language_Filter = OptionMenu(root, "Language", *langMap.keys())
    #Language_Filter.grid(row=0, column=1) <---Uncomment
    Topic_Filter = OptionMenu(root, "Topic", *topicMap.keys())
    #Topic_Filter.grid(row=0, column=2)    <---Uncomment

    root.mainloop()

if __name__ == '__main__':
    main()

我希望将显示选项菜单水平并排为Edition Language Topic

我的实际输出是:

【问题讨论】:

  • 如果你在里面创建Frame,那么你必须在self.frame.pack()中使用参数。而且您不能使用grid() - 或者您使用self.frame.grid() 而不是self.frame.pack()
  • @furas 我知道 'pack' 和 'grid' 不应该混合使用,您可以仅根据网格编辑上述代码吗?
  • 你混合了两种不同的技术 self.frame = tk.Frame(master)class OptionMenu(tk.Frame): - 再次查看上一个问题中的代码。
  • @furas 所以我不必在课堂上传递参数,对吗?

标签: python oop tkinter optionmenu


【解决方案1】:

你混合了两种不同的技术

第一:继承

class OptionMenu(tk.Frame): # <-- with Frame

    def __init__(self, master, status, *options):

        super().__init__(master) # <-- with super()

第二:包括

class OptionMenu(): # <-- without Frame

    def __init__(self, master, status, *options):

        self.frame = tk.Frame(master) # <-- create inner widget

首先创建可以使用menu.pack()menu.grid()的真实小部件

Second 不创建小部件 - 它创建带有小部件的普通类,您必须使用 menu.frame.pack()menu.frame.grid()


真实小部件示例

import tkinter as tk

class OptionMenu(tk.Frame): # <-- with Frame

    def __init__(self, master, status, *options):

        super().__init__(master) # <-- with super()

        self.status = tk.StringVar()
        self.status.set(status)

        # use `self` as parent for widgets inside

        self.dropdown = tk.OptionMenu(self, self.status, *options)
        self.dropdown.pack()


def main():

    editionMap = {1:"English", 2:"German", 3:"Russian"}
    langMap = {1:"English", 2:"German", 3:"Russian"}
    topicMap = {1:"English", 2:"German", 3:"Russian"}

    root = tk.Tk()

    Edition_Filter = OptionMenu(root, "Edition", *editionMap.keys())
    Edition_Filter.grid(row=0, column=0)

    Language_Filter = OptionMenu(root, "Language", *langMap.keys())
    Language_Filter.grid(row=0, column=1)

    Topic_Filter = OptionMenu(root, "Topic", *topicMap.keys())
    Topic_Filter.grid(row=0, column=2)

    root.mainloop()

if __name__ == '__main__':
    main()

【讨论】:

  • 如果您从其他类继承 - 即。 class OptionMenu(tk.Frame) - 那么你必须使用 super().__init__() 来执行原始的 __init__() - 即。 tk.Frame.__init__() 做了很多重要的事情。
  • 因为最初我创建了新的小部件,其中包含两个元素 - OptionMenuLabel - 所以我使用 Frame 对它们进行分组。
  • 我们使用Frame 对元素进行分组有以下三个原因: 1. 在内部和外部使用不同的布局管理器(你可以有pack() 外部和grid() 内部,或者grid() 外部和pack() 内)。 2.创建具有许多元素的小部件。 3. 轻松显示/隐藏许多元素 - 您可以在 Frame 中添加元素,并且您必须仅隐藏 Frame 而不是许多单独的元素。
  • 如果您创建MyOptionMenu(OptionMenu):,那么您必须在__init__() 中使用super().__init__()OptionMenu.__init__(self, master, self.var, *options)。如果您不使用它,它将无法正常工作。
  • 你的 def __init__(self, master, status, *options): 替换了原来的 OptionMenu.__init__() 所以你必须在你的 def __init__() 中手动调用它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
  • 1970-01-01
  • 2018-09-09
  • 2014-04-28
相关资源
最近更新 更多