以下は『ハイライトちゃん』ver.1.4.2のソースコード全文です:
import tkinter as tk
from tkinter import scrolledtext
import unicodedata
class HighlightApp:
def __init__(self, root):
self.root = root
self.root.title("文字ハイライトツール - ハイライトちゃん")
self.highlight_mode = tk.StringVar(value="zenkaku") # デフォルト:全角
self.highlight_color = tk.StringVar(value="yellow") # デフォルト:黄色
# メニュー
menu = tk.Menu(self.root)
settings_menu = tk.Menu(menu, tearoff=0)
# ハイライト種別
settings_menu.add_radiobutton(label="全角をハイライト", variable=self.highlight_mode, value="zenkaku")
settings_menu.add_radiobutton(label="半角をハイライト", variable=self.highlight_mode, value="hankaku")
# 色メニュー
color_menu = tk.Menu(settings_menu, tearoff=0)
color_menu.add_radiobutton(label="黄", variable=self.highlight_color, value="yellow", command=self.update_highlight_color)
color_menu.add_radiobutton(label="赤", variable=self.highlight_color, value="tomato", command=self.update_highlight_color)
color_menu.add_radiobutton(label="青", variable=self.highlight_color, value="lightblue", command=self.update_highlight_color)
settings_menu.add_cascade(label="色", menu=color_menu)
menu.add_cascade(label="設定", menu=settings_menu)
self.root.config(menu=menu)
# Grid拡張設定
self.root.columnconfigure(0, weight=1)
self.root.columnconfigure(1, weight=1)
self.root.rowconfigure(0, weight=1)
# テキストウィンドウ(左:入力)
self.text_input = scrolledtext.ScrolledText(self.root, wrap="word")
self.text_input.grid(row=0, column=0, padx=5, pady=5, sticky="nsew")
# テキストウィンドウ(右:ハイライト)
self.text_highlighted = scrolledtext.ScrolledText(self.root, wrap="word")
self.text_highlighted.grid(row=0, column=1, padx=5, pady=5, sticky="nsew")
# ボタンフレーム
btn_frame = tk.Frame(self.root)
btn_frame.grid(row=1, column=0, columnspan=2, pady=5)
tk.Button(btn_frame, text="表示", command=self.highlight_text).pack()
# ハイライトスタイル設定
self.update_highlight_color()
def update_highlight_color(self):
"""選択された色でハイライトスタイルを更新"""
color = self.highlight_color.get()
self.text_highlighted.tag_configure("highlight", background=color)
def highlight_text(self):
text = self.text_input.get("1.0", tk.END)
self.text_highlighted.delete("1.0", tk.END)
self.text_highlighted.insert("1.0", text)
self.text_highlighted.tag_remove("highlight", "1.0", tk.END)
for idx, char in enumerate(text):
if self.highlight_mode.get() == "zenkaku" and self.is_fullwidth(char):
self.apply_highlight(idx)
elif self.highlight_mode.get() == "hankaku" and self.is_halfwidth(char):
self.apply_highlight(idx)
def apply_highlight(self, idx):
start = f"1.0 + {idx} chars"
end = f"1.0 + {idx+1} chars"
self.text_highlighted.tag_add("highlight", start, end)
def is_fullwidth(self, char):
return unicodedata.east_asian_width(char) in ('F', 'W', 'A')
def is_halfwidth(self, char):
return unicodedata.east_asian_width(char) == 'Na'
if __name__ == "__main__":
root = tk.Tk()
##タイトルバーアイコン表示用
data = '''R0lGODdhEAAQAIYAAAAAAIlpV/Tkz+vax3JVR9nJtraklY14aX9/f5NzW8q4pnlbTKSLfFVVVUs2MP///y8nG/8AADs3Mreki3hoYKaYjmtQQGlVSde6u1VFM1E+N007MsW5pTwzNPXZcjgrJ//44f//qvrZue3Sb+HPvubOtuHImOPFlunNZv+/v97Ru93Bs8S1pMOzoNq+tsivmcCsnLywpb+/v72xn7mqmLCYiayejqWRjrKbV7acW7eeP79/f6pVVZyJhZ2HeZqCTx8fH4NkUoFrK+PWv35za39/P39/AHBlYH9iUn9vSXtqXmZmM35eTnNWR2hPQ2ZMTGFIO2dMP2JLPn8/P38AAFVVAFhLRl1IPk5EOkY3NEAzIUw3Kz8yLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAEAAQAEAI8AABCASAAIAUJkEWWBDYYCCADVywbMnAQsELA0ocCnwAYAESBgYGDDhAgEAHAA0QSKBwIMEABQMKCBgSkgMAjgQBXAnAs2cCJx8KAjAC4AIBHzIHkBBQI8DCJTsA9Bjxo4IAIhqOCBAwAAKACFUgXDjhAYWHHBMmwLDRgsKHKQMLRgmQgGeCBQ6+DiwCoAlPAgwYEAhgEoCEgU8IhAQRs4CBA1lQ6nUAJcCArQICaFiwAQAVHgCE6BDI4YCVA5dpAAgBIAWAGyZwxBBQYMZWFQIqAJBhGICWJBMyGIBZQAGIAkAeOIBQYgUGDC5EaBwYEAA7'''
root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(data=data))
####
root.geometry("900x500")
app = HighlightApp(root)
root.mainloop()