I finished writing the translator program using Python and Tkinter. I used automatic translation, without a button, and because of this, the application slows down a lot. Is there any way to optimize or speed up the translation process? If you have any advice, I'll be glad to listen, but I'm new to Python. And I'm also interested in the question, is it possible to change the text inside the combobox?
/main
from languages import lang, lang_to_translate
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from googletrans import Translator
def defocus(event):
event.widget.master.focus_set()
def get_choice1(event):
global choice_language1
choice_language1 = language_selection1.get()
def get_choice2(event):
global choice_language2
choice_language2 = language_selection2.get()
dest = lang.index(choice_language2)
global language_abbreviation
language_abbreviation = lang_to_translate[dest]
print(language_abbreviation)
def ex_button():
c1 = language_selection1.get()
c2 = language_selection2.get()
label1.configure(text=c1)
label2.configure(text=c2)
language_selection1.set(c2)
language_selection2.set(c1)
get_choice1('event')
def do_translation(event):
choice_language1 = language_selection1.get()
choice_language2 = language_selection2.get()
text = text1.get("1.0", END).strip()
translator = Translator()
translated_text = translator.translate(text, dest=f'{language_abbreviation}')
text2.delete("1.0", END)
text2.insert(END, translated_text.text)
root = Tk()
app_width = 800
app_height = 500
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
root.title('Переводчик')
root['bg'] = '#1D1B26'
root.geometry(f'{app_width}x{app_height} {int(x)} {int(y)}')
root.resizable(width=False, height=False)
language_selection1 = ttk.Combobox(root, values = lang, font='Comfortaa 10', )
language_selection1.current(1)
language_selection1.place(relx=0.16,y=50)
language_selection1.bind('<<ComboboxSelected>>', get_choice1)
language_selection1.bind('<FocusIn>', defocus)
label1 = Label(root)
exchange_button = PhotoImage(file='transfer.png')
img_label = Label(image=exchange_button)
exchange_button = exchange_button.subsample(18,18)
exchange_button1 = Button(root, image=exchange_button,background='#2ee59d',borderwidth=0, command=ex_button)
exchange_button1.place(relx=0.49,y=50)
language_selection2 = ttk.Combobox(root, values = lang, font='Comfortaa 10', )
language_selection2.set('Выберите язык')
language_selection2.place(relx=0.66,y=50)
language_selection2.bind('<<ComboboxSelected>>', get_choice2)
language_selection2.bind('<FocusIn>', defocus)
first_frame = Frame(root, bg='Black')
first_frame.place(x=41, y=100,width= 250, height=200) #127
text1 = Text(first_frame, bg = 'White')
text1.bind('<Any-KeyRelease>', do_translation)
text1.place(x=0,y=0,width= 250, height=200)
label2 = Label(root)
second_frame = Frame(root, bg='Black')
second_frame.place(x=528, y=100,width= 250, height=200) #441
text2 = Text(second_frame, bg = 'White')
text2.place(x=0,y=0,width= 250, height=200)
root.mainloop()
/languages
lang = ['Belarusian',
'English',
'German',
'Italian',
'Japanese',
'Kazakh',
'Kyrgyz',
'Norwegian',
'Polish',
'Russian',
'Spanish',
'Swedish',
'Turkish',
'Ukrainian', ]
lang_to_translate =['be',
'en',
'de',
'it',
'ja',
'kk',
'ky',
'no',
'pl',
'ru',
'es',
'sv',
'tr',
'uk', ]
CodePudding user response:
Is there any way to optimize or speed up the translation process?
You shouldn't be attempting to do the translation every time the user presses a key. Since the translation takes more than a couple hundred milliseconds, you should wait until the user has stopped typing so that you're not forcing a pause between every character.
You can use tkinter's after
method to schedule the translation to happen in the future. With each key release you can cancel and reschedule the translation. If the user stops typing for a second or two, the translation will happen.
I can't run your code, but here's a brief illustration of the technique:
import tkinter as tk
import googletrans
after_id = None
translator = googletrans.Translator()
def do_translation():
source = input_text.get("1.0", "end").strip()
translated = translator.translate(source, dest="it")
output_text.delete("1.0", "end")
output_text.insert("end", translated.text)
def schedule_translation(event):
global after_id
if after_id is not None:
event.widget.after_cancel(after_id)
after_id = event.widget.after(1000, do_translation)
root = tk.Tk()
input_text = tk.Text(root)
output_text = tk.Text(root)
input_text.pack(side="left", fill="both", expand=True)
output_text.pack(side="left", fill="both", expand=True)
input_text.bind("<Any-KeyRelease>", schedule_translation)
root.mainloop()
For a more robust solution you can do the translation in a separate thread or process, but multithreading and multiprocessing adds a lot of complexity.