【问题标题】:tkinter frame display basicstkinter 帧显示基础知识
【发布时间】:2016-12-07 21:39:48
【问题描述】:

我正在尝试在 Python/tkinter 中创建一个应用程序(我的第一个应用程序),它最终应该在 Raspberry Pi 上运行,并附有一个小型触摸屏显示器 (480x320px)。屏幕分为主机和框架,框架(稍后)将包含 6 个功能键(按钮)

所以我从下面的代码开始,希望/期望我能以某种方式将主应用程序窗口分成两个框架,一个是灰色的,一个是黑色的……但我(在我的 PC 上)看到的只是 MainApp 窗口尺寸正确,不可调整大小,标题正确(到目前为止一切都很好!)和黄色背景......我在 MainApp 中定义的框架似乎没有显示,即使里面有标签,它们是粘性的,它们有一个重量(我不记得我还尝试了什么以及我在哪里搜索过)

请问我在这里俯瞰什么?

#!/usr/bin/python3
import tkinter as tk
#
# main application
#
class MainApp(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.parent.title("My first GUI")
        self.parent.geometry("480x320")
        self.parent.resizable(width=False, height=False)
        self.parent.config(bg="yellow")

        mainframe = tk.Frame(self, bg="grey", width=480, height=280 )
        mainframe.grid(column=0, row=0, sticky="WENS")
        tk.Label(mainframe, text="co-cooo").grid(column=0, row=0, sticky="WENS")

        fkeyframe = tk.Frame(self, bg="black", width=480, height=40)
        fkeyframe.grid(column=0, row=1, sticky="WENS")
        tk.Label(fkeyframe, text="fo-fooo").grid(column=0, row=0, sticky="WENS")

        self.rowconfigure(0, weight=1, minsize=280)
        self.rowconfigure(1, weight=1, minsize=40)
#
# define root element and start application
#
def main():
    root = tk.Tk()
    app = MainApp(root)
    root.mainloop()  

#
# start if called from command line
#
if __name__ == '__main__':
    main()

#      0,0   MainApp (yellow)          480,0
#       +---------------------------------+
#       |   mainframe (grey, h=280)       |
#       |+-------------------------------+|
#       ||                               ||
#       ||                               ||
#       ||                               ||
#       |+-------------------------------+|
#       |   fkeyframe  (black, h=40)      |
#       |+-------------------------------+|
#       ||+----+----+----+----+----+----+||
#       ||| Bt | Bt | Bt | Bt | Bt | Bt |||
#       ||+----+----+----+----+----+----+||
#       |+-------------------------------+|
#       +---------------------------------+
#    320,0                             320,480

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    你在正确的轨道上。我看到您有条不紊,一次只尝试解决一个布局问题,而不是尝试将所有小部件放在屏幕上然后尝试修复它们。这绝对是您刚起步时最好的工作方式。

    第一个问题是您忽略了将MainApp 添加到主窗口。您可以创建它,但不会将其布置在屏幕上。

    因此,第一步是将其添加到主窗口。通过在创建后调用packplacegrid 来执行此操作。由于它是根窗口内唯一的小部件,pack 是最简单的:

    app.pack(fill="both", expand=True)
    

    这将导致MainApp 及其所有子项可见。

    第二个问题是您会注意到现在所有内容都已压缩并位于窗口的左侧。这是因为您将mainframe 放在MainAppgrid 中,但是您没有为MainApp 中的任何列赋予权重,因此整个窗口中的所有额外空间都未使用。而且,由于框架想要缩小以适应其内容,您的mainframe 框架会水平缩小以适应其中的一个小部件。

    根据经验,如果您将一个或多个小部件放入父小部件中,则必须始终为父小部件中的至少一行一列赋予权重。

    为此,请致电columnconfigure,就像您致电grid_rowconfigure一样:

    self.columnconfigure(0, weight=1)
    

    这样,您的mainframe 现在覆盖了窗口的整个上部,fkeyframe 覆盖了底部,您可以开始添加更多小部件。

    【讨论】:

      【解决方案2】:

      __init__ 中使用frame.grid_propagate(False) 以防止将框架调整为内部小部件的尺寸:

      def __init__(self, parent):
          tk.Frame.__init__(self, parent)
          self.parent = parent
          self.parent.title("My first GUI")
          self.parent.geometry("480x320")
          self.parent.resizable(width=False, height=False)
          self.parent.config(bg="yellow")
      
          mainframe = tk.Frame(self, bg="grey", width=480, height=280 )
          mainframe.grid(column=0, row=0, sticky="WENS")
          mainframe.grid_propagate(False)
          tk.Label(mainframe, text="co-cooo").grid(column=0, row=0, sticky="WENS")
      
          fkeyframe = tk.Frame(self, bg="black", width=480, height=40)
          fkeyframe.grid(column=0, row=1, sticky="WENS")
          mainframe.grid_propagate(False)
          tk.Label(fkeyframe, text="fo-fooo").grid(column=0, row=0, sticky="WENS")
      
          self.rowconfigure(0, weight=1, minsize=280)
          self.rowconfigure(1, weight=1, minsize=40)
      

      【讨论】:

      • 部分改进...现在我看到灰色和黑色,在 MainApp 窗口的最左侧带有叠加标签 co-cooo 和 fo-fooo,右侧的其余部分(大约 80%)仍然是黄色...所以框架似乎不尊重我要求的宽度
      • 更新答案,看frame的grid_propagate方法。
      • 我开始减少我认为是冗余的代码,所以self.grid() 实际上做了一些非常好的事情......我现在遇到了新的现象,所以我接受你的答案并在受挫时打开另一个超过 10^6
      • <frame>.grid_propagate(False) 杀死了更多现象......谢谢
      • 从 cmets 对您的回答来看,您解决了一个问题,但又创造了其他问题。这正是关闭传播所发生的事情。它解决了一个直接的问题,但会导致其他问题。在我看来,在这种特定情况下,关闭传播可以解决症状,而不是问题。至于我对pack 的使用,这是一个小问题。我本可以使用grid,但这需要三行而不是一行,没有额外的好处。
      猜你喜欢
      • 1970-01-01
      • 2014-04-16
      • 2018-05-25
      • 2014-11-28
      • 2014-02-14
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多