Python设计图书馆管理系统技术文档(五)

5.3 管理功能实现

  • 这个程序管理员的功能就3个,添加书籍、淘汰书籍、用户管理。
5.3.1 管理员界面(AdminHome.py)
import sys
import qdarkstyle
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from UserManage import UserManage
from addBookDialog import addBookDialog
from dropBookDialog import dropBookDialog


class AdminHome(QWidget):
    def __init__(self):
        super().__init__()
        self.setUpUI()

    def setUpUI(self):
        self.resize(500, 600)
        self.setWindowTitle("欢迎使用图书馆管理系统")
        self.Hlayout = QHBoxLayout()
        self.buttonVlayout = QVBoxLayout()
        self.setLayout(self.Hlayout)

        font = QFont()
        font.setPixelSize(16)
        self.userManageButton = QPushButton("用户管理")
        self.addBookButton = QPushButton("添加书籍")
        self.dropBookButton = QPushButton("淘汰书籍")
        self.userManageButton.setFont(font)
        self.addBookButton.setFont(font)
        self.dropBookButton.setFont(font)
        self.userManageButton.setFixedWidth(100)
        self.userManageButton.setFixedHeight(42)
        self.addBookButton.setFixedWidth(100)
        self.addBookButton.setFixedHeight(42)
        self.dropBookButton.setFixedWidth(100)
        self.dropBookButton.setFixedHeight(42)
        self.buttonVlayout.addWidget(self.addBookButton)
        self.buttonVlayout.addWidget(self.dropBookButton)
        self.buttonVlayout.addWidget(self.userManageButton)
        # 将三个按钮所在的垂直布局添加到水平布局中
        self.Hlayout.addLayout(self.buttonVlayout)

        self.addBookButton.clicked.connect(self.addBookButtonClicked)
        self.dropBookButton.clicked.connect(self.dropBookButtonClicked)
        self.userManageButton.clicked.connect(self.userManage)

    def addBookButtonClicked(self):
        addDialog = addBookDialog(self)
        addDialog.show()
        addDialog.exec_()

    def dropBookButtonClicked(self):
        dropDialog = dropBookDialog(self)
        dropDialog.show()
        dropDialog.exec_()

    def userManage(self):
        UserDelete = UserManage(self)
        UserDelete.show()
        UserDelete.exec_()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("./images/MainWindow_1.png"))
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    mainMindow = AdminHome()
    mainMindow.show()
    sys.exit(app.exec_())
  • 代码分析
    • 本页面,就三个按钮。三个按钮对应三个信号槽函数。这三个函数,分别是添加书籍、淘汰书籍、用户管理的类实例。点击相应按钮后,弹出对应窗口。如图。
      在这里插入图片描述
5.3.2 用户管理(UserManage.py)
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import qdarkstyle
from PyQt5.QtSql import *
import time
import sip


