在使用 tkinter 和 customtkinter 时,我是否在 Python 中正确使用了 OOP?

问题描述 投票:0回答:1

我正在尝试结合使用 tkinter 和 customtkinter 在 Python 中创建一个应用程序。现在对于该应用程序,我只制作了一个登录页面和一个帐户页面。因此,到目前为止,我拥有的唯一功能是,一旦在登录页面上输入有效的凭据,用户就会被带到其帐户的页面。

我在 Java 方面的经验比 Python 多得多(这就是为什么我在 Python 中尝试这个,所以我实际上可以了解更多)所以我真的无法判断我编写应用程序的方式是否正确。我之前用 tkinter 制作过应用程序,但在使用类时也没有制作过。

这是我的登录页面代码:

import customtkinter as ctk
import tkinter as tk
from tkinter import messagebox
from PIL import ImageTk, Image
from accountPage import AccountPage  

class LoginPage:
    def __init__(self) -> None:   
        self.root = ctk.CTk()    

        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue") 

        self.root.after(0, lambda:self.root.state('zoomed')) 
        self.root.title("Login Page") 

        bgImage = Image.open("bg.jpg")  
        bg = ImageTk.PhotoImage(bgImage) 
        bgLabel = tk.Label(self.root, image = bg)     
        bgLabel.place(x = 0, y = 0, relwidth = 1, relheight = 1)

        loginFrame = ctk.CTkFrame(self.root)     
        loginFrame.pack(pady = 120, padx = 500, fill = "both", expand = True)   

        loginLabel = ctk.CTkLabel(loginFrame, text = "Login", font = ("Tahoma", 35, "bold"))
        loginLabel.pack(pady = 30, padx = 10)

        self.usernameEntry = ctk.CTkEntry(loginFrame, placeholder_text="Username", font = ("Tahoma", 15), width = 300, height = 50)   
        self.usernameEntry.pack(pady = 30, padx = 10)

        self.passwordEntry = ctk.CTkEntry(loginFrame, placeholder_text="Password", show = "*", font = ("Tahoma", 15), width = 300, height = 50)   
        self.passwordEntry.pack(pady = 30, padx = 10) 

        loginButton = ctk.CTkButton(loginFrame, text="Login", font = ("Tahoma", 15, "bold"), command = self.validateLogin, width = 300, height = 50)  
        loginButton.pack(pady = 30, padx = 10)  

        self.root.mainloop()  



    def validateLogin(self) -> None: 

        name = self.usernameEntry.get().lower() 

        if self.checkProvidedLogin(name, self.passwordEntry.get()): 
              
            self.root.destroy()    
            AccountPage(name)

        else:

            messagebox.showerror(message = "Invalid login, Try again") 
    


    def checkProvidedLogin(self, username, password) -> bool:

        with open('logins.csv', 'r') as file:
                logins = file.read().splitlines()

        for line in logins:   
             if line == username + "," + password: 
                  return True

        return False  


if __name__ == "__main__":
    LoginPage()

这是我现在的帐户页面代码:

import customtkinter as ctk
import tkinter as tk
from PIL import ImageTk, Image

class AccountPage:
    def __init__(self, username) -> None: 
        self.accountRoot = ctk.CTk() 

        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue") 

        self.accountRoot.after(0, lambda:self.accountRoot.state('zoomed')) 

        bgImage = Image.open("bg.jpg")  
        bg = ImageTk.PhotoImage(bgImage) 
        bgLabel = tk.Label(self.accountRoot, image = bg)    
        bgLabel.place(x = 0, y = 0, relwidth = 1, relheight = 1) 

        accountFrame = ctk.CTkFrame(self.accountRoot)
        accountFrame.pack(pady = 50, padx = 50, fill = "both", expand = True)   

        welcomeLabel = ctk.CTkLabel(accountFrame, text = f"Welcome, {username}!", font = ("Tahoma", 35, "bold"))
        welcomeLabel.pack(pady = 20)

        self.accountRoot.mainloop()

再次,一切正常。输入有效的信用信息后,就会出现帐户页面。但我不知道我是否真的正确地将 OOP 与 tkinter/customtkinter 结合使用。

