When writing code in Python etc., I often can't think of English words to use for variable names. Until now, I started up a browser and did google translate, but nowadays I feel a little annoying. I made a simple Japanese-English-only translation tool to support myself with no English ability. ↑ The finished product looks like this. We aimed for a tool that can be executed as quickly as possible and with a small number of operations. The essential translation function utilizes the googletrans library. I haven't used it in a new way, so I'll omit the explanation. Reference page ⇒ Python – I tried googletrans.
Windows10 Home Python3.8.2(32bit) Visual Studio Code 1.45.1
from ctypes import windll
from tkinter import Tk,Entry,Label
import tkinter as tk
from googletrans import Translator #External library
import win32gui #External library
import pyperclip #External library
import pyautogui #External library
#Flag of whether it has been converted
translated_flg = False
#Function to turn on IME--------------------------------------------------
def imm_on(event):
hWnd = win32gui.GetForegroundWindow() #Get active window
himc = windll.LoadLibrary("imm32").ImmGetContext(hWnd) #Get context
windll.LoadLibrary("imm32").ImmSetOpenStatus(himc, 1) #Turn on IME in the acquired context
windll.LoadLibrary("imm32").ImmReleaseContext(hWnd, himc) #Free context
#Function that performs translation processing--------------------------------------------------
def translate_jp(japanese):
global translated_flg
#IF for judging continuous processing
if translated_flg == True:
root.destroy() #Finish if already converted
else:
#Translation processing date (ja) ⇒ English (en)
english = Translator().translate(japanese, src="ja", dest="en")
#Change the font and color of the conversion label
translated["font"] = ("segoe UI",14)
translated["foreground"] = "black"
#Update the string (StringVar) in each label
trans_var.set("「 "+english.text.lower()+" 」") #Convert to lowercase
ex_var.set("Press Enter again to exit")
#Copy to clipboard
pyperclip.copy(english.text.lower()) #Convert to lowercase
translated_flg = True
#Function that performs initialization processing--------------------------------------------------
def initialize(event):
global translated_flg
#Update the string (StringVar) in each label
trans_var.set(""The converted Japanese is displayed here."")
ex_var.set("Please enter the Japanese to translate")
#Change the font and color of the conversion label
translated["font"] = ("Meiryo UI",8)
translated["foreground"] = "gray"
#False translated flag
translated_flg = False
#Main processing unit--------------------------------------------------
#tk Preparing to draw a window
root = Tk()
root.geometry("+600+400") #Window drawing position
root.option_add("*font",("Meiryo UI",14))
root.title("Simple translation (Japanese ⇒ English)")
#Prepare the string variable StringVar for tk
ex_var = tk.StringVar()
ex_var.set("Please enter the Japanese to translate")
trans_var = tk.StringVar()
trans_var.set(""The converted Japanese is displayed here."")
#Upper label_1) Drawing
label_1 = Label(root,textvariable=ex_var,font=("Meiryo UI",8))
label_1.pack(pady=10) #Arrangement (top and bottom margins 10px)
#Japanese input Entry (jp_input) drawing
jp_input = Entry(root, width="14")
jp_input.pack(padx=10) #Arrangement (left and right margins 10px) de
jp_input.focus_set() #Specify as the initial position of focus
#Label drawing of the lower label (translated)
translated = Label(root,textvariable=trans_var,font=("Meiryo UI",8))
translated["foreground"] = "gray"
translated.pack(padx=10,pady=10)
# jp_imm when input is drawn_on function execution
jp_input.bind("<Expose>", imm_on)
# jp_Function execution when Enter is pressed on input
#Since bind can only execute callback functions, pass arguments as lambda expressions
jp_input.bind("<Return>", lambda f:translate_jp(jp_input.get()))
# jp_Execute initialize function when some key is pressed in input
jp_input.bind("<Key>",initialize)
#tk window drawing
root.mainloop()
#After the end "Alt"+Switch windows with "Tab" (return to the last active window)
pyautogui.hotkey("Alt","Tab",interval=0.05)
This time, I created a batch file for startup and set a shortcut key so that it can be started in one shot.
Start-up.bat (example)
@echo off
start /min C:\Python\Python38-32\python.exe C:\Users\aaa\Desktop\python\Simple translation tool (Japanese and English).py
(1) Create the above command with Notepad etc. and save it with the extension .bat. (In the above case, 2byte characters are included, so it was necessary to change the character code to ANSI and save it.) (2) Create a shortcut for the created bat file in any location ③ Right-click the shortcut ⇒ "Properties" ⇒ "Shortcut key" on the "Shortcut" tab to set
Feeling like. This makes it possible to start and execute shortcuts for py files with any key.
Also, by typing start / min ~
in the bat file, the console screen is minimized so that the tool can be started.
(Actually I thought to make it an exe, but for some reason the conversion with pyinstaller does not work ...)
Since this tool is a Japanese translation, it is used only when the basic IME is ON (Japanese input mode).
However, the tk window always starts with IME turned off.
Therefore, I have to press the half-width key to switch IME, which is a little troublesome.
So, I tried to turn on IME automatically ** at the same time as starting the tool.
First, specify .focus_set ()
for the Entry widget created by tkinter. Input is possible at the same time as startup.
Furthermore, when the event sequence of bind is specified as <Expose>
and the widget is drawn.
Changed to execute a function that automatically turns on IME when the window is launched (that is, when the window is launched).
The code to turn on IME is as follows.
hWnd = win32gui.GetForegroundWindow() #Get active window
himc = windll.LoadLibrary("imm32").ImmGetContext(hWnd) #Get context
windll.LoadLibrary("imm32").ImmSetOpenStatus(himc, 1) #Turn on IME in the acquired context
windll.LoadLibrary("imm32").ImmReleaseContext(hWnd, himc) #Free context
(Although I still have a poor understanding of windll, I was able to turn on IME above for the time being)
The tool's exit operation is also simple, and it is possible to exit with just the ** Enter key **.
(I wanted to avoid quitting with a button because it causes extra mouse movement)
First, when Enter (Return) is pressed, set the judgment flag translated_flg to True and set it to True.
If Enter is pressed further in that state, the termination process root.destroy ()
will be performed.
In addition, when the contents of the widget are updated by BackSpace etc., the flag will be initialized.
After exiting, the window that was active at startup has lost focus. To return to the original window
With pyautogui.hotkey ("Alt", "Tab", interval = 0.05)
, the Windows shortcut key" Alt "+" Tab "is pressed, and
** Automatically perform active switching to the window you were working on **.
However, this method only uses the specification that the window switching by the shortcut returns to the one that was active immediately before, and it may not work depending on the environment.
(If anyone knows a good way, please let me know)
In addition, the last translated result is copied to the clipboard at the end. After transitioning to the original window, the translation result can be pasted with just Ctrl + V.
At first, I was planning to do something simple as a practice of making tools, but on the way I made some changes and made some changes. It took a lot of time and effort. .. (I learned a lot from that) The reflection is that, as I wrote in the text, I couldn't make it into an exe by Pyinstaller for some reason, so I used bat. Perhaps because of that, the impression that it took a while to start the tool. .. I would like to investigate this area when I have time.
This is the first time I tried to create a GUI with tkinter, but the following sites were very helpful. ⇒ Introduction to Easy Python / Tkinter While there were few sites that could be helpful for event sequences, the following sites were useful. ⇒ Tkinter bind and event sequence