class UserManage(QDialog):
    # 初始化
    def __init__(self, parent=None):
        super(UserManage, self).__init__(parent)
        self.resize(380, 400)
        self.Vlayout = QVBoxLayout()
        self.setLayout(self.Vlayout)
        self.setWindowTitle("管理用户")
        # 用户数
        self.userCount = 0
        self.oldDeleteId = ""
        self.oldDeleteName = ""
        self.deleteId = ""
        self.deleteName = ""
        self.setUpUI()

    def setUpUI(self):
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName('./db/LibraryManagement.db')
        self.db.open()
        self.query = QSqlQuery()
        self.getResult()

        '''1. 表格设置'''
        # 定义一个表格
        self.tableWidget = QTableWidget()
        # 设定表格行数为数据库查询到的user总数
        self.tableWidget.setRowCount(self.userCount)
        # 设定表格的列数为2列
        self.tableWidget.setColumnCount(2)
        # 表格的两列表头分别为”学号“、”姓名“
        self.tableWidget.setHorizontalHeaderLabels(['学号', '姓名'])
        # 然后再设定表不可编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 标题可拉伸
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 整行选中
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 展示表格控件
        self.Vlayout.addWidget(self.tableWidget)

        self.setRows()
        self.deleteUserButton = QPushButton("删 除 用 户")
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.deleteUserButton, Qt.AlignHCenter)
        self.widget = QWidget()
        self.widget.setLayout(hlayout)
        self.widget.setFixedHeight(48)
        font = QFont()
        font.setPixelSize(15)
        self.deleteUserButton.setFixedHeight(36)
        self.deleteUserButton.setFixedWidth(180)
        self.deleteUserButton.setFont(font)
        self.Vlayout.addWidget(self.widget, Qt.AlignCenter)
        # 设置信号
        self.deleteUserButton.clicked.connect(self.deleteUser)
        self.tableWidget.itemClicked.connect(self.getStudentInfo)

    # 返回学生用户的总数量
    def getResult(self):
        sql = "SELECT StudentId,Name FROM User WHERE IsAdmin=0"
        self.query.exec_(sql)
        self.userCount = 0
        while self.query.next():
            self.userCount += 1
        # sql = "SELECT StudentId,Name FROM User WHERE IsAdmin=0"
        self.query.exec_(sql)

    # 一行行的QTableWidgetItem赋值
    def setRows(self):
        font = QFont()
        font.setPixelSize(14)
        for i in range(self.userCount):
            if self.query.next():
                StudentIdItem = QTableWidgetItem(self.query.value(0))
                StudentNameItem = QTableWidgetItem(self.query.value(1))
                StudentIdItem.setFont(font)
                StudentNameItem.setFont(font)
                StudentIdItem.setTextAlignment(Qt.AlignCenter)
                StudentNameItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, 0, StudentIdItem)
                self.tableWidget.setItem(i, 1, StudentNameItem)
        # return

    # 在上面的信号槽中,连接下面这个槽函数,就会获取用户信息
    # 把要删除的ID和Name赋给变量
    def getStudentInfo(self):
        # 索引行的ID、姓名
        row = self.tableWidget.currentIndex().row()
        # 设置滚动,和行数保持一致
        self.tableWidget.verticalScrollBar().setSliderPosition(row)
        self.getResult()
        i = 0
        while self.query.next() and i != row:
            i = i + 1
        # 这段代码和下面对应的代码,有啥作用?
        # self.oldDeleteId = self.deleteId
        # self.oldDeleteName = self.deleteName
        self.deleteId = self.query.value(0)
        self.deleteName = self.query.value(1)

    # 删除用户
    def deleteUser(self):
        if self.deleteId == "" and self.deleteName == "":
            print(QMessageBox.warning(self, "警告", "请选中要删除的用户"))
            return
        # elif self.deleteId == self.oldDeleteId and self.deleteName == self.oldDeleteName:
        #     print(QMessageBox.warning(self, "警告", "该用户信息不存在"))
        #     return
        if QMessageBox.information(self, "提醒", "删除用户:%s,%s\n用户一经删除将无法恢复,是否继续?" % (self.deleteId, self.deleteName),
                                   QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.No:
            return
        # 从User表删除用户
        sql = "DELETE FROM User WHERE StudentId='%s'" % self.deleteId

        self.query.exec_(sql)
        self.db.commit()
        # 归还所有书籍
        sql = "SELECT * FROM User_Book  WHERE StudentId='%s' AND BorrowState=1" % self.deleteId
        self.query.exec_(sql)
        timeNow = time.strftime('%Y-%m-%d', time.localtime(time.time()))
        updateQuery = QSqlQuery()
        while self.query.next():
            bookId = self.query.value(1)
            sql = "UPDATE Book SET NumCanBorrow=NumCanBorrow+1 WHERE BookId='%s'" % bookId
            updateQuery.exec_(sql)
            self.db.commit()
        sql = "UPDATE User_Book SET ReturnTime='%s',BorrowState=0 WHERE StudentId='%s' AND BorrowState=1" % (
            timeNow, self.deleteId)
        self.query.exec_(sql)
        self.db.commit()
        print(QMessageBox.information(self, "提醒", "删除用户成功!", QMessageBox.Yes, QMessageBox.Yes))
        self.updateUI()
        return

    # 删除界面
    def updateUI(self):
        self.getResult()
        self.Vlayout.removeWidget(self.widget)
        self.Vlayout.removeWidget(self.tableWidget)
        sip.delete(self.widget)
        sip.delete(self.tableWidget)
        # 删除上一个界面,再重新进行表格设置,展示删除后的新界面
        self.tableWidget = QTableWidget()
        # 设置行数
        self.tableWidget.setRowCount(self.userCount)
        # 设置列数
        self.tableWidget.setColumnCount(2)
        # 设置表头
        self.tableWidget.setHorizontalHeaderLabels(['学号', '姓名'])
        # 不可编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 标题可拉伸
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 整行选中,QAbstractItemView视图
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.Vlayout.addWidget(self.tableWidget)

        self.setRows()
        """
        和上面的功能一样,删除了上面的界面,还要重新展示按钮,重新绑定一下两个槽函数
        :return
        """
        self.deleteUserButton = QPushButton("删 除 用 户")
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.deleteUserButton, Qt.AlignHCenter)
        self.widget = QWidget()
        self.widget.setLayout(hlayout)
        self.widget.setFixedHeight(48)
        font = QFont()
        font.setPixelSize(15)
        self.deleteUserButton.setFixedHeight(36)
        self.deleteUserButton.setFixedWidth(180)
        self.deleteUserButton.setFont(font)
        self.Vlayout.addWidget(self.widget, Qt.AlignCenter)
        # 设置信号
        self.deleteUserButton.clicked.connect(self.deleteUser)
        self.tableWidget.itemClicked.connect(self.getStudentInfo)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("./images/MainWindow_1.png"))
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    mainWindow = UserManage()
    mainWindow.show()
    sys.exit(app.exec_())


  • 代码分析
    • 这是一个对话框的窗体控件。只用一个垂直布局(外围红框),然后放入一个QTableWidget控件(淡黄的虚线)。先设置QTableWidgetItem(学号、姓名的单元格),再用数据库sql语句获取非管理员的所有用户getResult(sql之后左侧展示所有的行),放入QTableWidget里面显示setRows(把学号、姓名下面的单元格填入信息)。因为涉及到后面的删除操作,上图说明。
      在这里插入图片描述

    • 这两天阳了,也没吃药,光喝水,第3天,终于阳康了。

    • 在setUpUI最后,定义了两个信号槽

      self.deleteUserButton.clicked.connect(self.deleteUser)
      self.tableWidget.itemClicked.connect(self.getStudentInfo)
      
    • 在deleteUser函数里面,完成了如下工作。

      • (1)判断是否选择要删除的用户
      • (2)在选中删除用户后,点击删除弹出警告提醒。
      • (3)接着,在数据库中的Book表中修改还能借阅的数量NumCanBorrow。再把User_Book表中借阅的状态改为0(用户都不在了,为何不删除呢)
      • (4)最后,提醒删除成功,接着运行后面的函数方法updateUI()。
    • 在updateUI方法中,完成了如下工作。

      • (1)删除布局widget和表布局tableWidget。
      • (2)再重新进行表格设置,展示删除后的新界面。
      • (3)因为在这个函数一开始是删除了布局,所以,再重新生成“删除用户”按钮。
    • 至此,完成了这一对话框的分析和学习。

