如何使框架内的按钮影响其框架外的内容?我是编程新手,无法自己解决这个问题。这是我的代码和一些图片,准确地显示了我想要做的事情。任何帮助将不胜感激。
import tkinter
import tkinter.messagebox
import customtkinter
class SidebarFrame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master, corner_radius=0)
self.grid_rowconfigure(4, weight=1)
self.logo_label = customtkinter.CTkLabel(self, text="Board Game\nBorrow", font=customtkinter.CTkFont(size=20, weight="bold")) #Title
self.logo_label.grid(row=0, column=0, padx=30, pady=(20, 10))
self.functionsframe = FunctionsSidebarFrame(self) #Call Functions Frame
self.functionsframe.grid(row=1, column=0, padx=10, pady=10)
self.functions_remove() #Hide Functions Frame
self.loginframe = LoginSidebarFrame(self) #Call Login Frame
self.loginframe.grid(row=1, column=0, padx=10, pady=10)
self.sidebar_button_1 = customtkinter.CTkButton(self, text="Login", command=self.login)
self.sidebar_button_1.grid(row=2, column=0, padx=10, pady=10)
def login_remove(self):
self.loginframe.grid_remove()
def login_show(self):
self.loginframe.grid()
def functions_remove(self):
self.functionsframe.grid_remove()
def functions_show(self):
self.functionsframe.grid()
def login(self):
if self.loginframe.winfo_ismapped():
self.login_remove()
self.functions_show()
elif not self.loginframe.winfo_ismapped():
self.login_show()
self.functions_remove()
class FunctionsSidebarFrame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master, width=120, corner_radius=8)
self.grid_rowconfigure(4, weight=1)
self.sidebar_button_1 = customtkinter.CTkButton(self, text="Veiw Game List", command=self.viewGames) #Side Button 1 (View Game List)
self.sidebar_button_1.grid(row=1, column=0, padx=10, pady=10)
self.sidebar_button_2 = customtkinter.CTkButton(self, text="Request Game", command=self.requestGame) #Side Button 2 (Request Game)
self.sidebar_button_2.grid(row=2, column=0, padx=10, pady=10)
self.sidebar_button_3 = customtkinter.CTkButton(self, text="Add Game", command=self.addGame) #Side Button 3 (Add Game)
self.sidebar_button_3.grid(row=3, column=0, padx=10, pady=10)
def viewGames(self):
print("View Games")
def requestGame(self):
print("Request Game")
def addGame(self):
print("Add Game")
class LoginSidebarFrame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master, width=120, corner_radius=8)
text = customtkinter.CTkLabel(self, text="Please Login", font=customtkinter.CTkFont(size=15, weight="bold")) #Title
text.grid(row=0, column=0, padx=10, pady=10)
class ScrollFrame(customtkinter.CTkScrollableFrame):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self._parent_frame.grid(row=0, column=0, rowspan=3, padx=(20,0), pady=(40,70), sticky="nsew")
self.label = customtkinter.CTkLabel(self, text="Game List", font=customtkinter.CTkFont(size=18, weight="bold"))
self.label.grid(row=0, column=0, padx=20)
# Add Game List here
class GeneralFrame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master)
label = customtkinter.CTkLabel(self, text="Login Frame")
label.grid(row=0, column=0, padx=20, pady=20)
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.title("Board Game Borrow")
self.geometry(f"{1100}x{580}")
self.grid_columnconfigure(1, weight=1)
self.grid_columnconfigure(2, weight=0)
self.grid_rowconfigure((0, 1, 2), weight=1)
self.sidebar_frame = SidebarFrame(self) #Call Sidebar Frame
self.sidebar_frame.grid(row=0, column=0, rowspan=4, sticky="nsew")
self.top_button1 = customtkinter.CTkButton(self, text="Create Account", width=15, height=10, command=self.create_account) #Top Button
self.top_button1.grid(row=0, column=3, padx=(20, 80), pady=10, sticky="ne")
self.top_button2 = customtkinter.CTkButton(self, text="Sign In", width=15, height=10, command=self.login) #Top Button
self.top_button2.grid(row=0, column=3, padx=20, pady=10, sticky="ne")
self.checkbox = customtkinter.CTkCheckBox(self, text="Sidebar", command=self.sidebar) #Call Checkbox
self.checkbox.grid(row=2, column=1, padx=20, pady=20, sticky="ws")
self.checkbox.select()
self.textbox = customtkinter.CTkTextbox(self, width=100) #Call Textbox
self.textbox.grid(row=0, column=2, padx=20, pady=(40,70), sticky="nsew", rowspan=3, columnspan=2)
self.textbox.insert("end", "Welcome to Board Game Borrow\n\n")
self.exit = customtkinter.CTkButton(self, text="Exit", command=self.quit) #Exit Button
self.exit.grid(row=2, column=3, padx=20, pady=20, sticky="es")
self.current_frame = None
button1 = customtkinter.CTkButton(self, text="Switch to Scroll Frame", command=lambda: self.switch_frame(ScrollFrame))
button1.grid(row=2, column=1, padx=20, pady=20, sticky="es")
button2 = customtkinter.CTkButton(self, text="Switch to Login Frame", command=lambda: self.switch_frame(GeneralFrame))
button2.grid(row=2, column=1, padx=180, pady=20, sticky="es")
button3 = customtkinter.CTkButton(self, text="Remove Frame", command=lambda: self.remove_frame())
button3.grid(row=2, column=2, padx=20, pady=20, sticky="es")
def switch_frame(self, frame_class):
new_frame = frame_class(self)
if self.current_frame is not None:
self.current_frame.grid_remove()
self.current_frame = new_frame
self.current_frame.grid(row=0, column=1)
print(self.current_frame)
def remove_frame(self):
self.current_frame.grid_remove()
self.current_frame = None
print(self.current_frame)
def sidebar_button_event(self):
print("sidebar_button click")
def sidebar(self):
if self.sidebar_frame.winfo_ismapped():
self.hide_sidebar()
elif not self.sidebar_frame.winfo_ismapped():
self.show_sidebar()
def hide_sidebar(self):
self.sidebar_frame.grid_remove()
def show_sidebar(self):
self.sidebar_frame.grid()
def create_account(self):
username = customtkinter.CTkInputDialog(text="Enter usernsme", title="Login")
text1 = username.get_input() # waits for input
password = customtkinter.CTkInputDialog(text="Enter password", title="Login")
text2 = password.get_input() # waits for input
# Add code to add username(text1) and password(text2) to a new user in the database
def login(self):
username = customtkinter.CTkInputDialog(text="Enter usernsme", title="Login")
text = username.get_input() # waits for input
password = customtkinter.CTkInputDialog(text="Enter password", title="Login")
text2 = password.get_input() # waits for input
if text == "admin" and text2 == "admin":
self.top_button2.grid_remove()
self.top_button2 = customtkinter.CTkButton(self, text="Sign Out", width=15, height=10)
self.top_button2.grid(row=0, column=3, padx=20, pady=10, sticky="ne")
self.sidebar_frame.login()
def __str__(self):
return "App"
if __name__ == "__main__":
app = App()
app.mainloop()
“查看游戏列表”按钮应具有与“切换到滚动框架”按钮相同的功能
我尝试让按钮运行
App.switch_frame(ScrollFrame)
但什么也没发生。没有错误消息或任何类型的更改。
您尝试的 App.switch_frame(ScrollFrame) 不起作用,因为它是从类而不是实例调用函数,而实例不是您看到的窗口。所以你需要从实例“app”调用该函数。
这是 OOP 的普遍问题。您经常需要类以某种方式进行交互,这只有在每个类都引用另一个类或者实例是全局的情况下才有可能。这两种解决方案都违背了使用 OOP 的目的/优点。
对于您的情况,您可以为 FunctionsSidebarFrame 类提供对应用程序实例的引用,然后您可以使用该引用来调用其 swith_frame 函数。
class FunctionsSidebarFrame(customtkinter.CTkFrame):
def __init__(self, master, app):
self.app = app
...
def viewGames(self):
self.app.switch_frame(ScrollFrame)
这还要求您为 SidebarFrame 类提供要传递给 FunctionsSidebarFrame 的引用。