从 class 创建的规模 ttk.Frame

Scale ttk.Frame created from the class

我正在尝试创建 Python 3.7+ Tkinter 应用程序,其中包含另一个可以通过单击按钮调出的框架:

Sentdex example

Whosebug example

我用 Tkinter (ThemedTk) 创建了一个 class,并想用 ttk.Frame 创建几个 classes。按钮将在框架之间切换。我现在的问题 - 我无法调整框架大小并将 'nesw' 粘贴到主根 Class。我假设我在 ttk.Frame 上做错了什么,但我无法理解这个问题。 我加了

self.grid(row=0, column=0)
self.rowconfigure(0, weight=3)
self.columnconfigure(0, weight=3)

但这似乎没有帮助... 完整代码:

import tkinter as tk
from tkinter import ttk
from ttkthemes import ThemedTk

class MainApp(ThemedTk):
    def __init__(self):
        ThemedTk.__init__(self)
        self.set_theme('equilux', themebg=True)
        self.title('Test App')
        self.style = ttk.Style(self)
        self.DESKTOP_WIDTH = self.winfo_screenwidth()
        self.DESKTOP_HEIGHT = self.winfo_screenheight()
        self.WIDTH = int(self.DESKTOP_WIDTH / 4)
        self.HEIGHT = int(self.DESKTOP_HEIGHT / 2.5)
        self.geometry(f'{self.WIDTH}x{self.HEIGHT}+{int(self.DESKTOP_WIDTH / 3)}+{int(self.DESKTOP_HEIGHT / 4)}')
        self.minsize(width=self.WIDTH, height=self.HEIGHT)
        self._frame = None
        self.switch_frame(MainLogin)

    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.grid(row=0, column=0)


class MainLogin(ttk.Frame):
    def __init__(self, master):
        ttk.Frame.__init__(self, master, padding=(5, 5, 5, 5), borderwidth=10, relief='ridge', sticky='nesw')
        self.grid(row=0, column=0)
        self.rowconfigure(0, weight=3)
        self.columnconfigure(0, weight=3)
        self.master = master
        self.userid = tk.StringVar()
        self.password = tk.StringVar()
        self.remember = tk.StringVar()

        self.frame_login = ttk.Frame(self, padding=(10, 10, 10, 10), borderwidth=2, relief='ridge')

        self.label_welcome = ttk.Label(self.frame_login, text='Open App')
        self.label_user = ttk.Label(self.frame_login, text='User ID:')
        self.entry_user = ttk.Entry(self.frame_login, textvariable=self.userid)
        self.label_password = ttk.Label(self.frame_login, text='Password:')
        self.entry_password = ttk.Entry(self.frame_login, textvariable=self.password, show='*')
        self.check_remember = ttk.Checkbutton(self.frame_login, text='Remember me', variable=self.remember, onvalue='yes', offvalue='no')
        self.button_login = ttk.Button(self.frame_login, text='Login', command=lambda: MainLogin.login(self.userid, self.password))
        self.button_register = ttk.Button(self.frame_login, text='Register', command=self.register)

        self.grid_widgets()
        self.resize_widgets()

    def grid_widgets(self):
        self.frame_login.grid(row=0, column=0, sticky='nesw')
        self.label_welcome.grid(row=0, column=0, columnspan=2, pady=30, sticky='n')
        self.label_user.grid(row=1, column=0, padx=10, pady=5, sticky='e')
        self.entry_user.grid(row=1, column=1, padx=10, pady=5, sticky='w')
        self.label_password.grid(row=2, column=0, padx=10, pady=5, sticky='e')
        self.entry_password.grid(row=2, column=1, padx=10, pady=5, sticky='w')
        self.check_remember.grid(row=3, column=0, columnspan=2, pady=5, sticky='n')
        self.button_login.grid(row=4, column=0, padx=10, pady=5, ipadx=30, sticky='e')
        self.button_register.grid(row=4, column=1, padx=10, pady=5, ipadx=30, sticky='w')

    def resize_widgets(self):
        self.columnconfigure(0, weight=3)
        self.rowconfigure(0, weight=3)
        self.frame_login.columnconfigure(0, weight=3)
        self.frame_login.columnconfigure(1, weight=3)

    @staticmethod
    def login(userif, password):
        print('Login button pressed')

    def register(self):
        print('Register button pressed')



if __name__ == '__main__':
    root = MainApp()
    root.mainloop()

因为在任何时候你在根 window 中只有一个帧,最简单的解决方案是使用 pack 而不是 grid,因为你不需要不必担心配置行和列。

def switch_frame(self, frame_class):
    """Destroys current frame and replaces it with a new one."""
    new_frame = frame_class(self)
    if self._frame is not None:
        self._frame.destroy()
    self._frame = new_frame
    self._frame.pack(fill="both", expand=True)

通过这个小改动,MainLogin 框架将填充 window。

如果您更喜欢使用 grid,您可以将上面代码中对 pack 的调用替换为:

self._frame.grid(row=0, column=0, sticky="nsew")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)