You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pydicom修改PatientName标签时触发AttributeError问题求助

解决Dicom PatientName属性无法直接赋值的问题

pydicom里的PatientName对应的是PersonName类实例,它的given_name、family_name、name_prefix这些属性都是只读的,所以直接用ds.PatientName.given_name = 新值的写法必然触发AttributeError。要修改这些字段,正确的做法是创建一个新的PersonName对象,然后替换整个ds.PatientName字段。

具体实现步骤

  1. 从pydicom导入PersonName类;
  2. 从你的tkinter输入框中收集用户输入的头衔、名、姓;
  3. 用收集到的参数创建新的PersonName实例;
  4. 将新实例赋值给ds.PatientName,再保存文件。

修改后的tkinter代码示例

假设你原来的代码结构如下,这里给出修正后的核心部分:

import pydicom
import tkinter as tk
from tkinter import ttk, messagebox
from pydicom.valuerep import PersonName  # 导入PersonName类

# 读取目标Dicom文件
ds = pydicom.dcmread("your_file.dcm")

def save_modified_name():
    # 获取输入框中的新值,去除首尾空格
    new_prefix = entry_new_prefix.get().strip()
    new_given = entry_new_given.get().strip()
    new_family = entry_new_family.get().strip()
    
    # 创建新的PersonName对象,传入各字段值
    updated_name = PersonName(
        family_name=new_family,
        given_name=new_given,
        name_prefix=new_prefix
    )
    
    # 替换原PatientName字段
    ds.PatientName = updated_name
    
    # 保存修改后的文件
    try:
        ds.save_as("modified_patient_name.dcm")
        messagebox.showinfo("完成", "患者姓名已成功修改并保存")
    except Exception as e:
        messagebox.showerror("错误", f"保存失败:{str(e)}")

# --- 以下是UI部分(可根据你的原有代码调整)---
root = tk.Tk()
root.title("Dicom患者姓名修改")

# 旧数据显示区域
ttk.Label(root, text="原姓名信息").grid(row=0, column=0, columnspan=2, padx=5, pady=5)
ttk.Label(root, text="头衔:").grid(row=1, column=0, padx=5, pady=2)
entry_old_prefix = ttk.Entry(root, state="readonly")
entry_old_prefix.insert(0, ds.PatientName.name_prefix)
entry_old_prefix.grid(row=1, column=1, padx=5, pady=2)

ttk.Label(root, text="名:").grid(row=2, column=0, padx=5, pady=2)
entry_old_given = ttk.Entry(root, state="readonly")
entry_old_given.insert(0, ds.PatientName.given_name)
entry_old_given.grid(row=2, column=1, padx=5, pady=2)

ttk.Label(root, text="姓:").grid(row=3, column=0, padx=5, pady=2)
entry_old_family = ttk.Entry(root, state="readonly")
entry_old_family.insert(0, ds.PatientName.family_name)
entry_old_family.grid(row=3, column=1, padx=5, pady=2)

# 新数据输入区域
ttk.Label(root, text="新姓名信息").grid(row=4, column=0, columnspan=2, padx=5, pady=10)
ttk.Label(root, text="头衔:").grid(row=5, column=0, padx=5, pady=2)
entry_new_prefix = ttk.Entry(root)
entry_new_prefix.grid(row=5, column=1, padx=5, pady=2)

ttk.Label(root, text="名:").grid(row=6, column=0, padx=5, pady=2)
entry_new_given = ttk.Entry(root)
entry_new_given.grid(row=6, column=1, padx=5, pady=2)

ttk.Label(root, text="姓:").grid(row=7, column=0, padx=5, pady=2)
entry_new_family = ttk.Entry(root)
entry_new_family.grid(row=7, column=1, padx=5, pady=2)

# 保存按钮
btn_save = ttk.Button(root, text="保存修改", command=save_modified_name)
btn_save.grid(row=8, column=0, columnspan=2, padx=5, pady=10)

root.mainloop()

说明

  • 这种方式完全符合pydicom的设计规范,不需要手动拼接^分隔符,避免了格式错误;
  • 如果某个字段用户没有输入(比如头衔为空),PersonName会自动处理空值,生成符合Dicom标准的姓名格式;
  • 代码中加入了异常捕获,能在保存失败时给出明确提示。

内容的提问来源于stack exchange,提问作者Kasai kemono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:45:28