如何将LoginOrReg类的变量传递到HabitTracker类?
解决LoginOrReg与HabitTracker间的变量传递问题
核心问题分析
- 错误创建新实例:在
HabitTracker.main_menu中,你重新创建了一个全新的LoginOrReg实例,这个实例的login_username和data都是初始空值,和用户登录时的实例完全无关,自然拿不到登录后的变量。 - 变量获取时机错误:在
LoginOrReg.login方法中,窗口刚创建就调用self.login_username = self.login_username_entry.get(),此时用户还没输入内容,拿到的是空字符串。 - 循环导入与实例传递错误:创建
HabitTracker时没有传递当前登录的LoginOrReg实例,导致后续无法访问已登录的用户数据。
修改后的LoginOrReg文件代码
import customtkinter import mysql.connector # 避免循环导入,这里只在需要时导入HabitTracker import HabitTracker as HT class LoginOrReg: customtkinter.set_appearance_mode('dark') customtkinter.set_default_color_theme('blue') def __init__(self): # 初始化数据库连接,不要在参数里传空值 self.db = mysql.connector.connect(host='', user='', password='', database="") self.cursor = self.db.cursor() self.login_username = "" self.data = None # 初始化为None,登录后赋值 # 登录窗口创建 def login(self): self.login_window = customtkinter.CTk() self.login_window.geometry('400x400') self.login_username_entry = customtkinter.CTkEntry(self.login_window, placeholder_text='Enter Your Username') self.login_username_entry.pack(pady=30) self.login_password_entry = customtkinter.CTkEntry(self.login_window, placeholder_text='Enter Your Password', show="*") self.login_password_entry.pack(pady=30) self.log_user_in_button = customtkinter.CTkButton(self.login_window, text='Login', command=self.log_user_in).pack(pady=30) self.reg_button = customtkinter.CTkButton(self.login_window, text='Register New User', command=self.reg_user).pack(pady=20) self.login_window.mainloop() # 用户登录逻辑 def log_user_in(self): # 在这里获取用户输入的用户名和密码,而不是窗口初始化时 input_username = self.login_username_entry.get() input_password = self.login_password_entry.get() # 修正SQL语句:SELECT里的AND是逻辑运算符,不是字段分隔符 self.cursor.execute('SELECT COUNT(*) FROM users WHERE username=%s AND password=%s', (input_username, input_password)) row_count = self.cursor.fetchone()[0] if row_count == 1: # 获取用户ID self.cursor.execute('SELECT userID FROM users WHERE username=%s AND password=%s', (input_username, input_password)) self.data = self.cursor.fetchone() self.login_username = input_username print(f"登录成功,用户ID:{self.data}") # 关闭登录窗口 self.login_window.destroy() # 创建HabitTracker实例,把当前LoginOrReg实例传过去 self.habit_tracker = HT.HabitTracker(login=self) self.habit_tracker.main_menu() else: # 提示错误,注意pack的返回值是None,不要直接赋值给变量 customtkinter.CTkLabel(self.login_window, text="User Not Found. Please Try Again.", font=('Helvetica', 10)).pack(pady=10) # 注册方法(保留原逻辑,这里假设你会实现) def reg_user(self): pass # 启动程序 if __name__ == "__main__": login_reg = LoginOrReg() login_reg.login()
修改后的HabitTracker文件代码
import customtkinter import mysql.connector from datetime import datetime class HabitTracker: def __init__(self, login) -> None: self.login = login # 接收传入的已登录LoginOrReg实例 self.main_window = None self.db = mysql.connector.connect(host='', user='', password='', database="") self.cursor = self.db.cursor() self.sorting_options = [] self.sort = None def main_menu(self): self.main_window = customtkinter.CTk() self.main_window.geometry('1080x720') self.sorting_options = ['Daily', 'Weekly', 'Monthly', 'Highest Streak'] # 使用已登录实例的login_username customtkinter.CTkLabel(self.main_window, text=f'Welcome {self.login.login_username}', font=('Arial', 40)).pack(pady=5) self.sort = customtkinter.CTkComboBox(self.main_window, values=self.sorting_options) self.sort.set('Sort By') self.sort.pack(pady=10) # 注意:这里的create_habit和sort_by需要你确保已正确导入或实现,避免未定义错误 customtkinter.CTkButton(self.main_window, text='Create New Habit', command=self.create_habit, fg_color='green').pack(pady=20) # 使用已登录实例的data(用户ID)查询习惯 if self.login.data: user_id = self.login.data[0] self.cursor.execute('SELECT habit_name FROM habit WHERE user_id=%s GROUP BY habit_name', (user_id,)) self.habits = self.cursor.fetchall() for habit in self.habits: # 修正按钮文本:habit是元组,取第一个元素 customtkinter.CTkButton(self.main_window, text=habit[0], command=lambda h=habit[0]: self.edit_habit(h)).pack(pady=10) self.main_window.mainloop() # 占位的创建习惯方法 def create_habit(self): pass # 占位的编辑习惯方法 def edit_habit(self, habit_name): print(f"编辑习惯:{habit_name}")
关键修改点说明
- 传递已登录实例:创建
HabitTracker时,直接把当前登录成功的LoginOrReg实例(self)传过去,而不是创建新实例。 - 修正变量获取时机:在
log_user_in方法中才获取用户输入的用户名和密码,确保拿到的是用户实际输入的内容。 - 修复SQL语句错误:原SELECT语句中的
username AND password是语法错误,改为正确的逻辑判断。 - 避免循环导入:将
HabitTracker的导入放在LoginOrReg文件的顶部(而非方法内),同时确保HabitTracker不循环导入LoginOrReg。 - 修正按钮文本与命令:习惯按钮的文本需要取元组的第一个元素,lambda表达式正确绑定循环变量。
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

