PyQt5 + MySql = 图书管理系统,期末课程设计,直接上报告,里面有PYQT5常见问题解决方案。

做完期末设计传上来看看,要源码的留言,有人的话,我开源在github中

三、实验步骤(及实验数据)

1.数据库的设计

       使用Navicat配置好基础的数据库和表,填入一些基本信息

       在项目的一个文件模块中连接好对应数据库,写好对应的方法函数,便于主程序调用。

2.图书管理系统的设计与实现

       首先确定好项目的路径以及放好资源文件,在Qt Designer里面把基础界面完成,主要为两个页面大类,一是登录和注册,二就是管理系统的主要展示和功能界面。这里因为我在需要更换主题,测试后发现直接写在designer里会把项目中写的css样式覆盖掉,所以我先把这里的样式移到代码中,这里一些组件样式显示为透明

       明确好目录结构,使用到的图片资源会自动存为.qrc文件,在python中使用需要用外部工具pyrcc进行转换,否则无法在运行界面里显示图片。

      

       接下来开始代码编写,首先导入所需库,这里基本是需要用到在导入的,避免过多导入不需要的库。做好一些全局的配置,像是这里我有做的,图标同步,直接使用ui文件,做高分辨率屏幕适配,以及引起的高清图像显示配置。

       建立登录界面的类,继承自QMainWindow,以及从对应ui文件导出的login,做好界面的初始化,因为这里的信号与槽的数量较少,这里是直接写在构造方法下面的。

       在这个界面类中,最值得注意的便是这里注册信号对应的函数了,从这里正式开始接触数据库与python的交互,还是显示提交式的。这里只重点提及数据库操作。这是固定流程,1.使用先前定义的模块中的函数,get_conn()来连接上数据库及表,拿到信息;2.继续获取consur一会用来操作数据库;3.制作sql语句,重点便是在这里“%s”,这里%s便是用来代替你要传入的字符;4.使用cur.execute()执行sql语句,注意这里的顺序是从左到右填入%s的位置;5.像是对于这种修改数据库信息的都需要执行conn.commit()显示提交;6.关闭资源。

       简单看一下登录信号,这里的查询数据库操作比改数据库信息的要少一步,但是也多了个cur.fetchone()来接收数据查询的结果,数据存在先创建一个属性用来存放主界面的类,关闭当前界面,通过此前的属性来打开新类窗口。

       主界面类,也是注意初始化,因为这里信号与槽的数量比较多,所以在构造方法中放了个接口写到后面去了,避免太过混乱。因为这里的代码比较多,不好一一细讲。其实大致步骤和前面的相同,主要就是信号与槽,按钮与方法的关系,做好用到的控件的方法的了解,就可以很好的使用。

登录界面:

注册界面:

        不展示了我的名字在这个界面上,懒得改

实现效果:

       值得注意的是,为了好看我把所有窗口的windows自带边框隐藏掉了,关闭和缩小操作我都自己加的图标。

主界面:

添加书籍:

编辑书籍:

展示读者信息:

暗色主题:

配置:

主要代码:

        

from PyQt5.QtWidgets import *
from PyQt5.uic import loadUiType
import sys
from PyQt5 import QtCore, QtGui
from dbutil import get_conn, close_conn
import ctypes

# 保证图标同步
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")

# UI--Logic分离  不会有提示,避免进行py转换
main, _ = loadUiType('index.ui')
login, _ = loadUiType('login.ui')

# 让实际同预览效果一致,添加对高分辨率屏幕的支持
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
# PyQt5高清屏幕自适应设置,以及让添加的高清图标显示清晰,不然designer导入的图标在程序加载时会特别模糊
QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)


