视图
python
复制代码
from PyQt5 import QtWidgets, QtCore
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setWindowTitle("图书管理系统")
MainWindow.resize(1000, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
MainWindow.setCentralWidget(self.centralwidget)
# 主垂直布局
self.main_layout = QtWidgets.QVBoxLayout(self.centralwidget)
# =======================
# 1. 查询区域
# =======================
self.group_search = QtWidgets.QGroupBox("查询条件")
self.search_layout = QtWidgets.QHBoxLayout()
self.label_title = QtWidgets.QLabel("书名:")
self.lineEdit_title = QtWidgets.QLineEdit()
self.label_author = QtWidgets.QLabel("作者:")
self.lineEdit_author = QtWidgets.QLineEdit()
self.label_isbn = QtWidgets.QLabel("ISBN:")
self.lineEdit_isbn = QtWidgets.QLineEdit()
self.label_category = QtWidgets.QLabel("分类:")
self.lineEdit_category = QtWidgets.QLineEdit()
self.label_sort = QtWidgets.QLabel("排序:")
self.combo_sort = QtWidgets.QComboBox()
self.combo_sort.addItems(["ID", "书名", "作者", "分类"])
self.search_layout.addWidget(self.label_title)
self.search_layout.addWidget(self.lineEdit_title)
self.search_layout.addWidget(self.label_author)
self.search_layout.addWidget(self.lineEdit_author)
self.search_layout.addWidget(self.label_isbn)
self.search_layout.addWidget(self.lineEdit_isbn)
self.search_layout.addWidget(self.label_category)
self.search_layout.addWidget(self.lineEdit_category)
self.search_layout.addWidget(self.label_sort)
self.search_layout.addWidget(self.combo_sort)
self.group_search.setLayout(self.search_layout)
self.main_layout.addWidget(self.group_search)
# =======================
# 2. 按钮区域
# =======================
self.button_layout = QtWidgets.QHBoxLayout()
self.btn_add = QtWidgets.QPushButton("添加图书")
self.btn_delete = QtWidgets.QPushButton("删除图书")
self.btn_search = QtWidgets.QPushButton("查询")
self.btn_refresh = QtWidgets.QPushButton("刷新")
self.button_layout.addWidget(self.btn_add)
self.button_layout.addWidget(self.btn_delete)
self.button_layout.addWidget(self.btn_search)
self.button_layout.addWidget(self.btn_refresh)
self.main_layout.addLayout(self.button_layout)
# =======================
# 3. 表格区域
# =======================
self.tableWidget = QtWidgets.QTableWidget()
self.tableWidget.setColumnCount(5)
self.tableWidget.setHorizontalHeaderLabels(
["ID", "书名", "作者", "ISBN", "分类"]
)
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.main_layout.addWidget(self.tableWidget)
# =======================
# 4. 分页区域
# =======================
self.page_layout = QtWidgets.QHBoxLayout()
self.btn_prev = QtWidgets.QPushButton("上一页")
self.btn_next = QtWidgets.QPushButton("下一页")
self.label_page = QtWidgets.QLabel("第 1 页")
self.page_layout.addStretch()
self.page_layout.addWidget(self.btn_prev)
self.page_layout.addWidget(self.label_page)
self.page_layout.addWidget(self.btn_next)
self.page_layout.addStretch()
self.main_layout.addLayout(self.page_layout)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
数据层
python
复制代码
from database import Database
class BookManager:
def __init__(self):
self.db = Database()
def add_book(self, title, author, isbn, category):
sql = """
INSERT INTO books (title, author, isbn, category)
VALUES (?, ?, ?, ?)
"""
self.db.execute(sql, (title, author, isbn, category))
def delete_book(self, book_id):
sql = "DELETE FROM books WHERE id=?"
self.db.execute(sql, (book_id,))
def search_books(self, title="", author="", isbn="", category="",
order_by="id", page=1, page_size=10):
offset = (page - 1) * page_size
allowed_sort = ["id", "title", "author", "category"]
if order_by not in allowed_sort:
order_by = "id"
sql = f"""
SELECT * FROM books
WHERE title LIKE ?
AND author LIKE ?
AND isbn LIKE ?
AND category LIKE ?
ORDER BY {order_by}
LIMIT ? OFFSET ?
"""
cursor = self.db.execute(sql, (
f"%{title}%",
f"%{author}%",
f"%{isbn}%",
f"%{category}%",
page_size,
offset
))
return cursor.fetchall()
def count_books(self, title="", author="", isbn="", category=""):
sql = """
SELECT COUNT(*) FROM books
WHERE title LIKE ?
AND author LIKE ?
AND isbn LIKE ?
AND category LIKE ?
"""
cursor = self.db.execute(sql, (
f"%{title}%",
f"%{author}%",
f"%{isbn}%",
f"%{category}%"
))
return cursor.fetchone()[0]
python
复制代码
import sqlite3
class Database:
def __init__(self, db_name="books.db"):
self.conn = sqlite3.connect(db_name)
self.conn.row_factory = sqlite3.Row # 查询结果可用字典访问
self.create_table()
def create_table(self):
sql = """
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
author TEXT,
isbn TEXT UNIQUE,
category TEXT
)
"""
self.conn.execute(sql)
self.conn.commit()
def execute(self, sql, params=()):
cursor = self.conn.cursor()
cursor.execute(sql, params)
self.conn.commit()
return cursor
控制逻辑层
python
复制代码
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QTableWidgetItem
from book_management_ui import Ui_MainWindow
from book_manager import BookManager
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.manager = BookManager()
self.current_page = 1
self.page_size = 10
self.init_signal()
self.query_books()
# 绑定信号
def init_signal(self):
self.ui.btn_add.clicked.connect(self.add_book)
self.ui.btn_delete.clicked.connect(self.delete_book)
self.ui.btn_search.clicked.connect(self.search_reset)
self.ui.btn_refresh.clicked.connect(self.refresh)
# 分页按钮
self.ui.btn_prev.clicked.connect(self.prev_page)
self.ui.btn_next.clicked.connect(self.next_page)
# 排序字段
def get_order_by(self):
mapping = {
"ID": "id",
"书名": "title",
"作者": "author",
"分类": "category"
}
return mapping.get(self.ui.combo_sort.currentText(), "id")
# 查询(分页核心函数)
def query_books(self):
title = self.ui.lineEdit_title.text().strip()
author = self.ui.lineEdit_author.text().strip()
isbn = self.ui.lineEdit_isbn.text().strip()
category = self.ui.lineEdit_category.text().strip()
order_by = self.get_order_by()
books = self.manager.search_books(
title, author, isbn, category,
order_by,
self.current_page,
self.page_size
)
total = self.manager.count_books(title, author, isbn, category)
total_pages = max(1, (total + self.page_size - 1) // self.page_size)
self.ui.label_page.setText(
f"第 {self.current_page} 页 / 共 {total_pages} 页"
)
self.load_table(books)
# 搜索重置页码
def search_reset(self):
self.current_page = 1
self.query_books()
# 刷新
def refresh(self):
self.current_page = 1
self.query_books()
# 上一页
def prev_page(self):
if self.current_page > 1:
self.current_page -= 1
self.query_books()
# 下一页
def next_page(self):
self.current_page += 1
self.query_books()
# 添加
def add_book(self):
title = self.ui.lineEdit_title.text().strip()
author = self.ui.lineEdit_author.text().strip()
isbn = self.ui.lineEdit_isbn.text().strip()
category = self.ui.lineEdit_category.text().strip()
if not title:
QMessageBox.warning(self, "错误", "书名不能为空")
return
try:
self.manager.add_book(title, author, isbn, category)
QMessageBox.information(self, "成功", "添加成功")
self.search_reset()
except Exception as e:
QMessageBox.warning(self, "错误", str(e))
# 删除
def delete_book(self):
row = self.ui.tableWidget.currentRow()
if row == -1:
QMessageBox.warning(self, "错误", "请选择一行")
return
book_id = int(self.ui.tableWidget.item(row, 0).text())
self.manager.delete_book(book_id)
QMessageBox.information(self, "成功", "删除成功")
self.search_reset()
# 加载表格
def load_table(self, books):
self.ui.tableWidget.setRowCount(0)
for row, book in enumerate(books):
self.ui.tableWidget.insertRow(row)
self.ui.tableWidget.setItem(row, 0, QTableWidgetItem(str(book["id"])))
self.ui.tableWidget.setItem(row, 1, QTableWidgetItem(book["title"]))
self.ui.tableWidget.setItem(row, 2, QTableWidgetItem(book["author"]))
self.ui.tableWidget.setItem(row, 3, QTableWidgetItem(book["isbn"]))
self.ui.tableWidget.setItem(row, 4, QTableWidgetItem(book["category"]))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())