Python独習!

習得したPython知識をペイフォワード

Pythonで設定ファイル(.xml)の読み込みと書き換えをする

ソフトウェアの設定(好みの画面設定、出力ファイルの保存場所とか)を保存するには、ini、xmljsonどれがいいの?
ソフトウェアの目的に合わせて選択するしかない。ネットに沢山の情報が転がっているが、それらは異なる背景を持つプログラマーたちの意見である。そこからは何がベストなのか決めることはできない、という結論に至った。流行り廃りだけで言えば、iniファイルは時代遅れ、xmlが普及している、jsonが伸びてきている、といったところ。

サンプルプログラム

今回はxmlを取り上げることにして、気が向いたらjsonを試してみる。
作ったプログラムはありふれた内容だが、[Read]ボタンで設定ファイルから値を読み込んでテキストボックスに表示、[Write]ボタンでテキストボックス上で編集した内容を設定ファイルに書き込む、というもの。

〇[Read]ボタンを押すとconfig.xmlの値をテキストボックスに表示する
python_xml_read

〇[Write]ボタンを押すとconfig.xmlにテキストボックスの値を書き込む
python_xml_write

ソースコード

# ReadWriteXML_001.py
# Python 3.8.1

import tkinter as tk
import xml.etree.ElementTree as ET

class App(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        ## Make instances
        self.ent1 = tk.Entry(self, width=50)
        self.ent2 = tk.Entry(self, width=50)
        self.ent3 = tk.Entry(self, width=50)

        self.lb1 = tk.Label(self, text="ent1:")
        self.lb2 = tk.Label(self, text="ent2:")
        self.lb3 = tk.Label(self, text="ent3:")

        self.bt1 = tk.Button(self, text="Read",  width=6, command=self.read_xml)          
        self.bt2 = tk.Button(self, text="Write", width=6, command=self.write_xml)

        ## Place them
        self.lb1.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
        self.lb2.grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
        self.lb3.grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)

        self.ent1.grid(row=0, column=1, columnspan=2, padx=5, pady=5)
        self.ent2.grid(row=1, column=1, columnspan=2, padx=5, pady=5)
        self.ent3.grid(row=2, column=1, columnspan=2, padx=5, pady=5)
        
        self.bt1.grid(row=3, column=1, padx=5, pady=5)
        self.bt2.grid(row=3, column=2, padx=5, pady=5)

    def read_xml(self):
        try:
            tree = ET.parse('config.xml')
            root = tree.getroot()

            text_ent1 = root.find("./setting/ent1").text
            text_ent2 = root.find("./setting/ent2").text
            text_ent3 = root.find("./setting/ent3").text

            self.ent1.delete(0, tk.END)
            self.ent2.delete(0, tk.END)
            self.ent3.delete(0, tk.END)        
        
            self.ent1.insert(0, text_ent1)
            self.ent2.insert(0, text_ent2)
            self.ent3.insert(0, text_ent3)
        except Exception:
            print("例外エラー")
        else:
            print("XML読み込み完了")

    def write_xml(self):
        try:
            tree = ET.parse('config.xml')
            root = tree.getroot()

            text_ent1 = self.ent1.get()
            text_ent2 = self.ent2.get()
            text_ent3 = self.ent3.get()

            root.find("./setting/ent1").text = text_ent1
            root.find("./setting/ent2").text = text_ent2
            root.find("./setting/ent3").text = text_ent3

            tree.write('config.xml')
        except Exception:
            print("例外エラー")
        else:
            print("XML書き込み完了")

if __name__ == "__main__":
    root = tk.Tk()
    app = App(master=root)
    app.mainloop()
/* -----codeの行番号----- */