class LoginAPP(QMainWindow, login):  # 建立Login界面类,继承对应的父类

    # 定义构造方法
    def __init__(self):
        # 初始化
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.qbt.clicked.connect(self.handel_login)
        # self.setWindowFlags(Qt.Qt.CustomizeWindowHint)  # 去掉标题栏的代码
        # self.setWindowFlags(Qt.Qt.FramelessWindowHint)
        # self.setWindowFlags(Qt.Qt.CustomizeWindowHint)
        # 登录按扭连接的事件(连接到一个方法)
        self.loginb.clicked.connect(self.login_btn)
        self.zc.clicked.connect(self.zc_btn)
        self.zct.clicked.connect(self.zct_btn)
        self.setWindowIcon(QtGui.QIcon('icons/tushuguanli.png'))

        """隐藏系统边框;隐藏系统自带窗口背景"""
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

    def handel_login(self):
        self.close()

    def zc_btn(self):
        self.login_reg.setCurrentIndex(2)

    def zct_btn(self):
        zh = self.zh.text()
        mm = self.mm.text()
        qmm = self.qmm.text()
        if mm == qmm:
            #  数据库操作流程
            # 1、获取连接
            conn = get_conn()
            # 2、获取cursor
            cur = conn.cursor()
            # 3.制作sql语句
            sql = "INSERT into users(user_name,user_pwd) values(%s, %s);"
            # 4.执行sql语句
            cur.execute(sql, (zh, mm))
            # 5、insert、update、delete必须显示提交
            conn.commit()
            # 6、关闭资源
            close_conn(conn, cur)
            self.error_message.setText('注册成功')
            self.login_reg.setCurrentIndex(0)
        else:
            self.zcm.setText('两次密码不一致')
        self.zh.setText('')
        self.mm.setText('')
        self.qmm.setText('')

    def login_btn(self):
        # 连接数据库, 这里的get_conn是自己定义的
        conn = get_conn()
        cur = conn.cursor()
        # 创建sql语句获得数据库中的具体内容
        # 注意%s代指后面执行语句的括号参数
        sql = "select * from users where user_name=%s and user_pwd=%s"
        print(self.password.text())
        print(self.username.text())

        # 拿到输入内容,这里是通过self.名为username的输入框
        user_name = self.username.text()
        pwd = self.password.text()
        # 运行sql语句进行数据验证
        cur.execute(sql, (user_name, pwd))
        data = cur.fetchone()
        print(data)

        if data:
            self.mapp = MainAPP()  # 创建属性赋类
            self.close()  # 关闭此前类窗口
            self.mapp.show()  # 打开新类窗口
        else:
            self.error_message.setText('登录失败')


