TkEasyGUIでクリップボード監視リアルタイム翻訳ツールを作る
Pythonで最も簡単にGUIアプリが作れる`TkEasyGUI`を使って、以下のようなクリップボード監視型のリアルタイム翻訳ツールを作ってみます。
前回紹介した、完全ローカル翻訳できる`Argos Translate`を使って、クリップボードが書き換わると自動で翻訳するツールをPythonで作ってみました。
必要となるPythonパッケージのインストール
GUIアプリのために、`TkEasyGUI。ローカル翻訳のために、`argostranslate`をインストールします。ターミナル(WindowsならPowerShell、macOSならターミナル.app)を起動して、次のコマンドを実行しましょう。
python -m pip install TkEasyGUI argostranslate
次に、Argos Translateの日英翻訳、英日翻訳のモデルをダウンロードします。
argospm install translate-ja_en
argospm install translate-en_ja
クリップボード監視ツールを作る
そして、さっそく監視ツールを作ります。以下がクリップボードを監視して、逐次ローカル翻訳する機能を実装したツールのプログラムです。`translate_easy.py`などの名前で保存します。
import subprocess
from queue import Queue
from threading import Thread
import TkEasyGUI as eg
# スレッドを使うので矛盾が起きないようキューを用意
ui_queue = Queue()
def main():
# 開始時点のクリップボードを確認
clip = eg.get_clipboard()
# 画面レイアウトを作成
layout = [
[eg.Multiline("", key="input", enable_events=True, size=(60, 10))],
[eg.Radio("英日翻訳", key="-ej-", default=True), eg.Radio("日英翻訳", key="-je-")],
[eg.Multiline("", key="output", readonly=True, size=(60, 10))],
]
# ウィンドウを作成
with eg.Window(
"クリップボード監視して翻訳",
layout,
keep_on_top=True,
resizable=True,
) as window:
# イベントループ
for event, values in window.event_iter(timeout=100, timeout_key="-timeout-"):
# 手動で書き換わったら翻訳実行
if event == "input":
translate(window)
continue
if event == "-timeout-":
# check ui_queue
if not ui_queue.empty():
window["output"].update(ui_queue.get())
continue
# クリップボードが書き換わったか?
clip_new = eg.get_clipboard()
if clip_new == clip:
continue
clip = clip_new
window["input"].update(clip)
translate(window)
# 翻訳実行(スレッドを起動)
def translate(win):
ej = win["-ej-"].get()
in_str = win["input"].get_text()
Thread(target=translate_job, args=(in_str, ej)).start()
def translate_job(in_str: str, ej:bool):
if ej:
cmd = ["argos-translate", "--from", "en", "--to", "ja", in_str]
else:
cmd = ["argos-translate", "--from", "ja", "--to", "en", in_str]
try:
res = subprocess.run(cmd, capture_output=True, encoding="utf-8")
result = res.stdout
ui_queue.put(result)
except Exception as e:
print(e)
if __name__ == "__main__":
main()
プログラムを実行するには、以下のコマンドを実行します。
python translate_easy.py
プログラムのポイント
このプログラムのポイントは以下の部分です。以下は、ウィンドウにMultiline(複数行入力ボックス)を二つとRadio(ラジオボタン)を二つ作成するものです。
〜抜粋〜
layout = [
[eg.Multiline("", key="input", enable_events=True, size=(60, 10))],
[eg.Radio("英日翻訳", key="-ej-", default=True), eg.Radio("日英翻訳", key="-je-")],
[eg.Multiline("", key="output", readonly=True, size=(60, 10))],
]
# ウィンドウを作成
with eg.Window(
"クリップボード監視して翻訳",
layout,
keep_on_top=True,
resizable=True,
) as window:
# イベントループ
for event, values in window.event_iter(timeout=100, timeout_key="-timeout-"):
〜抜粋〜
クリップボード監視翻訳ツールの使い勝手をよくするために、ウィンドウを常に最前面に表示するために、keep_on_top=Trueを指定しているのもポイントです。
また、長文を与えると、Argos Translateからの応答が遅い時があるので、下記のように、スレッドを利用して、実行が終わった時点で、実行結果を更新するようにしています。
# 翻訳実行(スレッドを起動)
def translate(win):
ej = win["-ej-"].get()
in_str = win["input"].get_text()
Thread(target=translate_job, args=(in_str, ej)).start()
# スレッドでArgos Translateを実行
def translate_job(in_str: str, ej:bool):
if ej:
cmd = ["argos-translate", "--from", "en", "--to", "ja", in_str]
else:
cmd = ["argos-translate", "--from", "ja", "--to", "en", in_str]
try:
res = subprocess.run(cmd, capture_output=True, encoding="utf-8")
result = res.stdout
ui_queue.put(result)
except Exception as e:
print(e)
# まとめ
わずか60行ちょっとのプログラムで、翻訳ツールが作れてしまうのですから、良い時代になりました。
実際、使い込んでいくと、Argos Translateの翻訳がかなり適当な時があるのですが、知らない単語の周辺を翻訳するようにして、なるだけ原文を読む習慣をつける練習になるのかもしれません。あるいは、翻訳機能の部分をオンライン翻訳のAPIに置き換えるなどすると、より実用的になるかもです。
参考にしてみてください!
# 本書きました!(2024年7月)
TkEasyGUIとPySimpleGUIに関する書籍「Pythonでつくるデスクトップアプリ」を書きました✨ 良かったら見てみてください↓↓↓