1.病历管理系统包含以下主要功能:
核心功能:病历信息录入(患者姓名、年龄、性别、诊断结果、主治医生),自动记录就诊时间,病历信息展示(使用Treeview表格),病历信息查询(按姓名搜索),数据sqlite3存储。
主要组件:输入表单:包含患者基本信息输入字段,功能按钮:添加、查询、保存、加载、清空,病历列表:以表格形式展示所有病历记录,双击支持:双击记录可自动填充到输入框。
数据库存储:使用SQLite3替代JSON文件存储,自动创建数据库表结构,使用参数化查询防止SQL注入。
2.使用说明:运行程序后会生成medical_records.db文件用于存储数据,输入患者信息后点击"添加病历"按钮保存,输入姓名等条件进行高级搜索,双击表格记录可将数据填充到输入框。
高级查询
数据可视化
python
# -*- coding: utf-8 -*-
# @Author : 小红牛
# 微信公众号:WdPython
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
from datetime import datetime
from matplotlib import rcParams
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class MedicalRecordSystem:
def __init__(self, root):
self.root = root
self.root.title("病历管理系统1.0")
self.root.geometry("1000x800")
# 初始化数据库
self.conn = sqlite3.connect('medical_records.db')
self.create_table()
# 创建界面组件
self.create_widgets()
self.load_data()
def create_table(self):
cursor = self.conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
gender TEXT,
diagnosis TEXT,
doctor TEXT,
date TEXT)''')
self.conn.commit()
def create_widgets(self):
# 输入区域
input_frame = ttk.LabelFrame(self.root, text="病历信息输入")
input_frame.pack(pady=10, padx=10, fill="x")
labels = ["患者姓名:", "年龄:", "性别:", "诊断结果:", "主治医生:"]
self.entries = {}
for i, text in enumerate(labels):
label = ttk.Label(input_frame, text=text)
label.grid(row=i, column=0, padx=5, pady=5, sticky="e")
entry = ttk.Entry(input_frame, width=40)
entry.grid(row=i, column=1, padx=5, pady=5, sticky="w")
self.entries[text.strip(":")] = entry
# 按钮区域
btn_frame = ttk.Frame(self.root)
btn_frame.pack(pady=10)
buttons = [
("添加病历", self.add_record),
("修改病历", self.update_record),
("删除病历", self.delete_record),
("高级搜索", self.advanced_search),
("数据可视化", self.show_statistics),
("清空输入", self.clear_entries)
]
for i, (text, command) in enumerate(buttons):
btn = ttk.Button(btn_frame, text=text, command=command)
btn.grid(row=0, column=i, padx=5)
# 病历列表
list_frame = ttk.LabelFrame(self.root, text="病历列表")
list_frame.pack(pady=10, padx=10, fill="both", expand=True)
columns = ("id", "name", "age", "gender", "diagnosis", "doctor", "date")
self.tree = ttk.Treeview(list_frame, columns=columns, show="headings")
headings = [
("id", "ID"),
("name", "患者姓名"),
("age", "年龄"),
("gender", "性别"),
("diagnosis", "诊断结果"),
("doctor", "主治医生"),
("date", "就诊日期")
]
for col_id, col_text in headings:
self.tree.heading(col_id, text=col_text)
self.tree.column(col_id, width=100, anchor="center")
vsb = ttk.Scrollbar(list_frame, orient="vertical", command=self.tree.yview)
hsb = ttk.Scrollbar(list_frame, orient="horizontal", command=self.tree.xview)
self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
self.tree.grid(row=0, column=0, sticky="nsew")
vsb.grid(row=0, column=1, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
list_frame.grid_rowconfigure(0, weight=1)
list_frame.grid_columnconfigure(0, weight=1)
self.tree.bind("<Double-1>", self.on_item_double_click)
# 数据库操作方法
def execute_query(self, query, parameters=()):
cursor = self.conn.cursor()
try:
cursor.execute(query, parameters)
self.conn.commit()
return cursor
except Exception as e:
self.conn.rollback()
messagebox.showerror("数据库错误", str(e))
return None
# 核心功能实现
def add_record(self):
record = (
self.entries["患者姓名"].get(),
self.entries["年龄"].get(),
self.entries["性别"].get(),
self.entries["诊断结果"].get(),
self.entries["主治医生"].get(),
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
if not record[0] or not record[3]:
messagebox.showwarning("输入错误", "患者姓名和诊断结果不能为空!")
return
try:
self.execute_query('''INSERT INTO records
(name, age, gender, diagnosis, doctor, date)
VALUES (?,?,?,?,?,?)''', record)
self.load_data()
self.clear_entries()
messagebox.showinfo("成功", "病历添加成功!")
except Exception as e:
messagebox.showerror("错误", f"添加失败:{str(e)}")
def update_record(self):
selected = self.tree.selection()
if not selected:
messagebox.showwarning("警告", "请先选择要修改的记录")
return
record_id = self.tree.item(selected[0], 'values')[0]
new_data = (
self.entries["患者姓名"].get(),
self.entries["年龄"].get(),
self.entries["性别"].get(),
self.entries["诊断结果"].get(),
self.entries["主治医生"].get(),
record_id
)
try:
self.execute_query('''UPDATE records SET
name=?, age=?, gender=?, diagnosis=?, doctor=?
WHERE id=?''', new_data)
self.load_data()
messagebox.showinfo("成功", "病历修改成功!")
except Exception as e:
messagebox.showerror("错误", f"修改失败:{str(e)}")
def delete_record(self):
selected = self.tree.selection()
if not selected:
messagebox.showwarning("警告", "请先选择要删除的记录")
return
if messagebox.askyesno("确认", "确定要删除这条记录吗?"):
record_id = self.tree.item(selected[0], 'values')[0]
try:
self.execute_query('DELETE FROM records WHERE id=?', (record_id,))
self.load_data()
messagebox.showinfo("成功", "记录已删除")
except Exception as e:
messagebox.showerror("错误", f"删除失败:{str(e)}")
def advanced_search(self):
search_window = tk.Toplevel(self.root)
search_window.title("高级搜索")
criteria = [
("患者姓名", "name"),
("最小年龄", "min_age"),
("最大年龄", "max_age"),
("性别", "gender"),
("诊断结果", "diagnosis"),
("主治医生", "doctor")
]
entries = {}
for i, (label, key) in enumerate(criteria):
ttk.Label(search_window, text=label + ":").grid(row=i, column=0, padx=5, pady=5)
entry = ttk.Entry(search_window)
entry.grid(row=i, column=1, padx=5, pady=5)
entries[key] = entry
def perform_search():
conditions = []
params = []
if entries['name'].get():
conditions.append("name LIKE ?")
params.append(f"%{entries['name'].get()}%")
if entries['min_age'].get():
conditions.append("age >= ?")
params.append(int(entries['min_age'].get()))
if entries['max_age'].get():
conditions.append("age <= ?")
params.append(int(entries['max_age'].get()))
if entries['gender'].get():
conditions.append("gender = ?")
params.append(entries['gender'].get())
if entries['diagnosis'].get():
conditions.append("diagnosis LIKE ?")
params.append(f"%{entries['diagnosis'].get()}%")
if entries['doctor'].get():
conditions.append("doctor LIKE ?")
params.append(f"%{entries['doctor'].get()}%")
query = "SELECT * FROM records"
if conditions:
query += " WHERE " + " AND ".join(conditions)
cursor = self.execute_query(query, params)
if cursor:
results = cursor.fetchall()
self.show_search_results(results)
search_window.destroy()
ttk.Button(search_window, text="搜索", command=perform_search).grid(row=len(criteria), columnspan=2)
def show_search_results(self, results):
result_window = tk.Toplevel(self.root)
result_window.title("搜索结果")
tree = ttk.Treeview(result_window, columns=("id", "name", "age", "gender", "diagnosis", "doctor", "date"),
show="headings")
headings = [
("id", "ID"), ("name", "姓名"), ("age", "年龄"),
("gender", "性别"), ("diagnosis", "诊断"),
("doctor", "医生"), ("date", "日期")
]
for col_id, col_text in headings:
tree.heading(col_id, text=col_text)
tree.column(col_id, width=100)
for record in results:
tree.insert("", "end", values=record)
tree.pack(fill="both", expand=True)
def show_statistics(self):
# 设置全局中文字体(解决中文显示问题)
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False # 解决负号显示问题
stat_window = tk.Toplevel(self.root)
stat_window.title("数据统计")
# 年龄分布统计
age_ranges = ["0-18", "19-30", "31-45", "46-60", "61+"]
queries = [
("0-18岁", "age BETWEEN 0 AND 18"),
("19-30岁", "age BETWEEN 19 AND 30"),
("31-45岁", "age BETWEEN 31 AND 45"),
("46-60岁", "age BETWEEN 46 AND 60"),
("61岁及以上", "age >= 61")
]
age_data = {}
for label, condition in queries:
cursor = self.execute_query(f"SELECT COUNT(*) FROM records WHERE {condition}")
age_data[label] = cursor.fetchone()[0]
# 常见疾病统计
cursor = self.execute_query(
"SELECT diagnosis, COUNT(*) FROM records GROUP BY diagnosis ORDER BY COUNT(*) DESC LIMIT 10")
disease_data = cursor.fetchall()
# 创建统计图表
fig = plt.Figure(figsize=(10, 6))
# 年龄分布饼图
ax1 = fig.add_subplot(121)
ax1.pie(age_data.values(), labels=age_data.keys(), autopct='%1.1f%%')
ax1.set_title('年龄分布')
# 常见疾病柱状图
ax2 = fig.add_subplot(122)
diagnoses = [item[0] for item in disease_data]
counts = [item[1] for item in disease_data]
ax2.barh(diagnoses, counts)
ax2.set_title('常见疾病TOP10')
ax2.invert_yaxis()
canvas = FigureCanvasTkAgg(fig, master=stat_window)
canvas.draw()
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
def load_data(self):
cursor = self.execute_query("SELECT * FROM records ORDER BY date DESC")
if cursor:
self.tree.delete(*self.tree.get_children())
for row in cursor.fetchall():
self.tree.insert("", "end", values=row)
def clear_entries(self):
for entry in self.entries.values():
entry.delete(0, "end")
def on_item_double_click(self, event):
selected = self.tree.selection()
if selected:
values = self.tree.item(selected[0], 'values')
self.clear_entries()
self.entries["患者姓名"].insert(0, values[1])
self.entries["年龄"].insert(0, values[2])
self.entries["性别"].insert(0, values[3])
self.entries["诊断结果"].insert(0, values[4])
self.entries["主治医生"].insert(0, values[5])
def __del__(self):
self.conn.close()
if __name__ == "__main__":
root = tk.Tk()
app = MedicalRecordSystem(root)
root.mainloop()
完毕!!感谢您的收看
----------★★跳转到历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具 NumPy Pygame