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

1.病历管理系统包含以下主要功能:

核心功能:病历信息录入(患者姓名、年龄、性别、诊断结果、主治医生),自动记录就诊时间,病历信息展示(使用Treeview表格),病历信息查询(按姓名搜索),数据sqlite3存储。
主要组件:输入表单:包含患者基本信息输入字段,功能按钮:添加、查询、保存、加载、清空,病历列表:以表格形式展示所有病历记录,双击支持:双击记录可自动填充到输入框。
数据库存储:使用SQLite3替代JSON文件存储,自动创建数据库表结构,使用参数化查询防止SQL注入。

2.使用说明:运行程序后会生成medical_records.db文件用于存储数据,输入患者信息后点击"添加病历"按钮保存,输入姓名等条件进行高级搜索,双击表格记录可将数据填充到输入框。
在这里插入图片描述
高级查询
在这里插入图片描述
数据可视化
在这里插入图片描述

# -*- 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 FigureCanvasTkAggclass MedicalRecordSystem:def __init__(self, root):self.root = rootself.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 cursorexcept 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("输入错误", "患者姓名和诊断结果不能为空!")returntry: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("警告", "请先选择要修改的记录")returnrecord_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 SETname=?, 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("警告", "请先选择要删除的记录")returnif 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] = entrydef 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MCP底层协议完整通信过程

2025 年是智能体的元年, 也注定是智能体集中爆发的一年! 两个互联领域的重大挑战: 第一、 Agent 与 Tools (工具)的交互 Agent 需要调用外部工具和 API

docker:制作镜像+上传镜像+拉取镜像

1.dockerfile制作镜像 示例内容&#xff1a; 1.创建一个index.js的文件 console.log("hello world")2.在相同目录下创建名为dockerfile的文件 FROM node:alpine COPY index.js /index.js CMD node /index.js3.构建镜像 docker build -t minterra/hello-docker . …

docker制作python大模型镜像(miniconda环境),工程改造记录

**环境说明&#xff1a;**从系统镜像开始打造python大模型镜像&#xff0c;之前是人工手动装的方式&#xff0c;并且模型和依赖在公网中&#xff0c;对于离线交付环境不太友好&#xff0c;所以打造的离线化交付版本 Dockerfile: FROM centos:7.9 ENV PYTHONIOENCODINGutf-8 E…

Rust中避免过度使用锁导致性能问题的策略

一、引言 在 Rust 多线程编程中&#xff0c;锁是实现线程同步的重要工具&#xff0c;它可以防止多个线程同时访问和修改共享数据&#xff0c;从而避免数据竞争和不一致的问题。然而&#xff0c;过度使用锁会带来严重的性能问题&#xff0c;如锁竞争导致的线程阻塞、上下文切换…

数据结构每日一题day15(链表)★★★★★

题目描述&#xff1a;将一个带头结点的单链表A分解为两个带头结点的单链表A和 B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持相对顺不变&#xff0c;最后返回 B 表。 算法思想&#xff1a; 1.初始化&#xff1a; 创建新链表 B 的头结点。…

【杂谈】-探索 NVIDIA Dynamo 的高性能架构

探索 NVIDIA Dynamo 的高性能架构 文章目录 探索 NVIDIA Dynamo 的高性能架构1. 大规模人工智能推理的日益严峻的挑战2. 使用 NVIDIA Dynamo 优化 AI 推理3. 实际应用和行业影响4. 竞争优势&#xff1a;Dynamo 与其他方案对比5. 总结 随着人工智能&#xff08;AI&#xff09;技…

postgresql数据库基本操作

1. 连接 PostgreSQL 数据库 首先&#xff0c;使用 psql 命令行工具连接到数据库。如果是本地连接&#xff0c;命令格式如下&#xff1a; psql -U postgres -d <数据库名称> -h <主机地址>其中&#xff1a; -U postgres&#xff1a;表示以 postgres 用户身份登录…

工业大模型:从设备诊断到工艺重构

引言 工业大模型正在引发制造业认知革命。据埃森哲研究,到2026年全球工业大模型市场规模将突破280亿美元,其中工艺优化应用占比达42%。本文将系统解析工业大模型的"预训练-领域适配-应用落地"技术路径,并通过设备健康诊断与工艺参数生成的实践案例,展示如何构建…

PyQt5基本介绍

