You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将LoginOrReg类的变量传递到HabitTracker类?

解决LoginOrReg与HabitTracker间的变量传递问题

核心问题分析

  1. 错误创建新实例:在HabitTracker.main_menu中,你重新创建了一个全新的LoginOrReg实例,这个实例的login_username和data都是初始空值,和用户登录时的实例完全无关,自然拿不到登录后的变量。
  2. 变量获取时机错误:在LoginOrReg.login方法中,窗口刚创建就调用self.login_username = self.login_username_entry.get(),此时用户还没输入内容,拿到的是空字符串。
  3. 循环导入与实例传递错误:创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:54:57