【问题标题】:Python 3.4 Tkinter, Understanding code/setting window sizePython 3.4 Tkinter,了解代码/设置窗口大小
【发布时间】:2016-04-08 05:53:48
【问题描述】:

我正在尝试使用类制作一个 tkinter GUI,我对它很陌生(我已经看过 TNB 的所有关于它的教程),并且在我的代码中实现功能和理解它时遇到了一些问题.我正在尝试修改在此站点上找到的代码以获得基本结构,但我无法弄清楚其中一些如何/为什么起作用以及如何添加一些东西。

这是我目前的代码:

import tkinter as tk


class Application(tk.Tk):  # Inheriting tkinter classes etc.

    def __init__(self):
        tk.Tk.__init__(self)  # Creates window?
        container = tk.Frame(self)  # Creates frame object
        container.pack(side="top", fill="both", expand=True)  # Places container/frame inside window
        container.grid_rowconfigure(0, weight=1)  # ?
        container.grid_columnconfigure(0, weight=1)  # ?

        self.frames = {}  # What does this do?
        for F in (MenuPage, StartPage, InfoPage, SettingsPage):
            page_name = F.__name__  # What is __name__ for?
            frame = F(container, self)
            self.frames[page_name] = frame  # Creating dictionary entries?
            frame.grid(row=0, column=0, sticky="NSEW")
        self.show_frame("MenuPage")  # Pushes menu page to top when initialised

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()  # Raises frame to top of stack


class MenuPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the menu page")
        label.pack(side="top", fill="x", pady=10)

        # Begins quiz
        start_btn = tk.Button(self,
                              text="Start",
                              command=lambda : controller.show_frame("StartPage"))
        start_btn.pack()

        # Takes user to information page
        info_btn = tk.Button(self,
                             text="Information",
                             command=lambda: controller.show_frame("InfoPage"))
        info_btn.pack()

        # Takes user to settings page
        settings_btn = tk.Button(self,
                                 text="Settings",
                                 command=lambda: controller.show_frame("SettingsPage"))
        settings_btn.pack()

        # Quits program/closes all GUIs
        quit_btn = tk.Button(self,
                             text="Quit",
                             command=self.controller.destroy)
        quit_btn.pack()


# First page of quiz, will need to inherit from settings?
class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the start")
        label.pack(side="top", fill="x", pady=10)


class InfoPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the info page")
        label.pack(side="top", fill="x", pady=10)

        # Takes user back to main menu
        menu_btn = tk.Button(self,
                             text="Go to the menu page",
                             command=lambda: controller.show_frame("MenuPage"))
        menu_btn.pack()


class SettingsPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the settings page")
        label.pack(side="top", fill="x", pady=10)

        # Takes user back to main menu
        menu_btn = tk.Button(self,
                             text="Go to the menu page",
                             command=lambda: controller.show_frame("MenuPage"))
        menu_btn.pack()

if __name__ == "__main__":  # What does this do?
    app = Application()
    app.mainloop()

(我想为退出按钮添加功能,它实际上会关闭整个 GUI 程序。到目前为止,我已经尝试了各种使用 .destroy() 作为按钮命令和退出命令的方法,但我没有运气。我还尝试在 Application() 类中使用 destroy 函数,并从命令中调用它,但这也不起作用。我不确定我是否正确使用它。) - 已修复,感谢 Bryan Oakley 和 furas。

我不知道该怎么做的另一件事是更改窗口的大小参数,以便每个窗口都说(500x200)。不使用类时这很容易,但我什至不知道在使用它们时从哪里开始,并且有多个框架。

我还标记/标记了一些代码行,如果有人可以向我解释,那就太好了。在解释原始代码的某些部分之前有一个帖子,但他们只解决了该用户请求的特定部分。

在此先感谢 :) (希望现在所有的缩进都被复制过来了)

【问题讨论】:

  • 类似于variable = Widget().pack() 的行会将None 分配给variable(而不是Widget),因为pack()/grid()/place() 返回None。使用variable = Widget()variable.pack()
  • command=controller.destroy
  • 这可能解释了我在其他代码段上遇到的一些错误,尽管它们似乎在这里运行良好。我会改的,谢谢。

标签: python class user-interface tkinter


【解决方案1】:

此代码的设计使主程序(“控制器”)成为控制 GUI 的中心点。这就是为什么 self(应用程序本身)作为 controller 参数传递给其他框架的原因。

因此,要从其他页面之一调用控制器上的任何函数,您将调用self.controller.destroy()。要将其与退出按钮相关联,您可以这样做:

quit_btn = tk.Button(self, text="Quit", command=self.controller.destroy)
quit_btn.pack()

注意:在单个语句中创建小部件并将它们布置——调用packgridplace 是一个非常糟糕的习惯。您应该始终将小部件的创建与在屏幕上排列它们分开。当你在单个语句中这样做时,你的变量将始终设置为None,这是没有用的。

【讨论】:

  • 谢谢你完美的工作!我在尝试:quit_btn = tk.Button(self, text = "Quit", command = self.destroy)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
相关资源
最近更新 更多