PyQt5高校系统:登录后讲师课程界面无法获取ID加载课程及界面联动问题
问题描述
我们用PyQt5和Python开发了一套高校系统,讲师通过ID和密码登录后,进入的课程界面没法根据登录ID加载对应讲师的课程(ID传不到后续界面),同时各界面操作也没实现联动。目前尝试过把用户ID设为全局变量、创建前一界面对象调用方法,但要么出现“User未定义”错误,要么ID虽已定义但课程列表为空,想知道怎么实现界面联动,以及让前一界面的变更同步到后一界面。
相关代码
class InstructorLogin(QDialog): def __init__(self): super(InstructorLogin, self).__init__() loadUi("NewInstructorLogin.ui",self) self.LoginInst.clicked.connect(self.gotoAfterInstLogin) self.ExitLoginInst.clicked.connect(self.gotoMainExit1) self.PmuPassInstButton.setEchoMode(QtWidgets.QLineEdit.Password) #For the password def gotoAfterInstLogin(self): global f global user user = self.PmuIDInstButton.text() password = self.PmuPassInstButton.text() # print(user) if len(user)==0 or len(password)==0: self.InvalidPassLab.setText("Please input all fields.") else: conn = sqlite3.connect("Cognito.db") cur = conn.cursor() query = 'SELECT Password FROM Instructor WHERE Instructor_id =\''+user+"\'" cur.execute(query) result_pass = cur.fetchone()[0] #to compare password if result_pass == password: self.gotoInstructorLoginAbulBashar() #####end of noorsol else: self.InvalidPassLab.setText("Invalid username or password") def gotoMainExit1(self): widget.setCurrentIndex(widget.currentIndex()-1) #Remove comment later def gotoInstructorLoginAbulBashar(self): widget.setCurrentIndex(widget.currentIndex()+15) # def user_getter(self): # return user ######################################################################################################################## class ChooseCourseInst(QMainWindow): global user def __init__(self): super(ChooseCourseInst, self).__init__() #self.afterObj = AfterInstructorLogin() self.afterInstructorLogin = AfterInstructorLogin() loadUi("CoursesChosenInt.ui",self) widget.setCurrentIndex(widget.currentIndex()+4) self.exitabulbashar.clicked.connect(self.gotoexitabulbashar) #self.InstServButton.clicked.connect(self.gotoInstServButton) self.coursesreq.activated.connect(self.gotoInstServButton) #self.courses(user) #print(user) def courses(self): self.instructorLogin = InstructorLogin() conn = sqlite3.connect("Cognito.db") query = 'SELECT DISTINCT Course_name FROM Course WHERE Instructor_id =\''+self.instructorLogin.gotoAfterInstLogin(user)+"\'" cur = conn.cursor() cur.execute(query) final_result = [i[0] for i in cur.fetchall()] for i in range(len(final_result)): self.coursesreq.addItem(final_result[i]) def gotoexitabulbashar(self): widget.setCurrentIndex(widget.currentIndex()-16) def gotoInstServButton(self): self.chosencourse = self.coursesreq.currentText() self.afterInstructorLogin.labeltest.setText(self.chosencourse) self.afterInstructorLogin.diplayInfo() #self.afterInstructorLogin.labeltest.show() widget.setCurrentIndex(widget.currentIndex()-11)
解决方案
1. 废弃全局变量,用构造传参传递用户ID
全局变量容易出现作用域混乱问题,直接在跳转界面时把登录成功的用户ID传给目标界面实例:
# 修改InstructorLogin的跳转方法 def gotoInstructorLoginAbulBashar(self): self.close() # 创建课程选择界面并传入用户ID self.course_window = ChooseCourseInst(user_id=user) self.course_window.show() # 修改ChooseCourseInst的构造方法 class ChooseCourseInst(QMainWindow): def __init__(self, user_id): super(ChooseCourseInst, self).__init__() loadUi("CoursesChosenInt.ui",self) # 保存用户ID为实例属性 self.user_id = user_id # 绑定控件信号 self.exitabulbashar.clicked.connect(self.gotoexitabulbashar) self.coursesreq.activated.connect(self.gotoInstServButton) # 初始化加载课程 self.load_courses()
2. 修复课程加载逻辑,刷新界面
原来的课程加载方法错误地重新创建登录实例,直接用保存的用户ID查询并刷新下拉框:
def load_courses(self): # 先清空下拉框避免重复数据 self.coursesreq.clear() conn = sqlite3.connect("Cognito.db") cur = conn.cursor() # 用参数化查询避免SQL注入,不要直接拼接字符串 query = 'SELECT DISTINCT Course_name FROM Course WHERE Instructor_id = ?' cur.execute(query, (self.user_id,)) final_result = [i[0] for i in cur.fetchall()] for course in final_result: self.coursesreq.addItem(course) conn.close()
3. 实现界面联动与变更同步
(1)正向传递数据
选择课程后跳转时,直接把选中的课程传给后续界面:
def gotoInstServButton(self): chosen_course = self.coursesreq.currentText() self.close() # 创建后续界面并传入用户ID和选中课程 self.after_window = AfterInstructorLogin(user_id=self.user_id, chosen_course=chosen_course) self.after_window.show() # 修改AfterInstructorLogin的构造方法 class AfterInstructorLogin(QMainWindow): def __init__(self, user_id, chosen_course): super().__init__() loadUi("对应的UI文件.ui", self) self.user_id = user_id # 直接更新界面内容 self.labeltest.setText(chosen_course) self.displayInfo()
(2)反向同步变更
如果需要后续界面的操作回传更新到前一界面,用PyQt的信号槽机制:
# 在AfterInstructorLogin中定义自定义信号 from PyQt5.QtCore import pyqtSignal class AfterInstructorLogin(QMainWindow): course_updated = pyqtSignal(str) # 定义传递更新后课程名的信号 def update_course(self, new_course_name): # 课程更新后发射信号 self.course_updated.emit(new_course_name) # 在ChooseCourseInst中绑定信号与刷新逻辑 def gotoInstServButton(self): chosen_course = self.coursesreq.currentText() self.after_window = AfterInstructorLogin(user_id=self.user_id, chosen_course=chosen_course) # 绑定信号到刷新方法 self.after_window.course_updated.connect(self.refresh_course_list) self.after_window.show() def refresh_course_list(self, updated_course): # 重新加载课程列表 self.load_courses()
4. 额外修复:SQL注入风险
原代码直接拼接用户输入到SQL语句中,存在严重安全漏洞,必须改用参数化查询(如上面load_courses中的写法),用?作为占位符传递参数。
内容的提问来源于stack exchange,提问作者Fatimah
相关产品推荐
相关产品推荐

