Hello!
I’m a college student who wants to be a Python engineer, attending a Korean university.
Working on the project, and I came here because there was a problem with themed tkinter.
There is a problem with the Korean IME in the ttk.Entry object.
Hangul(Korean) creates words from a combination of letters(initial, medial, finale).
I’d like to dynamically print those letters with get() method whenever I type that letters into ttk.Entry
But only when ttk.Entry enters one completed letter, the letter is printed.
Desired example)
input ㅎ >>> print console: ㅎ
input ㅏ >>> print console: 하
input ㄴ >>> print console: 한
Actual action)
input ㅎ >>> print console:
input ㅏ >>> print console:
input ㄴ >>> print console:
input whitespce >>> print console: 한
To look up that using event(type: QInputMethodEvent) in the QLineEdit of PyQt5 with event.preeditString(), the action I want will be implemented!
However, I understand that tkinter and PyQt5 are difficult to mix using, because of different event loops.
I’m already been working on the project quite a bit, so hard to change the entire code to PyQt5.
I would like to implement such as preeditString() only in certain parts…
What are the options? Only way to change all code…?
widgets.py
class Entry(ttk.Entry):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bind("<Control-a>", self.select_all)
def select_all(self, event):
event.widget.select_range(0, "end")
event.widget.icursor("end")
return "break"
class DebounceEntry(Entry):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.bind("<Key>", self._on_key)
self._on_key_func = None
self._after_id = None
self._debounce_ms = 200
def _on_key(self, event=None):
if self._on_key_func is None:
return
if self._after_id is not None:
self.after_cancel(self._after_id)
self._after_id = self.after(self._debounce_ms, self._on_key_func, event)
def bind_on_key(self, func, debounce_ms=None):
self._on_key_func = func
if debounce_ms is not None:
self._debounce_ms = debounce_ms
filters.py
import logging
import tkinter as tk
from tkinter import ttk
from playground.ui.widgets import DebounceEntry
from playground.korean_regexp.functions import (
get_reg_exp as re_korean, eng_to_kor, kor_to_eng
)
logger = logging.getLogger(__name__)
class FiltersFrame(ttk.LabelFrame):
def __init__(self, parent, play_tab, function_callback=None):
logger.debug("Initailizing Playground FiltersFrame")
super().__init__(parent, text="Filters")
self.parent = parent
self.play_tab = play_tab
self.function_callback = function_callback
self.name_label = ttk.Label(self, text="Course Name:")
self.name_label.grid(row=0, column=0, padx=(5, 0), pady=(5, 5), sticky="w")
# Using here!
self.name = DebounceEntry(self, width="30")
self.name_last_seen = ""
self.name.bind_on_key(self.on_name_key)
self.name.grid(row=0, column=1, padx=(5, 0), pady=(5, 5), sticky="w")
self.name.bind("<KeyRelease>", self.IME_test)
def selected_command(self, _event=None):
self.play_tab.packs_frame.render_packs()
def on_name_key(self, _event=None):
name = self.name.get().strip()
if name != self.name_last_seen:
self.name_last_seen = name
self.play_tab.packs_frame.render_packs()
def IME_test(self, event):
search_term = self.name.get()
print(search_term)