如果有人愿意查看我的代码并提供任何反馈,我们将不胜感激。

python oop tkinter customtkinter
1个回答
0
投票

描述

所以你的好处实现了你的目标,但还不是很好,我建议你看一下 customtkinters 文档 并特别查看

OOP
部分,这里是
CTkWindow
CTkTopLevel
OOP 代码的链接:

CTkWindow OOP

CTk顶级OOP

改进代码:

下面是没有错误的作品,并且根据文档进行了优化和良好的效果。

登录页面代码:

import customtkinter as ctk
import tkinter as tk
from PIL import ImageTk, Image

import customtkinter as ctk
import tkinter as tk
from tkinter import messagebox
from PIL import ImageTk, Image
from accountPage import AccountPage  

class LoginPage(ctk.CTk):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue") 

        self.after(0, lambda:self.state('zoomed')) 
        self.title("Login Page") 

        bgImage = Image.open("bg.jpg")  
        bg = ImageTk.PhotoImage(bgImage) 
        bgLabel = tk.Label(self, image = bg)     
        bgLabel.place(x = 0, y = 0, relwidth = 1, relheight = 1)

        loginFrame = ctk.CTkFrame(self)     
        loginFrame.pack(pady = 120, padx = 500, fill = "both", expand = True)   

        loginLabel = ctk.CTkLabel(loginFrame, text = "Login", font = ("Tahoma", 35, "bold"))
        loginLabel.pack(pady = 30, padx = 10)

        self.usernameEntry = ctk.CTkEntry(loginFrame, placeholder_text="Username", font = ("Tahoma", 15), width = 300, height = 50)   
        self.usernameEntry.pack(pady = 30, padx = 10)

        self.passwordEntry = ctk.CTkEntry(loginFrame, placeholder_text="Password", show = "*", font = ("Tahoma", 15), width = 300, height = 50)   
        self.passwordEntry.pack(pady = 30, padx = 10) 

        loginButton = ctk.CTkButton(loginFrame, text="Login", font = ("Tahoma", 15, "bold"), command = self.validateLogin, width = 300, height = 50)  
        loginButton.pack(pady = 30, padx = 10)
        
        self.toplevel_window = None 

    def validateLogin(self) -> None: 

        name = self.usernameEntry.get().lower() 

        if self.checkProvidedLogin(name, self.passwordEntry.get()): 
              
            self.withdraw()    
            self.toplevel_window = AccountPage(name)

        else:

            messagebox.showerror(message = "Invalid login, Try again") 
    
    def checkProvidedLogin(self, username, password) -> bool:

        with open('logins.csv', 'r') as file:
                logins = file.read().splitlines()

        for line in logins:   
             if line == username + "," + password: 
                  return True

        return False  


if __name__ == "__main__":
    root = LoginPage()
    root.mainloop()

帐户页面代码:

import customtkinter as ctk
from PIL import Image, ImageTk

class AccountPage(ctk.CTkToplevel):
    def __init__(self, username, *args, **kwargs) -> None: 
        super().__init__(*args, **kwargs)
        
        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue") 

        self.after(0, lambda:self.state('zoomed')) 

        bgImage = Image.open("bg.jpg")  
        bg = ImageTk.PhotoImage(bgImage) 
        bgLabel = ctk.CTkLabel(self, image = bg)    
        bgLabel.place(x = 0, y = 0, relwidth = 1, relheight = 1) 

        accountFrame = ctk.CTkFrame(self)
        accountFrame.pack(pady = 50, padx = 50, fill = "both", expand = True)   

        welcomeLabel = ctk.CTkLabel(accountFrame, text = f"Welcome, {username}!", font = ("Tahoma", 35, "bold"))
        welcomeLabel.pack(pady = 20)

        self.mainloop()

注:

因此,如果您观察登录页面代码,您可以看到您在销毁初始窗口后调用了

AccountPage
类,这会导致解释器中出现错误,因为您在实例化窗口被销毁后执行操作。这样做并不是一个好习惯,而是使用
TopLevel
Frame
在窗口或场景之间进行切换。 您所需要做的就是浏览文档,这非常简单

© www.soinside.com 2019 - 2024. All rights reserved.