python结合QT实现简单的图书管理系统

 更新时间:2026年02月25日 09:16:37   作者:忘忧记  
这篇文章主要介绍了一个基于Python和PyQt5的图书管理系统开发教程,适合Python初学者学习,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

适用对象:Python 初学者、刚接触面向对象和 GUI 编程的同学

目标:带你从零理解一个基于 PyQt5 的小型图书管理系统架构与实现细节

一、项目整体结构概览

我们这个系统由以下几个核心模块组成:

模块功能
model/数据模型(User, Book, Role, Permission)
dao/数据访问层(Database)
controller/控制逻辑(用户、图书、权限控制)
view/用户界面(登录、注册、不同角色主窗口)
main.py程序入口

二、数据模型(Model)

1. 角色定义 ——role.py

class Role:
    ADMIN = "admin"
    TEACHER = "teacher"
    STUDENT = "student"
  • 这里用类变量模拟“枚举”,避免魔法字符串。
  • 后续所有判断角色的地方都用 Role.ADMIN 而不是 "admin",更安全、可读性高。

2. 权限定义 ——permission.py

class Permission:
    ADD_BOOK = "add_book"
    DELETE_BOOK = "delete_book"
    IMPORT_BOOK = "import_book"
    EXPORT_BOOK = "export_book"

同样是枚举思想,定义系统支持的所有操作权限。

3. 用户模型 ——user.py

class User:
    def __init__(self, id, username, role):
        self.id = id
        self.username = username
        self.role = role

封装用户基本信息,用于在程序中传递身份。

4. 图书模型 ——book.py

class Book:
    def __init__(self, id, title, author, isbn, category):
        self.id = id
        self.title = title
        self.author = author
        self.isbn = isbn
        self.category = category

虽然当前代码中没直接用到 Book 类(因为数据库返回的是字典),但保留它为未来扩展打基础。

三、数据访问层(DAO)——database.py

import sqlite3

