Python项目源码63:病历管理系统1.0(tkinter+sqlite3+matplotlib)

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

相关推荐
不爱吃山楂罐头14 分钟前
第三十三天打卡复习
python·深度学习
Dxy12393102161 小时前
DrissionPage 性能优化实战指南:让网页自动化效率飞升
运维·爬虫·python·性能优化·自动化
蹦蹦跳跳真可爱5891 小时前
Python----目标检测(《SSD: Single Shot MultiBox Detector》论文和SSD的原理与网络结构)
人工智能·python·深度学习·神经网络·目标检测·计算机视觉
LeonDL1682 小时前
HALCON 深度学习训练 3D 图像的几种方式优缺点
人工智能·python·深度学习·3d·halcon·halcon训练3d图像·深度学习训练3d图像
慧都小妮子2 小时前
跨平台浏览器集成库JxBrowser 支持 Chrome 扩展程序,高效赋能 Java 桌面应用
开发语言·python·api·jxbrowser·chrome 扩展程序
tanyyinyu3 小时前
Python函数参数详解:从位置参数到灵活调用的艺术
运维·开发语言·python
qq_214782614 小时前
mac下通过anaconda安装Python
python·macos·jupyter
junyuz5 小时前
Dify docker内网部署常见问题记录
python·docker
@HNUSTer5 小时前
Python数据可视化科技图表绘制系列教程(一)
python·数据可视化·科技论文·专业制图·科研图表
reasonsummer6 小时前
【办公类-48-04】202506每月电子屏台账汇总成docx-5(问卷星下载5月范围内容,自动获取excel文件名,并转移处理)
python·excel