class MainAPP(QMainWindow, main):

    # 定义构造方法
    def __init__(self):
        # 初始化
        QMainWindow.__init__(self)
        """隐藏系统边框;隐藏系统自带窗口背景"""
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.setupUi(self)
        self.btn()
        self.show_books()
        self.show_readers()
        self.show_bro()
        self.show_peiz()
        self.show_peiz2()
        self.chk.setText('暗主题')
        self.theme = 1
        self.setWindowIcon(QtGui.QIcon('icons/tushuguanli.png'))
        self.show_author_combobox()
        self.show_e_combobox()
        self.dark_gray_theme()

    # 按钮信号与槽
    def btn(self):
        self.f1.clicked.connect(self.f1weg)  # 主界面1
        self.f2.clicked.connect(self.f2weg)  # 主界面2
        self.f3.clicked.connect(self.f3weg)  # 主界面3
        self.add_bt.clicked.connect(self.add_th)  # 添加书
        self.serchbt.clicked.connect(self.serch_btn)    # 搜索书
        self.qbt.clicked.connect(self.handel_gb)    # 关闭
        self.qbt_2.clicked.connect(self.handel_sx)  # 缩小窗口
        self.xg.clicked.connect(self.xg_btn)    # 修改书
        self.chk.clicked.connect(self.dark_gray_theme)  # 暗主题
        self.peiz.clicked.connect(self.f4weg)       # 配置界面(主界面4)
        self.aat.clicked.connect(self.add_a)        # 添加作者
        self.aac.clicked.connect(self.add_c)        # 添加出版社
        self.xg_2.clicked.connect(self.delete_book)  # 删除书籍

    def show_author_combobox(self):
        conn = get_conn()
        cur = conn.cursor()
        sql = "select author from pei_zhi"
        cur.execute(sql)
        data = cur.fetchall()

        if data:
            self.add_aut.clear()
            self.add_aut_3.clear()
            for author in data:
                self.add_aut.addItem(author[0])
                self.add_aut_3.addItem(author[0])

    def show_e_combobox(self):
        conn = get_conn()
        cur = conn.cursor()
        sql = "select 出版社 from pei_zhi2"
        cur.execute(sql)
        data = cur.fetchall()

        if data:
            self.add_aut_2.clear()
            self.add_aut_4.clear()
            for author in data:
                self.add_aut_2.addItem(author[0])
                self.add_aut_4.addItem(author[0])

    def show_peiz(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT author FROM pei_zhi;"
        # 4.执行sql语句
        cur.execute(sql)
        # 5.获取执行后的数据
        data = cur.fetchall()

        # 设计书籍表页面类的开始行,插入行
        self.pei_co.setRowCount(0)
        self.pei_co.insertRow(0)
        print(data)  # 数据形式为列表套元组,元组内为一条记录(一行)

        """取行下标,取行数据"""
        for row, form in enumerate(data):
            """取列下标,取列数据"""
            for column, item in enumerate(form):
                """设置表中值"""
                self.pei_co.setItem(row, column, QTableWidgetItem(str(item)))
                # column += 1

            """行位置设置&数据插入"""
            row_postion = self.pei_co.rowCount()
            self.pei_co.insertRow(row_postion)

    def show_peiz2(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT 出版社 FROM pei_zhi2;"
        # 4.执行sql语句
        cur.execute(sql)
        # 5.获取执行后的数据
        data = cur.fetchall()

        # 设计书籍表页面类的开始行,插入行
        self.pei_co2.setRowCount(0)
        self.pei_co2.insertRow(0)
        print(data)  # 数据形式为列表套元组,元组内为一条记录(一行)

        """取行下标,取行数据"""
        for row, form in enumerate(data):
            """取列下标,取列数据"""
            for column, item in enumerate(form):
                """设置表中值"""
                self.pei_co2.setItem(row, column, QTableWidgetItem(str(item)))
                # column += 1

            """行位置设置&数据插入"""
            row_postion = self.pei_co2.rowCount()
            self.pei_co2.insertRow(row_postion)

    def add_a(self):
        co = self.l1.text()
        if co:
            #  数据库操作流程
            # 1、获取连接
            conn = get_conn()
            # 2、获取cursor
            cur = conn.cursor()
            # 3.制作sql语句
            sql = "INSERT into pei_zhi(author) values(%s);"
            # 4.执行sql语句
            cur.execute(sql, (co,))
            # 5、insert、update、delete必须显示提交
            conn.commit()
            # 6、关闭资源
            close_conn(conn, cur)

            self.l1.setText('')
            # 刷新显示
            self.show_peiz()
            self.la3.setText('添加成功')
            self.show_author_combobox()
            self.show_e_combobox()
        else:
            self.la3.setText('添加失败')

    def add_c(self):
        co = self.l2.text()
        if co:
            #  数据库操作流程
            # 1、获取连接
            conn = get_conn()
            # 2、获取cursor
            cur = conn.cursor()
            # 3.制作sql语句
            sql = "INSERT into pei_zhi2(出版社) values(%s);"
            # 4.执行sql语句
            cur.execute(sql, (co,))
            # 5、insert、update、delete必须显示提交
            conn.commit()
            # 6、关闭资源
            close_conn(conn, cur)

            self.l2.setText('')
            # 刷新显示
            self.show_peiz2()
            self.la3.setText('添加成功')
            self.show_author_combobox()
            self.show_e_combobox()
        else:
            self.la3.setText('添加失败')

    def xg_btn(self):
        book_name = self.xgbn.text()
        book_code = self.xgbc.text()
        book_author = self.add_aut_3.currentText()
        book_cb = self.add_aut_4.currentText()
        book_price = self.xgbp.text()
        if book_cb and book_author and book_price and book_name and book_code:
            print(book_cb, book_price, book_name)
            #  数据库操作流程
            # 1、获取连接
            conn = get_conn()
            # 2、获取cursor
            cur = conn.cursor()
            # 3.制作sql语句
            sql = "update books set ISBN=%s, book_name=%s, book_autor=%s, 出版社=%s, book_price=%s where book_name=%s;"
            # 4.执行sql语句
            try:
                cur.execute(sql, (book_code, book_name, book_author, book_cb, book_price, book_name))
                # 5、insert、update、delete必须显示提交
                conn.commit()

            except:
                pass
            # 6、关闭资源
            close_conn(conn, cur)
            self.show_books()
        else:
            self.ts.setText('请确认数据后再提交')

    def serch_btn(self):
        book_name = self.serch_name.text()
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT ISBN, book_name, book_autor, 出版社, book_price FROM books where book_name=%s"
        # 4.执行sql语句
        try:
            cur.execute(sql, (book_name,))
            # 5.获取执行后的数据
            data = cur.fetchall()
            self.xgbn.setText(data[0][1])
            self.xgbc.setText(data[0][0])
            self.add_aut_3.setCurrentText(data[0][2])
            self.add_aut_4.setCurrentText(data[0][3])
            self.xgbp.setText(data[0][4])
            self.ts.setText('搜索成功')
        except:
            self.ts.setText('搜索失败')

    def f1weg(self):
        self.label_4.setText('')
        self.sfwegs.setCurrentIndex(0)
        if not self.theme:
            style = open("themes/ui.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
        else:
            style = open("themes/qdark.css", 'r')
            style = style.read()
            self.setStyleSheet(style)

    def f2weg(self):
        self.label_4.setText('')
        self.sfwegs.setCurrentIndex(1)
        if not self.theme:
            style = open("themes/f1.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
        else:
            style = open("themes/fd1.css", 'r')
            style = style.read()
            self.setStyleSheet(style)

    def f3weg(self):
        self.label_4.setText('')
        self.sfwegs.setCurrentIndex(2)
        if not self.theme:
            style = open("themes/f2.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
        else:
            style = open("themes/fd2.css", 'r')
            style = style.read()
            self.setStyleSheet(style)

    def f4weg(self):
        self.label_4.setText('')
        self.sfwegs.setCurrentIndex(3)
        if not self.theme:
            style = open("themes/f3.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
        else:
            style = open("themes/fd3.css", 'r')
            style = style.read()
            self.setStyleSheet(style)

    def handel_sx(self):
        self.showMinimized()

    def handel_gb(self):
        self.close()

    # 删除书籍
    def delete_book(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        sql = "delete from books where book_name = %s"
        book_name = self.xgbn.text()

        warning = QMessageBox.warning(self, '删除图书', '你确定要删除',
                                      QMessageBox.Yes | QMessageBox.No)
        if warning == QMessageBox.Yes:
            cur.execute(sql, (book_name,))
            conn.commit()
            close_conn(conn, cur)
            self.show_books()
            self.statusBar().showMessage('图书成功删除')

    def dark_gray_theme(self):  # 暗主题
        if self.theme:
            style = open("themes/ui.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
            self.theme = 0
        else:
            style = open("themes/qdark.css", 'r')
            style = style.read()
            self.setStyleSheet(style)
            self.theme = 1

    def add_th(self):
        b_name = self.add_bname.text()
        b_code = self.add_bcode.text()
        b_au = self.add_aut.currentText()
        b_cb = self.add_aut_2.currentText()
        b_price = self.add_bprice.text()
        print(b_name, b_code, b_au, b_cb, type(b_price))
        if b_code and b_name and b_price:
            #  数据库操作流程
            # 1、获取连接
            conn = get_conn()
            # 2、获取cursor
            cur = conn.cursor()
            # 3.制作sql语句
            sql = "INSERT into books(ISBN, book_name, book_autor, 出版社, book_price) values(%s, %s, %s, %s, %s);"
            # 4.执行sql语句
            cur.execute(sql, (b_code, b_name, b_au, b_cb, b_price))
            # 5、insert、update、delete必须显示提交
            conn.commit()
            # 6、关闭资源
            close_conn(conn, cur)

            self.add_bname.setText('')
            self.add_bcode.setText('')
            self.add_aut.setCurrentIndex(0)
            self.add_aut_2.setCurrentIndex(0)
            self.add_bprice.setText('')
            # 刷新显示
            self.show_books()
            self.label_4.setText('添加成功')
            # self.tabWidget_3.setCurrentIndex(0)
        else:
            self.label_4.setText('请检查数据!')

    # 获取所有图书

    def show_books(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT ISBN, book_name, book_autor, 出版社, book_price FROM books"
        # 4.执行sql语句
        cur.execute(sql)
        # 5.获取执行后的数据
        data = cur.fetchall()

        # 设计书籍表页面类的开始行,插入行
        self.book_table.setRowCount(0)
        self.book_table.insertRow(0)
        print(data)  # 数据形式为列表套元组,元组内为一条记录(一行)

        """取行下标,取行数据"""
        for row, form in enumerate(data):
            """取列下标,取列数据"""
            for column, item in enumerate(form):
                """设置表中值"""
                self.book_table.setItem(row, column, QTableWidgetItem(str(item)))
                # column += 1

            """行位置设置&数据插入"""
            row_postion = self.book_table.rowCount()
            self.book_table.insertRow(row_postion)

    def show_readers(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT r_id, reader_name, reader_sex, 电话,reader_birthday, reader_borrowtotal from reader;"
        # 4.执行sql语句
        cur.execute(sql)
        # 5.获取执行后的数据
        data = cur.fetchall()

        # 设计书籍表页面类的开始行,插入行
        self.reader_table.setRowCount(0)
        self.reader_table.insertRow(0)
        print(data)  # 数据形式为列表套元组,元组内为一条记录(一行)

        """取行下标,取行数据"""
        for row, form in enumerate(data):
            """取列下标,取列数据"""
            for column, item in enumerate(form):
                """设置表中值"""

                self.reader_table.setItem(row, column, QTableWidgetItem(str(item)))
                # column += 1

            """行位置设置&数据插入"""
            row_postion = self.reader_table.rowCount()
            self.reader_table.insertRow(row_postion)

    def show_bro(self):
        #  数据库操作流程
        # 1、获取连接
        conn = get_conn()
        # 2、获取cursor
        cur = conn.cursor()
        # 3.制作sql语句
        sql = "SELECT reader_id, ISBN, name, book_name, borrow_date  FROM borrow_record"
        # 4.执行sql语句
        cur.execute(sql)
        # 5.获取执行后的数据
        data = cur.fetchall()

        # 设计书籍表页面类的开始行,插入行
        self.bro_table.setRowCount(0)
        self.bro_table.insertRow(0)
        print(data)  # 数据形式为列表套元组,元组内为一条记录(一行)

        """取行下标,取行数据"""
        for row, form in enumerate(data):
            """取列下标,取列数据"""
            for column, item in enumerate(form):
                """设置表中值"""

                self.bro_table.setItem(row, column, QTableWidgetItem(str(item)))
                # column += 1

            """行位置设置&数据插入"""
            row_postion = self.bro_table.rowCount()
            self.bro_table.insertRow(row_postion)


def main():
    """启动"""
    app = QApplication(sys.argv)
    window = LoginAPP()
    window.show()
    app.exec_()  # 持续事件


if __name__ == '__main__':
    main()

四、实验思考与总结

    本次实验项目主要是通过Python搭配PyQt5进行数据库的实际操作项目开发。在整个项目的设计流程中我也逐渐熟悉了数据库的操作,再次加深了对SQL语言使用的印象。

       本次项目的完成,也让我学习到了很多新的知识和操作,使用python连接本地MYSQL数据库;PyQt5的代码设计,信号与槽,按钮与方法的连接交互;使用Qt Designer设计前端界面。因为这里的样式也用到了CSS,也加强了我前端样式的设计能力。

       当然在项目的推进过程中,也遇到了不少的问题。像是图片资源不显示,这是因为没有时刻进行设计和代码的同步转换;特别还有,在Qt Designer设计时一定要从右键点击来更改对象名称,要不然就别改,直接从对象浏览器那里改有时不会生效;此外一定要搞清楚各个文件的关系,像是ui文件和Python代码的联系,各种资源文件的使用,外部工具的使用等等;对于Qt代码各种组件的使用,不用专门系统的学习,用啥搜啥,理解到了就可以很好的使用;还有对代码中各个类界面的初始化,实例化,界面联系也要理解清楚。

       总的来说,本次项目的完成,让我收获颇丰。学习到了各种新的知识,新的操作,对数据库的理解和操作也进一步加深了。相信对我为了进一步的学习和工作带来不小的益处。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
作为AI语言模型,我可以为您提供一些关于PyQt5与MySQL结合开发工厂物资管理系统的一些建议和思路。 1. 安装PyQt5和MySQL驱动程序 首先,您需要安装PyQt5和MySQL驱动程序。PyQt5是一个Python库,它提供了一些用于创建GUI应用程序的类和方法。MySQL是一个流行的关系数据库管理系统,用于存储和管理数据。 2. 设计应用程序界面 在设计应用程序界面时,您可以使用PyQt5的Designer工具创建用户界面。Designer是PyQt5的可视化设计器,它允许您拖放控件并设置属性。您可以使用Designer创建表单、按钮、文本框、下拉列表等控件。 3. 连接MySQL数据库 在PyQt5中,您可以使用QSqlDatabase类来连接MySQL数据库。您需要在应用程序中设置数据库连接参数,如数据库名称、用户名、密码、主机名和端口号等。一旦连接成功,您可以使用QSqlQuery类执行SQL语句并获取结果。 4. 实现应用程序逻辑 在实现应用程序逻辑时,您可以使用PyQt5的信号和槽机制来处理用户输入和事件。您可以为按钮、文本框和其他控件定义槽函数,以响应用户的操作。您还可以使用QTableWidget类来显示和编辑数据。 5. 测试和调试应用程序 在测试和调试应用程序时,您可以使用PyQt5的调试工具来诊断问题。您可以使用QMessageBox类显示调试消息,使用QStatusBar类显示状态消息,使用QApplication类处理应用程序级别的事件。 总结 以上是我为您提供的一些关于PyQt5与MySQL结合开发工厂物资管理系统的建议和思路。当然,具体实现细节还需要您根据具体需求进行进一步的开发和优化。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值