合同管理系统包含以下主要功能:
数据库管理:
使用SQLite数据库存储合同信息
自动创建数据库和表结构
支持基本的CRUD操作
主要功能:
新增合同
编辑现有合同
删除合同
合同搜索功能
合同列表展示
界面特点:
使用表格展示合同列表
弹出式对话框进行合同编辑
直观的搜索栏
状态筛选功能
数据验证和错误处理
技术细节:
使用PyQt6的Model-View架构
自定义对话框组件
SQL查询参数化防止注入
日期选择控件
使用Python和PyQt6开发的合同管理系统
import sys
import sqlite3
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem,
QDateEdit, QComboBox, QMessageBox, QDialog, QFormLayout
)
from PyQt6.QtCore import Qt, QDate
class ContractDialog(QDialog):
def __init__(self, parent=None, contract=None):
super().__init__(parent)
self.setWindowTitle("合同详情")
self.setFixedSize(400, 300)
layout = QFormLayout()
self.contract_name = QLineEdit()
self.client = QLineEdit()
self.amount = QLineEdit()
self.start_date = QDateEdit()
self.end_date = QDateEdit()
self.status = QComboBox()
self.status.addItems(["有效", "过期", "终止", "完成"])
layout.addRow("合同名称:", self.contract_name)
layout.addRow("客户名称:", self.client)
layout.addRow("合同金额:", self.amount)
layout.addRow("开始日期:", self.start_date)
layout.addRow("结束日期:", self.end_date)
layout.addRow("合同状态:", self.status)
self.buttons = QPushButton("保存")
self.buttons.clicked.connect(self.accept)
layout.addRow(self.buttons)
self.setLayout(layout)
if contract:
self.fill_form(contract)
def fill_form(self, contract):
self.contract_name.setText(contract[1])
self.client.setText(contract[2])
self.amount.setText(str(contract[3]))
self.start_date.setDate(QDate.fromString(contract[4], "yyyy-MM-dd"))
self.end_date.setDate(QDate.fromString(contract[5], "yyyy-MM-dd"))
self.status.setCurrentText(contract[6])
class ContractManager(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("合同管理系统")
self.setGeometry(100, 100, 800, 600)
self.db_connect()
self.init_ui()
self.load_contracts()
def db_connect(self):
self.conn = sqlite3.connect("contracts.db")
self.cursor = self.conn.cursor()
self.cursor.execute("""
CREATE TABLE IF NOT EXISTS contracts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
client TEXT NOT NULL,
amount REAL,
start_date DATE,
end_date DATE,
status TEXT
)
""")
self.conn.commit()
def init_ui(self):
main_widget = QWidget()
main_layout = QVBoxLayout()
# 搜索栏
search_layout = QHBoxLayout()
self.search_input = QLineEdit()
self.search_input.setPlaceholderText("搜索合同...")
self.search_input.textChanged.connect(self.search_contracts)
search_layout.addWidget(self.search_input)
# 操作按钮
btn_layout = QHBoxLayout()
self.add_btn = QPushButton("新增合同")
self.add_btn.clicked.connect(self.add_contract)
self.edit_btn = QPushButton("编辑合同")
self.edit_btn.clicked.connect(self.edit_contract)
self.delete_btn = QPushButton("删除合同")
self.delete_btn.clicked.connect(self.delete_contract)
btn_layout.addWidget(self.add_btn)
btn_layout.addWidget(self.edit_btn)
btn_layout.addWidget(self.delete_btn)
# 表格
self.table = QTableWidget()
self.table.setColumnCount(6)
self.table.setHorizontalHeaderLabels(
["ID", "合同名称", "客户", "金额", "开始日期", "结束日期", "状态"]
)
self.table.setColumnWidth(1, 200)
self.table.setColumnWidth(2, 150)
# 组合布局
main_layout.addLayout(search_layout)
main_layout.addLayout(btn_layout)
main_layout.addWidget(self.table)
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
def load_contracts(self, search_text=""):
query = """
SELECT id, name, client, amount, start_date, end_date, status
FROM contracts
WHERE name LIKE ? OR client LIKE ?
"""
self.cursor.execute(query, (f"%{search_text}%", f"%{search_text}%"))
contracts = self.cursor.fetchall()
self.table.setRowCount(len(contracts))
for row, contract in enumerate(contracts):
for col, data in enumerate(contract):
item = QTableWidgetItem(str(data))
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsEditable)
self.table.setItem(row, col, item)
def get_selected_id(self):
selected = self.table.selectedItems()
return int(selected[0].text()) if selected else None
def add_contract(self):
dialog = ContractDialog(self)
if dialog.exec():
self.cursor.execute("""
INSERT INTO contracts
(name, client, amount, start_date, end_date, status)
VALUES (?, ?, ?, ?, ?, ?)
""", (
dialog.contract_name.text(),
dialog.client.text(),
float(dialog.amount.text()),
dialog.start_date.date().toString("yyyy-MM-dd"),
dialog.end_date.date().toString("yyyy-MM-dd"),
dialog.status.currentText()
))
self.conn.commit()
self.load_contracts()
def edit_contract(self):
contract_id = self.get_selected_id()
if not contract_id:
QMessageBox.warning(self, "警告", "请先选择一个合同")
return
self.cursor.execute("SELECT * FROM contracts WHERE id=?", (contract_id,))
contract = self.cursor.fetchone()
dialog = ContractDialog(self, contract)
if dialog.exec():
self.cursor.execute("""
UPDATE contracts SET
name=?, client=?, amount=?, start_date=?, end_date=?, status=?
WHERE id=?
""", (
dialog.contract_name.text(),
dialog.client.text(),
float(dialog.amount.text()),
dialog.start_date.date().toString("yyyy-MM-dd"),
dialog.end_date.date().toString("yyyy-MM-dd"),
dialog.status.currentText(),
contract_id
))
self.conn.commit()
self.load_contracts()
def delete_contract(self):
contract_id = self.get_selected_id()
if not contract_id:
QMessageBox.warning(self, "警告", "请先选择一个合同")
return
confirm = QMessageBox.question(
self, "确认删除", "确定要删除这个合同吗?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
if confirm == QMessageBox.StandardButton.Yes:
self.cursor.execute("DELETE FROM contracts WHERE id=?", (contract_id,))
self.conn.commit()
self.load_contracts()
def search_contracts(self):
search_text = self.search_input.text()
self.load_contracts(search_text)
def closeEvent(self, event):
self.conn.close()
event.accept()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ContractManager()
window.show()
sys.exit(app.exec())
版本二,新增首页设置密码【默认密码:admin123】
增强版的合同管理系统具有以下特点:


密码保护:添加了登录验证功能,只有输入正确密码才能进入系统
密码管理:支持修改密码,密码采用 SHA-256 哈希存储
界面优化:
添加了菜单栏,包含文件、设置和视图菜单
表格根据合同状态显示不同颜色,便于快速识别
增加了列显示 / 隐藏功能
改进了按钮和输入框的样式
功能增强:
添加了高级搜索功能,可以按状态和日期范围筛选
合同详情增加了备注字段
表格支持按日期排序
状态栏显示当前加载的合同数量
初始密码为 admin123,登录后可以通过 "设置 -> 修改密码" 来更改。
科技之星开源提供
import sys
import sqlite3
import hashlib
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem,
QDateEdit, QComboBox, QMessageBox, QDialog, QFormLayout, QDialogButtonBox,
QFrame, QSpinBox, QGroupBox, QTabWidget, QCheckBox, QGridLayout, QMenu
)
from PyQt6.QtCore import Qt, QDate, pyqtSignal
from PyQt6.QtGui import QAction, QIcon, QPalette, QColor, QFont
class PasswordManager:
"""密码管理类,负责密码的存储、验证和修改"""
def __init__(self, db_path="contracts.db"):
self.db_path = db_path
self._initialize_db()
def _initialize_db(self):
"""初始化密码存储表"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY,
key TEXT UNIQUE,
value TEXT
)
""")
# 检查是否已有密码
cursor.execute("SELECT value FROM settings WHERE key='password_hash'")
result = cursor.fetchone()
if not result:
# 设置默认密码
self.set_password("admin123")
conn.close()
def set_password(self, new_password):
"""设置新密码"""
password_hash = hashlib.sha256(new_password.encode()).hexdigest()
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)",
("password_hash", password_hash)
)
conn.commit()
conn.close()
def verify_password(self, password):
"""验证密码"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("SELECT value FROM settings WHERE key='password_hash'")
result = cursor.fetchone()
conn.close()
if not result:
return False
stored_hash = result[0]
input_hash = hashlib.sha256(password.encode()).hexdigest()
return input_hash == stored_hash
class LoginDialog(QDialog):
"""登录对话框"""
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("系统登录")
self.setFixedSize(300, 180)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint)
self.password_manager = PasswordManager()
layout = QVBoxLayout(self)
# 图标和标题
title_label = QLabel("合同管理系统")
title_font = QFont()
title_font.setPointSize(16)
title_font.setBold(True)
title_label.setFont(title_font)
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title_label)
# 分隔线
line = QFrame()
line.setFrameShape(QFrame.Shape.HLine)
line.setFrameShadow(QFrame.Shadow.Sunken)
layout.addWidget(line)
# 密码输入
form_layout = QFormLayout()
self.password_input = QLineEdit()
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
form_layout.addRow("管理员密码:", self.password_input)
layout.addLayout(form_layout)
# 记住密码选项
self.remember_checkbox = QCheckBox("记住密码")
layout.addWidget(self.remember_checkbox)
# 按钮
button_box = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
# 设置焦点
self.password_input.setFocus()
def accept(self):
"""验证密码并接受对话框"""
password = self.password_input.text()
if self.password_manager.verify_password(password):
super().accept()
else:
QMessageBox.warning(self, "登录失败", "密码错误,请重试!")
self.password_input.selectAll()
self.password_input.setFocus()
class ChangePasswordDialog(QDialog):
"""修改密码对话框"""
password_changed = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("修改密码")
self.setFixedSize(300, 200)
self.password_manager = PasswordManager()
layout = QVBoxLayout(self)
form_layout = QFormLayout()
self.old_password = QLineEdit()
self.old_password.setEchoMode(QLineEdit.EchoMode.Password)
self.new_password = QLineEdit()
self.new_password.setEchoMode(QLineEdit.EchoMode.Password)
self.confirm_password = QLineEdit()
self.confirm_password.setEchoMode(QLineEdit.EchoMode.Password)
form_layout.addRow("当前密码:", self.old_password)
form_layout.addRow("新密码:", self.new_password)
form_layout.addRow("确认新密码:", self.confirm_password)
layout.addLayout(form_layout)
button_box = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
)
button_box.accepted.connect(self.change_password)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
def change_password(self):
"""修改密码处理"""
old_pwd = self.old_password.text()
new_pwd = self.new_password.text()
confirm_pwd = self.confirm_password.text()
# 验证当前密码
if not self.password_manager.verify_password(old_pwd):
QMessageBox.warning(self, "修改失败", "当前密码不正确!")
self.old_password.selectAll()
self.old_password.setFocus()
return
# 验证新密码
if len(new_pwd) < 6:
QMessageBox.warning(self, "修改失败", "新密码长度至少需要6个字符!")
self.new_password.selectAll()
self.new_password.setFocus()
return
if new_pwd != confirm_pwd:
QMessageBox.warning(self, "修改失败", "两次输入的新密码不一致!")
self.confirm_password.selectAll()
self.confirm_password.setFocus()
return
# 修改密码
self.password_manager.set_password(new_pwd)
QMessageBox.information(self, "修改成功", "密码已成功修改!")
self.accept()
class ContractDialog(QDialog):
"""合同详情对话框"""
def __init__(self, parent=None, contract=None):
super().__init__(parent)
self.setWindowTitle("合同详情")
self.setFixedSize(400, 350)
layout = QFormLayout()
self.contract_name = QLineEdit()
self.client = QLineEdit()
self.amount = QLineEdit()
self.start_date = QDateEdit()
self.start_date.setCalendarPopup(True)
self.start_date.setDate(QDate.currentDate())
self.end_date = QDateEdit()
self.end_date.setCalendarPopup(True)
self.end_date.setDate(QDate.currentDate().addMonths(1))
self.status = QComboBox()
self.status.addItems(["有效", "过期", "终止", "完成"])
layout.addRow("合同名称:", self.contract_name)
layout.addRow("客户名称:", self.client)
layout.addRow("合同金额:", self.amount)
layout.addRow("开始日期:", self.start_date)
layout.addRow("结束日期:", self.end_date)
layout.addRow("合同状态:", self.status)
# 备注信息
self.notes = QLineEdit()
layout.addRow("备注:", self.notes)
self.buttons = QPushButton("保存")
self.buttons.clicked.connect(self.accept)
layout.addRow(self.buttons)
self.setLayout(layout)
if contract:
self.fill_form(contract)
def fill_form(self, contract):
"""填充表单数据"""
self.contract_name.setText(contract[1])
self.client.setText(contract[2])
self.amount.setText(str(contract[3]))
self.start_date.setDate(QDate.fromString(contract[4], "yyyy-MM-dd"))
self.end_date.setDate(QDate.fromString(contract[5], "yyyy-MM-dd"))
self.status.setCurrentText(contract[6])
if len(contract) > 7:
self.notes.setText(contract[7])
class ContractManager(QMainWindow):
"""合同管理主窗口"""
def __init__(self):
super().__init__()
self.setWindowTitle("合同管理系统")
self.setGeometry(100, 100, 1000, 600)
# 密码管理器
self.password_manager = PasswordManager()
# 数据库连接
self.db_connect()
# 初始化UI
self.init_ui()
# 加载合同数据
self.load_contracts()
def db_connect(self):
"""连接数据库"""
self.conn = sqlite3.connect("contracts.db")
self.cursor = self.conn.cursor()
# 创建合同表(如果不存在)
self.cursor.execute("""
CREATE TABLE IF NOT EXISTS contracts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
client TEXT NOT NULL,
amount REAL,
start_date DATE,
end_date DATE,
status TEXT,
notes TEXT
)
""")
self.conn.commit()
def init_ui(self):
"""初始化用户界面"""
main_widget = QWidget()
main_layout = QVBoxLayout()
# 表格 - 先初始化表格
self.table = QTableWidget()
self.table.setColumnCount(7)
self.table.setHorizontalHeaderLabels(
["ID", "合同名称", "客户", "金额", "开始日期", "结束日期", "状态"]
)
self.table.setColumnWidth(1, 200)
self.table.setColumnWidth(2, 150)
self.table.setColumnWidth(3, 100)
self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
# 顶部工具栏 - 现在可以安全地创建菜单栏,因为table已经初始化
self.create_menu_bar()
# 搜索栏
search_layout = QHBoxLayout()
self.search_input = QLineEdit()
self.search_input.setPlaceholderText("搜索合同名称或客户...")
self.search_input.setMinimumHeight(30)
self.search_input.setStyleSheet("padding: 5px;")
self.search_input.textChanged.connect(self.search_contracts)
# 高级搜索按钮
self.advanced_search_btn = QPushButton("高级搜索")
self.advanced_search_btn.setMinimumHeight(30)
self.advanced_search_btn.clicked.connect(self.show_advanced_search)
search_layout.addWidget(self.search_input)
search_layout.addWidget(self.advanced_search_btn)
# 操作按钮
btn_layout = QHBoxLayout()
self.add_btn = QPushButton("新增合同")
self.add_btn.setMinimumHeight(35)
self.add_btn.setIcon(QIcon.fromTheme("list-add"))
self.add_btn.clicked.connect(self.add_contract)
self.edit_btn = QPushButton("编辑合同")
self.edit_btn.setMinimumHeight(35)
self.edit_btn.setIcon(QIcon.fromTheme("document-edit"))
self.edit_btn.clicked.connect(self.edit_contract)
self.delete_btn = QPushButton("删除合同")
self.delete_btn.setMinimumHeight(35)
self.delete_btn.setIcon(QIcon.fromTheme("edit-delete"))
self.delete_btn.clicked.connect(self.delete_contract)
# 导出按钮
self.export_btn = QPushButton("导出数据")
self.export_btn.setMinimumHeight(35)
self.export_btn.setIcon(QIcon.fromTheme("document-export"))
self.export_btn.clicked.connect(self.export_data)
btn_layout.addWidget(self.add_btn)
btn_layout.addWidget(self.edit_btn)
btn_layout.addWidget(self.delete_btn)
btn_layout.addStretch()
btn_layout.addWidget(self.export_btn)
# 状态栏
self.statusBar().showMessage("就绪")
# 组合布局
main_layout.addLayout(search_layout)
main_layout.addLayout(btn_layout)
main_layout.addWidget(self.table)
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
def create_menu_bar(self):
"""创建菜单栏"""
menubar = self.menuBar()
# 文件菜单
file_menu = menubar.addMenu("文件")
# 导出数据
export_action = QAction("导出数据", self)
export_action.setShortcut("Ctrl+E")
export_action.triggered.connect(self.export_data)
file_menu.addAction(export_action)
file_menu.addSeparator()
# 退出
exit_action = QAction("退出", self)
exit_action.setShortcut("Ctrl+Q")
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
# 设置菜单
settings_menu = menubar.addMenu("设置")
# 修改密码
change_pwd_action = QAction("修改密码", self)
change_pwd_action.triggered.connect(self.change_password)
settings_menu.addAction(change_pwd_action)
# 视图菜单
view_menu = menubar.addMenu("视图")
# 显示/隐藏列
self.column_actions = []
for col in range(self.table.columnCount()):
col_name = self.table.horizontalHeaderItem(col).text()
action = QAction(col_name, self, checkable=True)
action.setChecked(True)
action.triggered.connect(lambda checked, c=col: self.toggle_column(c, checked))
self.column_actions.append(action)
view_menu.addAction(action)
def toggle_column(self, column, visible):
"""显示或隐藏表格列"""
if visible:
self.table.showColumn(column)
else:
self.table.hideColumn(column)
def load_contracts(self, search_text="", status_filter=None, date_range=None):
"""加载合同数据"""
query = """
SELECT id, name, client, amount, start_date, end_date, status, notes
FROM contracts
WHERE name LIKE ? OR client LIKE ?
"""
params = [f"%{search_text}%", f"%{search_text}%"]
# 状态筛选
if status_filter and status_filter != "全部":
query += " AND status = ?"
params.append(status_filter)
# 日期范围筛选
if date_range and len(date_range) == 2:
start_date, end_date = date_range
query += " AND start_date >= ? AND end_date <= ?"
params.extend([start_date, end_date])
# 添加排序
query += " ORDER BY start_date DESC"
self.cursor.execute(query, params)
contracts = self.cursor.fetchall()
self.table.setRowCount(len(contracts))
for row, contract in enumerate(contracts):
for col, data in enumerate(contract[:7]): # 只显示前7列
item = QTableWidgetItem(str(data))
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsEditable)
# 根据状态设置单元格颜色
if col == 6: # 状态列
if data == "有效":
item.setBackground(QColor(220, 255, 220))
elif data == "过期":
item.setBackground(QColor(255, 220, 220))
elif data == "终止":
item.setBackground(QColor(240, 240, 240))
elif data == "完成":
item.setBackground(QColor(220, 220, 255))
self.table.setItem(row, col, item)
self.statusBar().showMessage(f"共加载 {len(contracts)} 条合同数据")
def get_selected_id(self):
"""获取选中的合同ID"""
selected_items = self.table.selectedItems()
if not selected_items:
return None
return int(selected_items[0].text())
def add_contract(self):
"""添加新合同"""
dialog = ContractDialog(self)
if dialog.exec():
try:
self.cursor.execute("""
INSERT INTO contracts
(name, client, amount, start_date, end_date, status, notes)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
dialog.contract_name.text(),
dialog.client.text(),
float(dialog.amount.text()),
dialog.start_date.date().toString("yyyy-MM-dd"),
dialog.end_date.date().toString("yyyy-MM-dd"),
dialog.status.currentText(),
dialog.notes.text()
))
self.conn.commit()
self.load_contracts()
QMessageBox.information(self, "成功", "合同添加成功!")
except Exception as e:
QMessageBox.critical(self, "错误", f"添加合同失败: {str(e)}")
def edit_contract(self):
"""编辑选中的合同"""
contract_id = self.get_selected_id()
if not contract_id:
QMessageBox.warning(self, "警告", "请先选择一个合同")
return
self.cursor.execute("SELECT * FROM contracts WHERE id=?", (contract_id,))
contract = self.cursor.fetchone()
dialog = ContractDialog(self, contract)
if dialog.exec():
try:
self.cursor.execute("""
UPDATE contracts SET
name=?, client=?, amount=?, start_date=?, end_date=?, status=?, notes=?
WHERE id=?
""", (
dialog.contract_name.text(),
dialog.client.text(),
float(dialog.amount.text()),
dialog.start_date.date().toString("yyyy-MM-dd"),
dialog.end_date.date().toString("yyyy-MM-dd"),
dialog.status.currentText(),
dialog.notes.text(),
contract_id
))
self.conn.commit()
self.load_contracts()
QMessageBox.information(self, "成功", "合同更新成功!")
except Exception as e:
QMessageBox.critical(self, "错误", f"更新合同失败: {str(e)}")
def delete_contract(self):
"""删除选中的合同"""
contract_id = self.get_selected_id()
if not contract_id:
QMessageBox.warning(self, "警告", "请先选择一个合同")
return
confirm = QMessageBox.question(
self, "确认删除", "确定要删除这个合同吗?此操作不可撤销!",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
if confirm == QMessageBox.StandardButton.Yes:
try:
self.cursor.execute("DELETE FROM contracts WHERE id=?", (contract_id,))
self.conn.commit()
self.load_contracts()
QMessageBox.information(self, "成功", "合同已删除!")
except Exception as e:
QMessageBox.critical(self, "错误", f"删除合同失败: {str(e)}")
def search_contracts(self):
"""搜索合同"""
search_text = self.search_input.text()
self.load_contracts(search_text)
def show_advanced_search(self):
"""显示高级搜索对话框"""
dialog = QDialog(self)
dialog.setWindowTitle("高级搜索")
dialog.setMinimumWidth(400)
layout = QVBoxLayout()
# 状态筛选
status_layout = QHBoxLayout()
status_label = QLabel("合同状态:")
status_combo = QComboBox()
status_combo.addItems(["全部", "有效", "过期", "终止", "完成"])
status_layout.addWidget(status_label)
status_layout.addWidget(status_combo)
# 日期范围筛选
date_layout = QHBoxLayout()
date_label = QLabel("日期范围:")
start_date = QDateEdit()
start_date.setCalendarPopup(True)
start_date.setDate(QDate.currentDate().addMonths(-1))
end_label = QLabel("至")
end_date = QDateEdit()
end_date.setCalendarPopup(True)
end_date.setDate(QDate.currentDate())
date_layout.addWidget(date_label)
date_layout.addWidget(start_date)
date_layout.addWidget(end_label)
date_layout.addWidget(end_date)
# 按钮
button_layout = QHBoxLayout()
search_btn = QPushButton("搜索")
search_btn.clicked.connect(lambda: self.advanced_search(
status_combo.currentText(),
(start_date.date().toString("yyyy-MM-dd"), end_date.date().toString("yyyy-MM-dd"))
))
cancel_btn = QPushButton("取消")
cancel_btn.clicked.connect(dialog.close)
button_layout.addStretch()
button_layout.addWidget(search_btn)
button_layout.addWidget(cancel_btn)
layout.addLayout(status_layout)
layout.addLayout(date_layout)
layout.addLayout(button_layout)
dialog.setLayout(layout)
dialog.exec()
def advanced_search(self, status, date_range):
"""执行高级搜索"""
self.load_contracts(status_filter=status, date_range=date_range)
def export_data(self):
"""导出数据"""
QMessageBox.information(self, "提示", "数据导出功能将在后续版本中实现")
def change_password(self):
"""修改密码"""
dialog = ChangePasswordDialog(self)
dialog.exec()
def closeEvent(self, event):
"""关闭事件处理"""
self.conn.close()
event.accept()
def main():
"""主函数"""
app = QApplication(sys.argv)
# 先显示登录对话框
login_dialog = LoginDialog()
if login_dialog.exec() != QDialog.DialogCode.Accepted:
sys.exit()
# 登录成功后显示主窗口
window = ContractManager()
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
未经允许不得转载作者:
System,
转载或复制请以
超链接形式
并注明出处
科技之星网站 。
原文地址:
《
【Python 原创】科技之星合同简约记录开源Python和PyQt6开发的合同管理系统》
发布于
2025-5-19
(禁止商用或其它牟利行为)版权归原作者本人所有,您必须在下载后24小时内删除, 感谢您的理解与合作








谢谢谢
非常感谢您的关注和支持!很高兴您对我们的Python和PyQt6开发的合同管理系统感兴趣。有任何建议或疑问,随时欢迎提出,我们将竭诚为您提供帮助。期待您的反馈来促进我们产品的不断完善。祝您用得顺手!