【Part4】Tkinterでホットキーを設定しよう【CustomTkinterでメモ帳を作ろう】

2026年4月3日金曜日

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

前回はステータスバーもどきを実現しました。
ですがこれでも最低限の機能すらなく、おそらく多くの人はわざわざメニューから「保存」をするのではなく、Ctrl-Sをするのではないでしょうか。
ということで今回はホットキーの実現をします。

同時に今まで「上書き保存」を実装していなかったのでそれも実装します。

Tkinter/CustomTkinterでホットキーを実装する方法

これは非常に簡単です。以下のような感じで、バインドします。

        self.bind("<Control-n>", self.newfile)
        self.bind("<Control-Shift-s>", self.saveas)
        self.bind("<Control-s>", self.onsave)
        self.bind("<Control-o>", self.openfile)
        self.bind("<Control-N>", self.newfile)
        self.bind("<Control-Shift-S>", self.saveas)
        self.bind("<Control-S>", self.onsave)
        self.bind("<Control-O>", self.openfile)

こうみればわかりますが、CapsLockされているとき対策のために大文字でもバインドしなければいけないんですよね...
これはしょうがないです。

追加で実装した機能もふくめて様々な箇所を修正したため、全体のコードを以下に貼り付けます。

import tkinter as tk
from tkinter import filedialog, messagebox
import customtkinter as ctk

class MyFrame(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("メモ帳 - 新規")
        self.geometry("900x600")
        self.nowfile = ""

        self.menubar = tk.Menu(self)
        filemenu = tk.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="新規 (Ctrl+N)", command=self.newfile)
        filemenu.add_command(label="開く... (Ctrl+O)", command=self.openfile)
        filemenu.add_command(label="上書き保存... (Ctrl+S)", command=self.onsave)
        filemenu.add_command(label="名前を付けて保存... (Ctrl+Shift+S)", command=self.saveas)
        filemenu.add_command(label="終了 (Alt+F4)", command=self.quit)
        self.menubar.add_cascade(label="ファイル", menu=filemenu)
        self.config(menu=self.menubar)

        self.bind("<Control-n>", self.newfile)
        self.bind("<Control-Shift-s>", self.saveas)
        self.bind("<Control-s>", self.onsave)
        self.bind("<Control-o>", self.openfile)
        self.bind("<Control-N>", self.newfile)
        self.bind("<Control-Shift-S>", self.saveas)
        self.bind("<Control-S>", self.onsave)
        self.bind("<Control-O>", self.openfile)

        self.sbf = ctk.CTkFrame(self,height=24, corner_radius=0)
        self.sbf.pack(side="bottom", fill="x")
        self.statusbar1 = ctk.CTkLabel(self.sbf, text="1行、0列", anchor="e", padx=10)
        self.statusbar1.pack(side="right")
        self.statusbar2 = ctk.CTkLabel(self.sbf, text="UTF-8", anchor="e", padx=10)
        self.statusbar2.pack(side="right")

        self.textbox = ctk.CTkTextbox(self, wrap="none")
        self.textbox.pack(fill="both", expand=True)

        self.textbox.bind("<KeyRelease>", self.updatestatus)
        self.textbox.bind("<ButtonRelease-1>", self.updatestatus)
    
    def newfile(self, event=None):
        self.textbox.delete("1.0", tk.END)
        self.updatestatus()
        self.nowfile = ""
        self.title("メモ帳 - 新規")
    
    def openfile(self, event=None):
        file = filedialog.askopenfilename()
        if file:
            f = open(file, "r", encoding="utf-8")
            self.textbox.delete("1.0", tk.END)
            self.textbox.insert("1.0", f.read())
            self.updatestatus()
            f.close()
            self.title("メモ帳 - " + file)
            self.nowfile = file
    
    def onsave(self, event=None):
        if self.nowfile == "":
            self.saveas()
        else:
            f = open(self.nowfile, "w", encoding="utf-8")
            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="utf-8")
            f.write(self.textbox.get("1.0", tk.END))
            f.close()
            self.title("メモ帳 - " + file)
            self.nowfile = file
    
    def updatestatus(self, event=None):
        line,col = self.textbox.index(tk.INSERT).split(".")
        self.statusbar1.configure(text=str(line) + "行、"+ str(col) + "列")

if __name__ == "__main__":
    app = MyFrame()
    app.mainloop()

だいぶ長くなりましたが、まだ不十分ですね。次回に続きます。


このブログを検索

要望について

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

最近の出来事

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

Welcome!

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

お問い合わせ

名前

メール *

メッセージ *

QooQ