使用虚拟事件的翻译感知小部件
Translation aware widgets using virtual events
我有一个多语言 Tkinter 应用程序。由于 Tkinter 本身不公开 Tk 的底层 msgcat
功能,因此我使用 ttkbootstrap
。截至目前,我的翻译工作正常,当通过界面更改语言时,我会销毁并重建所有小部件。
虚拟事件是 Tkinter 的一个强大功能,它允许我 structure my application in an OO way 同时使用控制变量和虚拟事件的组合进行小部件间通信/消息传递。
我试图通过这段代码实现一个翻译感知小部件,但我现在知道,虚拟事件需要小部件焦点,但事实并非如此:
from ttkbootstrap import ttk
from ttkbootstrap.localization import MessageCatalog
def _tr(t: str) -> str:
return MessageCatalog.translate(t)
class TrButton(ttk.Button):
def __init__(self, master=None, text: str = "", **kwargs):
super().__init__(master=master, text=_tr(text), **kwargs)
self.bind(
"<<LanguageChanged>>", lambda *_: self.configure(text=_tr(self["text"]))
)
现在,重建所有小部件对我的应用程序来说并不是一项非常昂贵的任务,但我想知道是否有更好的方法?一种拥有真正翻译感知小部件的方法?
您写道虚拟事件需要小部件焦点,但事实并非如此。您是否在 Internet 上找到一些说明这是真的文档?
最简单的解决方案是让您的 class 跟踪自己的实例。然后您可以遍历所有实例以生成虚拟事件。
看起来像这样:
class TrButton(ttk.Button):
instances = []
def __init__(self, master=None, text: str = "", **kwargs):
TrButton.instances.append(weakref.proxy(self))
super().__init__(master=master, text=_tr(text), **kwargs)
self.bind(
"<<LanguageChanged>>", lambda *_: self.configure(text=_tr(self["text"]))
)
@classmethod
def language_changed(self):
for widget in TrButton.instances:
if widget.winfo_exists():
widget.event_generate("<<LanguageChanged>>")
只要语言发生变化,您就可以调用 TrButton.language_changed()
将事件发送到 class 的每个实例。
这段代码并不完美,应该有一种机制可以从实例列表中删除已删除的小部件。但是,它说明了如何遍历小部件列表以向它们发送虚拟事件,而无需它们具有焦点。
我有一个多语言 Tkinter 应用程序。由于 Tkinter 本身不公开 Tk 的底层 msgcat
功能,因此我使用 ttkbootstrap
。截至目前,我的翻译工作正常,当通过界面更改语言时,我会销毁并重建所有小部件。
虚拟事件是 Tkinter 的一个强大功能,它允许我 structure my application in an OO way 同时使用控制变量和虚拟事件的组合进行小部件间通信/消息传递。
我试图通过这段代码实现一个翻译感知小部件,但我现在知道,虚拟事件需要小部件焦点,但事实并非如此:
from ttkbootstrap import ttk
from ttkbootstrap.localization import MessageCatalog
def _tr(t: str) -> str:
return MessageCatalog.translate(t)
class TrButton(ttk.Button):
def __init__(self, master=None, text: str = "", **kwargs):
super().__init__(master=master, text=_tr(text), **kwargs)
self.bind(
"<<LanguageChanged>>", lambda *_: self.configure(text=_tr(self["text"]))
)
现在,重建所有小部件对我的应用程序来说并不是一项非常昂贵的任务,但我想知道是否有更好的方法?一种拥有真正翻译感知小部件的方法?
您写道虚拟事件需要小部件焦点,但事实并非如此。您是否在 Internet 上找到一些说明这是真的文档?
最简单的解决方案是让您的 class 跟踪自己的实例。然后您可以遍历所有实例以生成虚拟事件。
看起来像这样:
class TrButton(ttk.Button):
instances = []
def __init__(self, master=None, text: str = "", **kwargs):
TrButton.instances.append(weakref.proxy(self))
super().__init__(master=master, text=_tr(text), **kwargs)
self.bind(
"<<LanguageChanged>>", lambda *_: self.configure(text=_tr(self["text"]))
)
@classmethod
def language_changed(self):
for widget in TrButton.instances:
if widget.winfo_exists():
widget.event_generate("<<LanguageChanged>>")
只要语言发生变化,您就可以调用 TrButton.language_changed()
将事件发送到 class 的每个实例。
这段代码并不完美,应该有一种机制可以从实例列表中删除已删除的小部件。但是,它说明了如何遍历小部件列表以向它们发送虚拟事件,而无需它们具有焦点。