【Part5】エンコードを自動/手動で設定して読み込み・書き込みを行えるようにしよう【CTkでメモ帳を作る】

2026年4月10日金曜日

t f B! P L
 前回の続きです。
【前回】

今回行えるようにすること

・ファイルを開くときは自動で文字コードを識別する。
・手動で文字コードを指定して再読み込みする。
・保存するときの文字コードを指定する。

1つめについてですが、今回はライブラリを使うため、インストールをお願いします。

pip install chardet

2つ目についてはメニューバーに、3つ目についてはステータスバーの表示を活用します。
ずっと「UTF-8」と表示させていたのは伏線です。

改修部分

その前に初期化しょりについて、1行追加します。

        super().__init__()
        self.title("メモ帳 - 新規")
        self.geometry("900x600")
        self.nowfile = ""
        self.nowencode = "utf-8"

追加したのはself.nowencodeです。今回から文字コードを扱うのでこのように、今ど文字コードで編集しているのかというのをself.nowencodeで明示してきます。
ではまず2つ目についてです。

        encmenu = tk.Menu(filemenu, tearoff=0)
        encmenu.add_command(label="UTF-8",command=lambda:self.openenc("utf-8"))
        encmenu.add_command(label="Shift-JIS",command=lambda:self.openenc("shift-jis"))
        encmenu.add_command(label="CP932",command=lambda:self.openenc("cp932"))
        encmenu.add_command(label="EUC-JP", command=lambda:self.openenc("euc-jp"))
        encmenu.add_command(label="UTF-16LE", command=lambda:self.openenc("utf-16-le"))
        filemenu.add_cascade(label="文字コードを指定して再読み込み", menu=encmenu)

このようにして、文字コードを選択できるようにします。またその関数については以下の通りです。

    def openenc(self, encode):
        if self.nowfile != "":
            f = open(self.nowfile, "r", encoding=encode, errors="ignore")
            self.textbox.delete("1.0", tk.END)
            self.textbox.insert("1.0", f.read())
            f.close()
            self.statusbar2.configure(text=encode.upper())
            self.nowencode = encode

このようにすることで、ファイルを文字コードを指定して再読み込みできるようにします。

そして1つ目について。自動で識別してファイルを開けるように、以下のように関数を修正します。

    def openfile(self, event=None):
        file = filedialog.askopenfilename()
        if file:
            f = open(file, "rb")
            data = f.read()
            f.close()
            encode = chardet.detect(data)["encoding"]
            self.nowencode = encode
            self.statusbar2.configure(text=encode.upper())
            f = open(file, "r", encoding=encode)
            self.textbox.delete("1.0", tk.END)
            self.textbox.insert("1.0", f.read())
            self.title("メモ帳 - " + file)
            self.nowfile = file
            f.close()

少しコードの書き方が汚いかもしれませんが、こんな感じです。
最後に3つ目について。これは、ステータスバーの文字コードの部分をクリックした際にポップアップメニューを表示させ、そこで選べるようにします。

self.statusbar2.bind("<ButtonRelease-1>", self.showencodemenu)

このようにしてクリックイベントをバインドし、

    def showencodemenu(self, event):
        encmenu = tk.Menu(self, tearoff=0)
        encmenu.add_command(label="UTF-8",command=lambda:self.setenc("utf-8"))
        encmenu.add_command(label="Shift-JIS",command=lambda:self.setenc("shift-jis"))
        encmenu.add_command(label="CP932",command=lambda:self.setenc("cp932"))
        encmenu.add_command(label="EUC-JP", command=lambda:self.setenc("euc-jp"))
        encmenu.add_command(label="UTF-16LE", command=lambda:self.setenc("utf-16-le"))
        encmenu.post(event.x_root, event.y_root)
    
    def setenc(self, encode):
        self.nowencode = encode
        self.statusbar2.configure(text=encode.upper())

このように関数を定義します。
self.nowencodeに代入することによって保存時のエンコードをそれにします。
ということで、保存関数についても修正が必要です。

    def onsave(self, event=None):
        if self.nowfile == "":
            self.saveas()
        else:
            f = open(self.nowfile, "w", encoding=self.nowencode)
            f.write(self.textbox.get("1.0", tk.END))
            f.close()
            self.title("メモ帳 - " + self.nowfile)
    
    def saveas(self, event=None):
        file = filedialog.asksaveasfilename(defaultextension="txt")
        if file:
            f = open(file, "w", encoding=self.nowencode)
            f.write(self.textbox.get("1.0", tk.END))
            f.close()
            self.title("メモ帳 - " + file)
            self.nowfile = file

まあ行ったことは、encoding=を今まではutf-8固定だったのをself.nowencodeというのにしたということだけですね。

実行イメージ

以下のような感じで、メニューに新たな項目が追加されました。


また、保存時の文字コード指定についてもできています。


全体のコード

全体のコードについては長くなりすぎたので、どうしようかなあ...
考えた結果、以下に貼り付けておきました。そのまま開くと文字化けするんで、右クリックでリンク先を保存してください。


次回に続きます。

このブログを検索

要望について

ブログのレイアウトやテーマについての提案をいただきました。現在qooqテーマを適応中です。 よければフォームが期限切れしてしまったのでお問い合わせメールから要望等お願いします。

最近の出来事

最近の出来事
寿司打お勧め75位♪(練習モードだけど)

Welcome!

「プログラミング独学ブログ」へようこそ。 Yakinyといいます。幅広い範囲で投稿していますので、ぜひ過去の記事も見てみてください!!コメントも大歓迎です!

お問い合わせ

名前

メール *

メッセージ *

QooQ