class Database:
    def __init__(self, db_name="library.db"):
        self.conn = sqlite3.connect(db_name)
        self.conn.row_factory = sqlite3.Row  # ← 关键!让结果像字典一样访问
        self.init_tables()

    def init_tables(self):
        # 创建 users 表
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS users(
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                username TEXT UNIQUE,
                password TEXT,
                role TEXT
            )
        """)
        # 创建 books 表
        self.conn.execute("""
            CREATE TABLE IF NOT EXISTS books(
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                title TEXT NOT NULL,
                author TEXT,
                isbn TEXT,
                category TEXT
            )
        """)
        self.conn.commit()

    def execute(self, sql, params=()):
        cursor = self.conn.cursor()
        cursor.execute(sql, params)
        self.conn.commit()
        return cursor

重点说明

  • 使用 SQLite 内嵌数据库,无需额外安装服务。
  • row_factory = sqlite3.Row 让查询结果可以通过 row["username"] 方式访问,而不是 row[1],极大提升可读性。
  • execute 方法统一处理 SQL 执行 + 提交,避免忘记 commit。

四、用户控制器 ——user_controller.py

import hashlib
from dao.database import Database
from model.user import User
from model.role import Role

class UserController:
    def __init__(self):
        self.db = Database()
        self.ensure_admin()  # 确保 admin 用户存在

    def hash_password(self, password):
        return hashlib.sha256(password.encode()).hexdigest()

    def ensure_admin(self):
        cursor = self.db.execute("SELECT * FROM users WHERE username=?", ("admin",))
        if cursor.fetchone() is None:
            self.register("admin", "123456", Role.ADMIN)

    def register(self, username, password, role):
        if not username or not password:
            raise Exception("用户名或密码不能为空")
        self.db.execute("""
            INSERT INTO users(username, password, role)
            VALUES (?, ?, ?)
        """, (username, self.hash_password(password), role))

    def login(self, username, password):
        cursor = self.db.execute("SELECT * FROM users WHERE username=?", (username,))
        user = cursor.fetchone()
        if user and user["password"] == self.hash_password(password):
            return User(user["id"], user["username"], user["role"])
        return None

关键点解析

  • 密码安全:使用 hashlib.sha256 对密码哈希,绝不存明文密码
  • 自动创建管理员:第一次运行时自动创建 admin / 123456 账号,方便测试。
  • 登录验证:比对哈希后的密码,成功则返回 User 对象,失败返回 None
  • 异常处理:注册时空用户名/密码会抛出异常(后续 UI 会捕获并提示)。

注意:123456 是弱密码,实际项目应要求强密码或首次登录改密。

五、权限管理器 ——permission_manager.py

from model.role import Role
from model.permission import Permission

class PermissionManager:
    ROLE_PERMISSIONS = {
        Role.ADMIN: [
            Permission.ADD_BOOK,
            Permission.DELETE_BOOK,
            Permission.IMPORT_BOOK,
            Permission.EXPORT_BOOK
        ],
        Role.TEACHER: [Permission.ADD_BOOK],
        Role.STUDENT: []
    }

    @classmethod
    def has_permission(cls, role, permission):
        return permission in cls.ROLE_PERMISSIONS.get(role, [])

设计亮点

  • 权限配置集中在一个字典里,清晰直观。
  • 使用 @classmethod,无需实例化即可调用:PermissionManager.has_permission(...)
  • 学生没有任何权限,教师只能添加,管理员全有。

六、图书控制器 ——book_controller.py

from dao.database import Database
from controller.permission_manager import PermissionManager
from model.permission import Permission

class BookController:
    def __init__(self, user):
        self.db = Database()
        self.user = user

    def add_book(self, title, author, isbn, category):
        if not PermissionManager.has_permission(self.user.role, Permission.ADD_BOOK):
            raise Exception("没有权限")
        self.db.execute("""
            INSERT INTO books(title, author, isbn, category)
            VALUES (?, ?, ?, ?)
        """, (title, author, isbn, category))

    def delete_book(self, book_id):
        if not PermissionManager.has_permission(self.user.role, Permission.DELETE_BOOK):
            raise Exception("没有权限")
        self.db.execute("DELETE FROM books WHERE id=?", (book_id,))

    def list_books(self):
        cursor = self.db.execute("SELECT * FROM books")
        return cursor.fetchall()

权限控制集成

  • 每个操作前先检查权限,无权限则抛出异常。
  • 异常会被 UI 捕获并弹窗提示(见后文)。

七、用户界面(View)

1. 登录窗口 ——login_window.py

from PyQt5.QtWidgets import *
from controller.user_controller import UserController
from view.register_window import RegisterWindow

class LoginWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("登录")
        self.controller = UserController()
        # ... 布局代码 ...
        self.user = None

    def login(self):
        user = self.controller.login(self.edit_user.text(), self.edit_pass.text())
        if user:
            self.user = user
            self.accept()  # 关闭对话框并返回 True
        else:
            QMessageBox.warning(self, "错误", "登录失败")

    def open_register(self):
        RegisterWindow().exec_()  # 模态弹出注册窗口

要点

  • 继承 QDialog,适合登录/注册这类临时窗口。
  • accept() 表示“成功关闭”,main.py 中通过 if login.exec_(): 判断是否登录成功。
  • 密码输入框设置为密文:self.edit_pass.setEchoMode(QLineEdit.Password)

2. 注册窗口 ——register_window.py

class RegisterWindow(QDialog):
    def __init__(self):
        super().__init__()
        self.combo_role.addItems([Role.TEACHER, Role.STUDENT])  # 只能选教师或学生

    def register(self):
        self.controller.register(
            self.edit_user.text(),
            self.edit_pass.text(),
            self.combo_role.currentText()
        )
        QMessageBox.information(self, "成功", "注册成功")
        self.accept()

限制:普通用户不能注册为管理员,防止权限提升。

3. 不同角色主窗口

学生窗口 ——student_window.py

  • 只有 刷新按钮
  • 没有添加/删除按钮(UI 层就隐藏了)
  • 即使通过其他方式调用 add_book,也会因权限不足被 BookController 拦截

教师窗口 ——teacher_window.py

  • 添加、删除、刷新 按钮
  • 但删除时会触发权限检查 → 教师无 DELETE_BOOK 权限 → 抛出异常 → 弹窗“没有权限”

重要:这里存在一个 UI 与权限不一致 的问题!教师界面上显示了“删除”按钮,但点击会报错。更好的做法是:根据权限动态显示按钮

管理员窗口 ——admin_window.py

  • 只实现了“添加测试书”功能(硬编码)
  • 实际应像教师窗口那样弹出输入框(当前是简化版)

八、程序入口 ——main.py

import sys
from PyQt5.QtWidgets import QApplication
from view.login_window import LoginWindow
# ... 导入各角色窗口 ...

if __name__ == "__main__":
    app = QApplication(sys.argv)
    login = LoginWindow()
    if login.exec_():  # 如果登录成功
        user = login.user
        if user.role == Role.ADMIN:
            window = AdminWindow(user)
        elif user.role == Role.TEACHER:
            window = TeacherWindow(user)
        else:
            window = StudentWindow(user)
        window.show()
        sys.exit(app.exec_())

流程

  • 启动应用
  • 弹出登录窗口
  • 登录成功 → 根据角色打开对应主窗口
  • 进入事件循环

九、潜在问题与改进建议

1. 教师界面显示了“删除”按钮但无权限

原因:UI 未根据权限动态调整

修复建议

# 在 TeacherWindow.__init__ 中
if PermissionManager.has_permission(user.role, Permission.DELETE_BOOK):
    btn_layout.addWidget(self.btn_delete)

2. 管理员窗口功能简陋

当前 add_book 是硬编码的,应改为弹窗输入。

3. 密码强度弱

admin 默认密码 123456 不安全,应首次登录强制修改。

4. 优点总结

  • 分层清晰(Model / DAO / Controller / View)
  • 权限控制集中、可扩展
  • 使用 SQLite,零配置运行
  • 代码简洁,适合教学

十、如何运行

安装依赖:

pip install PyQt5

将所有 .py 文件放在同一目录

运行:

python main.py

首次运行会自动创建 library.dbadmin 账号

结语

这个小项目虽然简单,但涵盖了:

  • 面向对象编程(OOP)
  • MVC 架构思想
  • 数据库操作(SQLite)
  • GUI 开发(PyQt5)
  • 权限控制设计
  • 密码安全基础

非常适合 Python 初学者作为练手项目!你可以在此基础上:

  • 添加“借阅/归还”功能
  • 实现图书搜索
  • 支持 Excel 导入导出(利用已有 IMPORT_BOOK / EXPORT_BOOK 权限)

记住:好的代码 = 清晰的结构 + 明确的职责 + 安全的实践。

以上就是python结合QT实现简单的图书管理系统的详细内容,更多关于python图书管理系统的资料请关注脚本之家其它相关文章!

相关文章

  • Python实现12306火车票抢票系统

    Python实现12306火车票抢票系统

    这篇文章主要介绍了Python实现12306火车票抢票系统,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-07-07
  • Python学习之面向函数转面向对象详解

    Python学习之面向函数转面向对象详解

    本文将针对类进行一个综合练习,利用所学的面向对象编程、类的知识将我们之前做的面向函数编写的学生信息库重构为面向对象的方式,感兴趣的可以了解一下
    2022-03-03
  • Python numpy多维数组实现原理详解

    Python numpy多维数组实现原理详解

    这篇文章主要介绍了python numpy多维数组实现原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 使用Python编写一个简单的tic-tac-toe游戏的教程

    使用Python编写一个简单的tic-tac-toe游戏的教程

    这篇文章主要介绍了使用Python编写一个简单的tic-tac-toe游戏的教程,有利于Python初学者进行上手实践,需要的朋友可以参考下
    2015-04-04
  • python中pandas常用命令详解

    python中pandas常用命令详解

    pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的,这篇文章主要介绍了python中pandas常用命令,需要的朋友可以参考下
    2022-07-07
  • Python多进程机制实例详解

    Python多进程机制实例详解

    这篇文章主要介绍了Python多进程机制,以实例形式详细分析了Python多进程机制的原理与实现技巧,需要的朋友可以参考下
    2015-07-07
  • Python利用matplotlib实现动态可视化详解

    Python利用matplotlib实现动态可视化详解

    Python中的数据可视化是指原始数据的图形表示,以更好地可视化、理解和推理,Python提供了各种库,包含用于可视化数据的不同特性,下面我们就来看看如何利用matplotlib实现动态可视化吧
    2023-08-08
  • python读取ply文件实现方式

    python读取ply文件实现方式

    文章介绍了PLY文件格式,这是一种用于表示三维图形的文件格式,文章详细介绍了如何使用Python中的`plyfile`和`open3d`库来读取PLY文件,通过这两个库,可以方便地提取PLY文件中的每一个元素,文章还提供了使用这两个库读取PLY文件的示例代码
    2026-01-01
  • Python编程实现蚁群算法详解

    Python编程实现蚁群算法详解

    这篇文章主要介绍了Python编程实现蚁群算法详解,涉及蚂蚁算法的简介,主要原理及公式,以及Python中的实现代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • python中requests模拟登录的三种方式(携带cookie/session进行请求网站)

    python中requests模拟登录的三种方式(携带cookie/session进行请求网站)

    这篇文章主要介绍了python中requests模拟登录的三种方式(携带cookie/session进行请求网站),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11

最新评论