5.3.3 添加书籍(addBookDialog)
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import qdarkstyle
import time
from PyQt5.QtSql import *


class addBookDialog(QDialog):
    add_book_success_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(addBookDialog, self).__init__(parent)
        self.setUpUI()
        # 下面设置用以设置窗口模态类型为半模态,阻塞其他窗口反应半模态
        self.setWindowModality(Qt.WindowModal)
        self.setWindowTitle("添加书籍")

    def setUpUI(self):
        # 书名,书号,作者,分类,添加数量.出版社,出版日期
        # 书籍分类:哲学类、社会科学类、政治类、法律类、军事类、经济类、文化类、教育类、体育类、语言文字类、艺术类、历史类、地理类、天文学类、生物学类、医学卫生类、农业类
        BookCategory = ["哲学", "社会科学", "政治", "法律", "军事", "经济", "文化", "教育", "体育", "语言文字", "艺术",
                        "历史", "地理", "天文学", "生物学", "医学卫生", "农业"]
        self.resize(300, 300)
        self.Flayout = QFormLayout()
        self.setLayout(self.Flayout)

        # Label标签控件
        self.titlelabel = QLabel("  添加书籍")
        self.bookNameLabel = QLabel("书    名:")
        self.bookIdLabel = QLabel("书    号:")
        self.authNameLabel = QLabel("作    者:")
        self.categoryLabel = QLabel("分    类:")
        self.publisherLabel = QLabel("出 版 社:")
        self.publishDateLabel = QLabel("出版日期:")
        self.addNumLabel = QLabel("数    量:")

        # button控件
        self.addBookButton = QPushButton("添 加")

        # lineEdit控件
        self.bookNameEdit = QLineEdit()
        self.bookIdEdit = QLineEdit()
        self.authNameEdit = QLineEdit()
        # 分类创建的QComboBox,存储整个分类的列表。combo(联合体)
        # QComboBox,以占用最少屏幕控件的方式向用户呈现选项列表的方法
        self.categoryComboBox = QComboBox()
        self.categoryComboBox.addItems(BookCategory)
        self.publisherEdit = QLineEdit()
        self.publishTime = QDateTimeEdit()
        self.publishTime.setDisplayFormat("yyyy-MM-dd")
        # self.publishDateEdit = QLineEdit()
        self.addNumEdit = QLineEdit()

        self.bookNameEdit.setMaxLength(10)
        self.bookIdEdit.setMaxLength(6)
        self.authNameEdit.setMaxLength(10)
        self.publisherEdit.setMaxLength(10)
        self.addNumEdit.setMaxLength(12)
        self.addNumEdit.setValidator(QIntValidator())

        # 添加进formlayout
        self.Flayout.addRow("", self.titlelabel)
        self.Flayout.addRow(self.bookNameLabel, self.bookNameEdit)
        self.Flayout.addRow(self.bookIdLabel, self.bookIdEdit)
        self.Flayout.addRow(self.authNameLabel, self.authNameEdit)
        self.Flayout.addRow(self.categoryLabel, self.categoryComboBox)
        self.Flayout.addRow(self.publisherLabel, self.publisherEdit)
        self.Flayout.addRow(self.publishDateLabel, self.publishTime)
        self.Flayout.addRow(self.addNumLabel, self.addNumEdit)
        self.Flayout.addRow("", self.addBookButton)

        # 设置字体
        font = QFont()
        font.setPixelSize(20)
        self.titlelabel.setFont(font)
        font.setPixelSize(14)
        self.bookNameLabel.setFont(font)
        self.bookIdLabel.setFont(font)
        self.authNameLabel.setFont(font)
        self.categoryLabel.setFont(font)
        self.publisherLabel.setFont(font)
        self.publishDateLabel.setFont(font)
        self.addNumLabel.setFont(font)

        self.bookNameEdit.setFont(font)
        self.bookIdEdit.setFont(font)
        self.authNameEdit.setFont(font)
        self.publisherEdit.setFont(font)
        self.publishTime.setFont(font)
        self.categoryComboBox.setFont(font)
        self.addNumEdit.setFont(font)

        # button设置
        font.setPixelSize(16)
        self.addBookButton.setFont(font)
        self.addBookButton.setFixedHeight(32)
        self.addBookButton.setFixedWidth(140)

        # 设置间距
        self.titlelabel.setMargin(8)
        self.Flayout.setVerticalSpacing(10)

        self.addBookButton.clicked.connect(self.addBookButtonCicked)

    def addBookButtonCicked(self):
        bookName = self.bookNameEdit.text()
        bookId = self.bookIdEdit.text()
        authName = self.authNameEdit.text()
        bookCategory = self.categoryComboBox.currentText()
        publisher = self.publisherEdit.text()
        publishTime = self.publishTime.text()
        addBookNum = self.addNumEdit.text()
        if (
                bookName == "" or bookId == "" or authName == "" or bookCategory == "" or publisher == "" or publishTime == "" or addBookNum == ""):
            print(QMessageBox.warning(self, "警告", "有字段为空,添加失败", QMessageBox.Yes, QMessageBox.Yes))
            return
        else:
            addBookNum = int(addBookNum)
            db = QSqlDatabase.addDatabase("QSQLITE")
            db.setDatabaseName('./db/LibraryManagement.db')
            db.open()
            query = QSqlQuery()
            # 如果已存在,则update Book表的现存量,剩余可借量,不存在,则insert Book表,同时insert buyordrop表
            sql = "SELECT * FROM Book WHERE BookId='%s'" % bookId
            query.exec_(sql)
            if query.next():
                sql = "UPDATE Book SET NumStorage=NumStorage+%d,NumCanBorrow=NumCanBorrow+%d WHERE BookId='%s'" % (
                    addBookNum, addBookNum, bookId)
            else:
                sql = "INSERT INTO book VALUES ('%s','%s','%s','%s','%s','%s',%d,%d,0)" % (
                    bookName, bookId, authName, bookCategory, publisher, publishTime, addBookNum, addBookNum)
            query.exec_(sql)
            db.commit()
            # 插入droporinsert表
            timenow = time.strftime('%Y-%m-%d', time.localtime(time.time()))
            sql = "INSERT INTO buyordrop VALUES ('%s','%s',1,%d)" % (bookId, timenow, addBookNum)
            query.exec_(sql)
            db.commit()
            print(QMessageBox.information(self, "提示", "添加书籍成功!", QMessageBox.Yes, QMessageBox.Yes))
            self.add_book_success_signal.emit()
            self.close()
            self.clearEdit()
        return

    def clearEdit(self):
        self.bookNameEdit.clear()
        self.bookIdEdit.clear()
        self.authNameEdit.clear()
        self.addNumEdit.clear()
        self.publisherEdit.clear()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("./images/MainWindow_1.png"))
    app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
    mainMindow = addBookDialog()
    mainMindow.show()
    sys.exit(app.exec_())


  • 经过几节的学习,这个对话框控件的学习,就显得比较简单了。布局最后,再定义一个信号槽。槽函数addBookButtonCicked对应“添加”按钮,里面具体完成的工作是,如果这本书图书馆已经有的话,则只是更新数量UPDATE,没有是INSERT。还不要忘记在buyordrop表中增添一个添加书籍的记录。最后再调用函数方法clearEdit,完成一次添加工作。
5.3.4 淘汰书籍(dropBookDialog.py)
  • 这个对话框页面,更加简单,布局最后定义两个信号槽。

      self.bookIdEdit.textChanged.connect(self.bookIdEditChanged)
      self.dropBookButton.clicked.connect(self.dropBookButtonClicked)
    
  • 槽函数bookIdEditChanged对应“书号”的文本触发,一旦有这本书的话,马上把对话框各个字段全部更新显示出来。

  • 槽函数dropBookButtonClicked是按下“淘汰”按钮后的方法处理。先判断是否选择要淘汰的书籍,还要判断是否超过原有库存数量,这里获取的是book表里的第7个字段NumStorage,超了的话,提醒。然后,就可以删除Book表对应的记录,还不要忘记在buyordrop表中增添一个淘汰书籍的记录。最后再调用函数方法QMessageBox消息提醒,删除成功,关闭完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山哥ol

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值