本节为最后两个部分:主函数main和修改密码页面。
主要流程:1、主函数默认为登录页面,可以通过主函数的登录页面根据账号特性来登录管理员页面和学生用户主界面。
2、主函数加上菜单栏,可以进行登录、退出登录、注册、修改密码和退出等操作。
3、修改密码页面,可以根据之前的账号和密码校验,设置新的密码。
一、修改密码页面
导入的模块:
import hashlib
import sys
import qdarkstyle
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
(一)类基础设置
- 设置界面主题调用新的函数。
class changePasswordDialog(QDialog):
def __init__(self, parent=None):
super(changePasswordDialog, self).__init__(parent)
self.setWindowModality(Qt.WindowModal)
self.setWindowTitle("修改密码")
self.setUpUI()
(二)修改密码页面布局
1、设置页面大小和表单布局类型
def setUpUI(self):
self.resize(300, 280)
self.layout = QFormLayout()
self.setLayout(self.layout)
2、设置标签和输入框
- 设置标签和输入框
self.titlelabel = QLabel(" 修改密码")
self.studentIdLabel = QLabel("学 号:")
self.oldPasswordLabel = QLabel("旧 密 码:")
self.passwordLabel = QLabel("新 密 码:")
self.confirmPasswordLabel = QLabel("确认密码:")
self.studentIdEdit = QLineEdit()
self.oldPasswordEdit = QLineEdit()
self.passwordEdit = QLineEdit()
self.confirmPasswordEdit = QLineEdit()
- 设置标签和输入框字体大小
font = QFont()
font.setPixelSize(20)
self.titlelabel.setFont(font)
font.setPixelSize(16)
self.studentIdLabel.setFont(font)
self.oldPasswordLabel.setFont(font)
self.passwordLabel.setFont(font)
self.confirmPasswordLabel.setFont(font)
font.setPixelSize(16)
self.studentIdEdit.setFont(font)
self.changePasswordButton.setFont(font)
font.setPixelSize(10)
self.oldPasswordEdit.setFont(font)
self.passwordEdit.setFont(font)
self.confirmPasswordEdit.setFont(font)
# 设置标题的边距与间距
self.titlelabel.setMargin(8)
self.layout.setVerticalSpacing(10)
- 设置输入框输入内容的长度
self.studentIdEdit.setMaxLength(10)
self.oldPasswordEdit.setMaxLength(16)
self.passwordEdit.setMaxLength(16)
self.confirmPasswordEdit.setMaxLength(16)
- 设置密码掩膜
self.oldPasswordEdit.setEchoMode(QLineEdit.Password)
self.passwordEdit.setEchoMode(QLineEdit.Password)
self.confirmPasswordEdit.setEchoMode(QLineEdit.Password)
3、设置“确认修改”按钮
- 按钮标签和大小
self.changePasswordButton = QPushButton("确认修改")
self.changePasswordButton.setFixedWidth(140)
self.changePasswordButton.setFixedHeight(32)
4、在表单布局内添加以上控件
self.layout.addRow("", self.titlelabel)
self.layout.addRow(self.studentIdLabel, self.studentIdEdit)
self.layout.addRow(self.oldPasswordLabel, self.oldPasswordEdit)
self.layout.addRow(self.passwordLabel, self.passwordEdit)
self.layout.addRow(self.confirmPasswordLabel, self.confirmPasswordEdit)
self.layout.addRow("", self.changePasswordButton)
5、设置校验,限制输入的类型和数量
- 设置学生学号输入内容的类型
reg = QRegExp("PB[0~9]{8}")
pValidator = QRegExpValidator(self)
pValidator.setRegExp(reg)
self.studentIdEdit.setValidator(pValidator)
- 设置密码的输入内容类型
reg = QRegExp("[a-zA-z0-9]+$")
pValidator.setRegExp(reg)
self.oldPasswordEdit.setValidator(pValidator)
self.passwordEdit.setValidator(pValidator)
self.confirmPasswordEdit.setValidator(pValidator)
(三)信号传递
1、发送信号
- 绑定点击确认修改的按钮,点击后发送信号,触发修改密码函数
-
self.changePasswordButton.clicked.connect(self.changePasswordButtonClicked)
2、接收信号
- 槽函数
- 调用修改密码函数
-
def changePasswordButtonClicked(self):
(1)接收输入框文本内容,判断是否为空,若为空,则进行消息提醒
studentId = self.studentIdEdit.text()
oldPassword = self.oldPasswordEdit.text()
password = self.passwordEdit.text()
confirmPassword = self.confirmPasswordEdit.text()
if studentId == "" or oldPassword == "" or password == "" or confirmPassword == "":
print(QMessageBox.warning(self, "警告", "输入不可为空,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
return
(2)连接数据库,判断学生学号是否存在。
- 若不存在进行消息提醒。
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('./db/LibraryManagement.db')
db.open()
query = QSqlQuery()
sql = "SELECT * FROM User WHERE StudentId='%s'" % studentId
query.exec_(sql)
# 如果用户不存在
if not query.next():
print(QMessageBox.warning(self, "警告", "该用户不存在,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.studentIdEdit.clear()
return
- 若存在,则进行信息比对
- 校验学号和旧密码是否正确,若不正确,则查询无果不存在。
- 进行消息提示,旧密码输入错误。
hl = hashlib.md5()
hl.update(oldPassword.encode(encoding='utf-8'))
md5password = hl.hexdigest()
sql = "SELECT * FROM User WHERE Password='%s' AND StudentId='%s'" % (md5password, studentId)
query.exec_(sql)
if not query.next():
print(QMessageBox.warning(self, "警告", "原密码输入错误,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.oldPasswordEdit.clear()
return
- 若校验学号和旧密码成功,则存在。
- 判断重新输入的密码和确认输入的密码是否相同。
- 若不同则提示。
if password != confirmPassword:
print(QMessageBox.warning(self, "警告", "两次输入密码不同,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.passwordEdit.clear()
self.confirmPasswordEdit.clear()
return
- 若以上情况不存在,重新输入的密码和确认输入的密码相同
- 则修改成功,进行消息提示。
hl = hashlib.md5()
hl.update(password.encode(encoding='utf-8'))
md5password = hl.hexdigest()
sql = "UPDATE User SET Password='%s' WHERE StudentId='%s'" % (md5password, studentId)
query.exec_(sql)
db.commit()
QMessageBox.information(self, "提醒", "修改密码成功,请登录系统!", QMessageBox.Yes, QMessageBox.Yes)
self.close()
return
(四)程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./images/MainWindow_1.png"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainWindow = changePasswordDialog()
mainWindow.show()
sys.exit(app.exec_())
二、主函数main页面
导入的模块:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import qdarkstyle
# 登录页面模块
from Signin import SignInWidget
# 注册页面模块
from SignUP import SignUpWidet
from PyQt5 import sip
# 管理员页面模块
from AdminHome import AdminHome
# 学生页面模块
from StudentHome import StudentHome
# 修改密码模块
from changePasswordDialog import changePasswordDialog
(一)类基础设置
- 初始化主页面信息
class Main(QMainWindow):
def __init__(self, parent=None):
"""1.初始化主页信息 """
super(Main, self).__init__(parent)
# 水平布局
self.layout = QHBoxLayout()
(二)主函数页面
1、登录窗口界面
self.widget = SignInWidget()
# 定义尺寸
self.resize(900, 600)
# 定义标题
self.setWindowTitle("欢迎登陆图书馆管理系统")
# 居中显示
self.setCentralWidget(self.widget)
2、设置菜单栏控件
bar = self.menuBar()
self.Menu = bar.addMenu("菜单栏")
3、定义菜单栏时的各动作部件,并添加到菜单栏
self.signUpAction = QAction("注册", self)
self.changePasswordAction = QAction("修改密码", self)
self.signInAction = QAction("登录", self)
self.quitSignInAction = QAction("退出登录", self)
self.quitAction = QAction("退出", self)
self.Menu.addAction(self.signUpAction)
self.Menu.addAction(self.changePasswordAction)
self.Menu.addAction(self.signInAction)
self.Menu.addAction(self.quitSignInAction)
self.Menu.addAction(self.quitAction)
4、设置菜单栏上各部件触发的有效性
self.signUpAction.setEnabled(True)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(False)
(三)信号传递
# 连续三个信号槽,分别连接定位到AdminHome.py(管理员主主页)、StudentHome.py(用户主页)、
# menuTriggered方法(菜单弹出动作)
self.widget.is_admin_signal.connect(self.adminSignIn)
self.widget.is_student_signal[str].connect(self.studentSignIn)
self.Menu.triggered[QAction].connect(self.menuTriggered)
1、信号一
- self.widget.is_admin_signal.connect(self.adminSignIn)
- 连接管理员主页
- 调用管理员主页面函数
- 管理员登录页面的弹出和展示效果
def adminSignIn(self):
# 删除当前显示的窗口页面
sip.delete(self.widget)
# 调用管理员界面模块
self.widget = AdminHome()
# 设置为当前主页面
self.setCentralWidget(self.widget)
# 在菜单栏内点击修改密码无效
self.changePasswordAction.setEnabled(False)
# 点击注册页面有效
self.signUpAction.setEnabled(True)
# 点击登录页面无效
self.signInAction.setEnabled(False)
# 点击退出登录有效
self.quitSignInAction.setEnabled(True)
2、信号二
- self.widget.is_student_signal[str].connect(self.studentSignIn)
- 连接学生主界面
- 用户(学生)登录页面的弹出和展示效果
def studentSignIn(self, studentId):
sip.delete(self.widget)
self.widget = StudentHome(studentId)
self.setCentralWidget(self.widget)
self.changePasswordAction.setEnabled(False)
self.signUpAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(True)
3、信号三
- self.Menu.triggered[QAction].connect(self.menuTriggered)
- 绑定菜单栏内的行为动作
- 根据点击的对应内容触发调用相应窗口
- 主窗口菜单栏选项的弹出和展示效果
def menuTriggered(self, q):
if q.text() == "修改密码":
changePsdDialog = changePasswordDialog(self)
changePsdDialog.show()
changePsdDialog.exec_()
if q.text() == "注册":
sip.delete(self.widget)
self.widget = SignUpWidet()
self.setCentralWidget(self.widget)
# 注册成功后自动进入学生主页面
self.widget.student_signup_signal[str].connect(self.studentSignIn)
self.signUpAction.setEnabled(False)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(True)
self.quitSignInAction.setEnabled(False)
if q.text() == "退出登录" or q.text() == "登录":
sip.delete(self.widget)
self.widget = SignInWidget()
self.setCentralWidget(self.widget)
self.widget.is_admin_signal.connect(self.adminSignIn)
self.widget.is_student_signal[str].connect(self.studentSignIn)
self.signUpAction.setEnabled(True)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(False)
if q.text() == "退出":
q_app = QApplication.instance()
q_app.quit()
return
(四)程序入口
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./images/MainWindow_1.png"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainWindow = Main()
mainWindow.show()
sys.exit(app.exec_())
三、完整代码
(一)修改密码页面
修改密码页面完整代码
import hashlib
import sys
import qdarkstyle
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
class changePasswordDialog(QDialog):
def __init__(self, parent=None):
super(changePasswordDialog, self).__init__(parent)
self.setWindowModality(Qt.WindowModal)
self.setWindowTitle("修改密码")
self.setUpUI()
def setUpUI(self):
self.resize(300, 280)
self.layout = QFormLayout()
self.setLayout(self.layout)
# 自上而下,5个标签
self.titlelabel = QLabel(" 修改密码")
self.studentIdLabel = QLabel("学 号:")
self.oldPasswordLabel = QLabel("旧 密 码:")
self.passwordLabel = QLabel("新 密 码:")
self.confirmPasswordLabel = QLabel("确认密码:")
# 自上而下,4个文本框
self.studentIdEdit = QLineEdit()
self.oldPasswordEdit = QLineEdit()
self.passwordEdit = QLineEdit()
self.confirmPasswordEdit = QLineEdit()
# “确认修改”按钮
self.changePasswordButton = QPushButton("确认修改")
self.changePasswordButton.setFixedWidth(140)
self.changePasswordButton.setFixedHeight(32)
# 在表单布局放置以上小控件
self.layout.addRow("", self.titlelabel)
self.layout.addRow(self.studentIdLabel, self.studentIdEdit)
self.layout.addRow(self.oldPasswordLabel, self.oldPasswordEdit)
self.layout.addRow(self.passwordLabel, self.passwordEdit)
self.layout.addRow(self.confirmPasswordLabel, self.confirmPasswordEdit)
self.layout.addRow("", self.changePasswordButton)
font = QFont()
font.setPixelSize(20)
self.titlelabel.setFont(font)
font.setPixelSize(16)
self.studentIdLabel.setFont(font)
self.oldPasswordLabel.setFont(font)
self.passwordLabel.setFont(font)
self.confirmPasswordLabel.setFont(font)
font.setPixelSize(16)
self.studentIdEdit.setFont(font)
self.changePasswordButton.setFont(font)
font.setPixelSize(10)
self.oldPasswordEdit.setFont(font)
self.passwordEdit.setFont(font)
self.confirmPasswordEdit.setFont(font)
self.titlelabel.setMargin(8)
self.layout.setVerticalSpacing(10)
# 设置长度
self.studentIdEdit.setMaxLength(10)
self.oldPasswordEdit.setMaxLength(16)
self.passwordEdit.setMaxLength(16)
self.confirmPasswordEdit.setMaxLength(16)
# 设置密码掩膜
self.oldPasswordEdit.setEchoMode(QLineEdit.Password)
self.passwordEdit.setEchoMode(QLineEdit.Password)
self.confirmPasswordEdit.setEchoMode(QLineEdit.Password)
# 设置校验,限制输入的类型和数量
reg = QRegExp("PB[0~9]{8}")
pValidator = QRegExpValidator(self)
pValidator.setRegExp(reg)
self.studentIdEdit.setValidator(pValidator)
reg = QRegExp("[a-zA-z0-9]+$")
pValidator.setRegExp(reg)
self.oldPasswordEdit.setValidator(pValidator)
self.passwordEdit.setValidator(pValidator)
self.confirmPasswordEdit.setValidator(pValidator)
# 设置信号与槽
self.changePasswordButton.clicked.connect(self.changePasswordButtonClicked)
def changePasswordButtonClicked(self):
studentId = self.studentIdEdit.text()
oldPassword = self.oldPasswordEdit.text()
password = self.passwordEdit.text()
confirmPassword = self.confirmPasswordEdit.text()
if studentId == "" or oldPassword == "" or password == "" or confirmPassword == "":
print(QMessageBox.warning(self, "警告", "输入不可为空,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
return
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('./db/LibraryManagement.db')
db.open()
query = QSqlQuery()
sql = "SELECT * FROM User WHERE StudentId='%s'" % studentId
query.exec_(sql)
# 如果用户不存在
if not query.next():
print(QMessageBox.warning(self, "警告", "该用户不存在,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.studentIdEdit.clear()
return
# 如果密码错误
hl = hashlib.md5()
hl.update(oldPassword.encode(encoding='utf-8'))
md5password = hl.hexdigest()
sql = "SELECT * FROM User WHERE Password='%s' AND StudentId='%s'" % (md5password, studentId)
query.exec_(sql)
if not query.next():
print(QMessageBox.warning(self, "警告", "原密码输入错误,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.oldPasswordEdit.clear()
return
# 密码与确认密码不同
if password != confirmPassword:
print(QMessageBox.warning(self, "警告", "两次输入密码不同,请重新输入", QMessageBox.Yes, QMessageBox.Yes))
self.passwordEdit.clear()
self.confirmPasswordEdit.clear()
return
# 修改密码
hl = hashlib.md5()
hl.update(password.encode(encoding='utf-8'))
md5password = hl.hexdigest()
sql = "UPDATE User SET Password='%s' WHERE StudentId='%s'" % (md5password, studentId)
query.exec_(sql)
db.commit()
QMessageBox.information(self, "提醒", "修改密码成功,请登录系统!", QMessageBox.Yes, QMessageBox.Yes)
self.close()
return
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./iron-man.png"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainWindow = changePasswordDialog()
mainWindow.show()
sys.exit(app.exec_())
(二)主函数main页面
主函数main页面代码
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import qdarkstyle
from Signin import SignInWidget
from SignUP import SignUpWidet
from PyQt5 import sip
from AdminHome import AdminHome
from StudentHome import StudentHome
from changePasswordDialog import changePasswordDialog
# 主窗口设计
class Main(QMainWindow):
def __init__(self, parent=None):
"""1.初始化主页信息 """
super(Main, self).__init__(parent)
# 水平布局
self.layout = QHBoxLayout()
# 定义登录窗体控件
self.widget = SignInWidget()
# 定义尺寸
self.resize(900, 600)
# 定义标题
self.setWindowTitle("欢迎登陆图书馆管理系统")
# 居中显示
self.setCentralWidget(self.widget)
# 定义菜单栏
bar = self.menuBar()
self.Menu = bar.addMenu("菜单栏")
# 定义菜单栏时的各动作部件,并添加到菜单栏
self.signUpAction = QAction("注册", self)
self.changePasswordAction = QAction("修改密码", self)
self.signInAction = QAction("登录", self)
self.quitSignInAction = QAction("退出登录", self)
self.quitAction = QAction("退出", self)
self.Menu.addAction(self.signUpAction)
self.Menu.addAction(self.changePasswordAction)
self.Menu.addAction(self.signInAction)
self.Menu.addAction(self.quitSignInAction)
self.Menu.addAction(self.quitAction)
# 设置菜单栏上各部件触发的有效性
self.signUpAction.setEnabled(True)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(False)
# 连续三个信号槽,分别连接定位到AdminHome.py(管理员主主页)、StudentHome.py(用户主页)、
# menuTriggered方法(菜单弹出动作)
self.widget.is_admin_signal.connect(self.adminSignIn)
self.widget.is_student_signal[str].connect(self.studentSignIn)
self.Menu.triggered[QAction].connect(self.menuTriggered)
# 管理员登录页面的弹出和展示效果
def adminSignIn(self):
sip.delete(self.widget)
self.widget = AdminHome()
self.setCentralWidget(self.widget)
self.changePasswordAction.setEnabled(False)
self.signUpAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(True)
# 用户(学生)登录页面的弹出和展示效果
def studentSignIn(self, studentId):
sip.delete(self.widget)
self.widget = StudentHome(studentId)
self.setCentralWidget(self.widget)
self.changePasswordAction.setEnabled(False)
self.signUpAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(True)
# 主窗口菜单栏选项的弹出和展示效果
def menuTriggered(self, q):
if q.text() == "修改密码":
changePsdDialog = changePasswordDialog(self)
changePsdDialog.show()
changePsdDialog.exec_()
if q.text() == "注册":
sip.delete(self.widget)
self.widget = SignUpWidet()
self.setCentralWidget(self.widget)
# 注册成功后自动进入学生主页面
self.widget.student_signup_signal[str].connect(self.studentSignIn)
self.signUpAction.setEnabled(False)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(True)
self.quitSignInAction.setEnabled(False)
if q.text() == "退出登录" or q.text() == "登录":
sip.delete(self.widget)
self.widget = SignInWidget()
self.setCentralWidget(self.widget)
self.widget.is_admin_signal.connect(self.adminSignIn)
self.widget.is_student_signal[str].connect(self.studentSignIn)
self.signUpAction.setEnabled(True)
self.changePasswordAction.setEnabled(True)
self.signInAction.setEnabled(False)
self.quitSignInAction.setEnabled(False)
if q.text() == "退出":
q_app = QApplication.instance()
q_app.quit()
return
# 主main入口
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./iron-man.png"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainWindow = Main()
mainWindow.show()
sys.exit(app.exec_())
四、完整效果展示
(一)修改密码页面效果展示
- 修改密码主页面
- 若输入学号错误则提示不存在
- 若原密码输入错误则进行相应提示
- 若学号和旧密码均正确,新密码两次不一致则进行相应提示。
- 若学号、旧密码、两次新密码输入一致,则提示修改密码成功。
(二)main主函数页面
- main主界面
- 登录管理员账号,自动跳转至管理员界面
- 菜单栏点击退出登录,返回登录界面
- 输入学生账号,自动跳转至学生主界面
- 点击注册,显示注册窗口
- 点击修改密码,进入修改密码窗口
- 点击退出,则直接退出main程序
五、总结:
图书管理系统主要分为四个部分:main主函数、管理员界面、学生界面和数据库。
- 图书管理系统共计十三个模块,具体功能模块如下:
(一)main主函数
- main.py
1、登录界面(Signin.py)
2、注册界面(SignUP.py)
3、修改密码界面(changePasswordDialog.py)
(二)管理员界面
- AdminHome.py
1、添加书籍界面(addBookDialog.py)
2、用户管理界面(UserMange.py)
3、淘汰书籍界面(dropBookDialog.py)
4、所有书籍界面(BookStorageViewer.py)
(三)学生界面
- StudentHome.py
1、借书界面(borrowBookDialog.py)
2、还书页面(returnBookDialog.py)
3、借阅状态界面(BorrowStatusViewer.py)
4、所有书籍页面(BookStorageViewer.py)
(四)数据库
LibraryManagement.db数据库主要由五个表:所有书籍表Book、添加和淘汰书籍信息记录表BuyOrDrop、用户信息表User、用户借阅书籍的状态表User_Book、SQLite的系统表sqlite_master。
1、所有书籍表Book
- 库存总量 = 可借阅量+已借阅量
- 若不相等,则为sql语句修改数据库时的错误,忽略即可。
2、添加和淘汰书籍信息记录表BuyOrDrop
- 其中Time记录的时间,是操作时的时间
- BuyOrDrop添加或淘汰,1为添加,0为淘汰。
3、用户信息表User
- IsAdmin是否为管理员,1是管理员,0是学生用户
4、用户借阅书籍的状态表User_Book
- ReturnTime归还时间显示<null>,则表示未归还。
- BorrowState借阅状态,1表示未归还,0表示已归还。
5、SQLite的系统表sqlite_master
- sqlite_master表是SQLite的系统表。该表记录该数据库中保存的表、索引、视图、和触发器信息。每一行记录一个项目。在创建一个SQLIte数据库的时候,该表会自动创建。sqlite_master表包含5列。
- type列记录了项目的类型,如table、index、view、trigger。
- name列记录了项目的名称,如表名、索引名等。
- tbl_name列记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身。
- rootpage列记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL。
- sql列记录创建该项目的SQL语句。
图书管理系统完结✌
标签:setEnabled,widget,--,self,pyqt5,密码,QMessageBox,import,main From: https://www.cnblogs.com/LoLong/p/16994934.html