PyQt5是基于Digia公司强大图形框架Qt5的python接口&#xff0c;由一组python模块构成。是一个用于创建桌面应用程序的Python库&#xff0c;它是Qt图形用户界面工具包的Python绑定。 Qt是一个跨平台的C库&#xff0c;提供了一套丰富的工具和功能&#xff0c;用于开发图形用户界…

Tire 树(字典树/前缀树)

一、定义与结构 用来快速存储查找字符串集合的一种数据结构 将字符串按顺序连接根节点上&#xff0c;并在字符串结束的地方打上标记并计数。 二、模板题 acwing 835 Trie 树的字符串统计 题目&#xff1a; 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向…

【时时三省】(C语言基础)怎样定义和引用一维数组

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 一维数组是数组中最简单的&#xff0c;它的元素只需要用数组名加一个下标&#xff0c;就能唯一地确定。如上面介绍的学生成绩数组s就是一维数组。有的数组&#xff0c;其元素要指定两个下标才…

编译faiss

编译faiss-1.10.0 首先确保自己cmake的版本&#xff1a; cmake --version 确保其版本至少为CMake 3.24.0 or higher is required。 其次安装OpenBLAS&#xff1a; https://github.com/OpenMathLib/OpenBLAS 去这里去安转Openblas内容&#xff0c;然后确保自己的CPU的指令集是存…

Linux 入门:操作系统进程详解

目录 一.冯诺依曼体系结构 一&#xff09;. 软件运行前为什么要先加载&#xff1f;程序运行之前在哪里&#xff1f; 二&#xff09;.理解数据流动 二.操作系统OS(Operator System) 一&#xff09;.概念 二&#xff09;.设计OS的目的 三&#xff09;.如何理解操作系统…

word交叉引用图片、表格——只引用编号的处理方法

交叉引用图片/表格 在“引用”选项卡上的“题注”组中&#xff0c;单击“插入题注”。勾选【从题注中排除标签】。在文中插入题注。 【注 意】 这时候插入的题注只有编号项了。然后手动打上标签【TABLE】&#xff0c;并在标签和编号项之间加上【样式分隔符&#xff0c;AltCt…

rails 8 CSS不起效问题解决

很久没用rails了&#xff0c;最近打算重新复习一下。在配置好环境后&#xff0c;创建了项目&#xff0c;通过脚手架创建了数据库表&#xff0c;和相关的文件。但我发现却没有生成相应的CSS文件&#xff0c;可能是rails8 取消了吧。于是自己手动创建了相应的css文件。但是刷新页…

【nlohmann\json.hpp】‘_snprintf‘: is not a member of ‘std‘

这个问题时有发生但是为啥现在更新了vs2022 后,发生了这些报错:2>(compiling source file ../worker/src/fargo/PacedVideoSenderGo.cpp) 2>D:\XTRANS\thunderbolt\ayame

数据结构--【二叉树】

目录 定义结构体&#xff1a; 初始化&#xff1a; 手动创建一个二叉树&#xff1a; 前序遍历&#xff1a; 中序遍历&#xff1a; 后序遍历 二叉树节点个数&#xff1a; 叶子节点个数&#xff1a; 二叉树第k层节点个数&#xff1a; 二叉树的高度&#xff1a; 查找值为x…

深入解析Linux进程间通信(IPC):机制、应用与最佳实践

引言 在多任务操作系统中&#xff0c;进程间通信&#xff08;Inter-Process Communication, IPC&#xff09;是协同工作的核心机制。Linux作为现代操作系统的典范&#xff0c;提供了8种主要IPC方式&#xff0c;从传统的管道到面向网络的套接字&#xff0c;每种方法都暗藏独特的…

2025年“深圳杯”数学建模挑战赛B题-LED显示屏颜色转换设计与校正

LED显示屏颜色转换设计与校正 小驴数模 问题的背景 走在晚风都市&#xff0c;或春日田野&#xff0c;我们都会看到一个色彩斑斓的世界。色彩是我们对世界一种重要感知。什么是色彩&#xff0c;或颜色&#xff1f;颜色是光作用于人眼引起的视觉感知现象&#xff0c;它与物体的…

Java学习手册:Spring MVC 架构与实现

一、Spring MVC 概述 Spring MVC 是 Spring 框架的一个模块&#xff0c;它提供了一套 Web 应用开发的解决方案&#xff0c;实现了 MVC&#xff08;Model-View-Controller&#xff09;设计模式。Spring MVC 提供了清晰的分离逻辑层、视图层和控制器层的结构&#xff0c;便于开发…