PyQt6应用程序中,如何实现多种语言支持

在 PyQt6 中实现支持多种语言(国际化,简称 i18n)通常有两种方式:1. 可以通过使用 Qt 的 QTranslator 类来完成;2. 自定义字典来管理

1. 使用 Qt 的 QTranslator

1. 准备多语言资源文件

你需要创建一个翻译文件,以便将应用程序的文本翻译成不同的语言。

1.1 创建 .ts 文件

首先,你需要使用 Qt 的 lupdate 工具从 Python 代码中提取所有可翻译的字符串,并将它们存储到 .ts 文件中。

例如,你可以使用如下方法从 .py 文件中提取翻译内容:

lupdate your_app.py -ts translations/your_app_zh_CN.ts

这将生成一个包含所有可翻译文本的 .ts 文件。然后,你可以打开 .ts 文件并为每个文本项提供翻译。

1.2 编辑 .ts 文件

.ts 文件中,编辑 <translation> 元素以提供翻译。例如:

<context><name>MainWindow</name><message><source>Hello, World!</source><translation>你好,世界!</translation></message>
</context>
1.3 编译 .ts 文件为 .qm 文件

使用 lrelease 工具将 .ts 文件编译成 .qm 文件,这是运行时加载的翻译文件。

lrelease translations/your_app_zh_CN.ts

这将生成一个 your_app_zh_CN.qm 文件。

2. 在 PyQt6 应用中加载翻译文件

一旦你有了 .qm 文件,你就可以在 PyQt6 中加载它们并应用翻译。

2.1 导入相关模块
from PyQt6.QtCore import QCoreApplication, QTranslator, QLocale
from PyQt6.QtWidgets import QApplication, QMainWindow
2.2 设置翻译器

在应用程序的启动过程中,创建并加载翻译器。

class MyApp(QApplication):def __init__(self, argv):super().__init__(argv)# 创建翻译器self.translator = QTranslator()# 加载合适的语言翻译文件locale = QLocale.system().name()  # 获取系统的当前语言translation_file = f"translations/your_app_{locale}.qm"if self.translator.load(translation_file):# 如果加载成功,安装翻译器self.installTranslator(self.translator)# 启动界面self.main_window = QMainWindow()self.main_window.show()app = MyApp([])
app.exec()

3. 使用 QObject.tr() 进行文本翻译

你需要将所有的可翻译文本包装在 QObject.tr() 方法中。这是让 Qt 能够识别并翻译字符串的关键步骤。

from PyQt6.QtWidgets import QLabel, QMainWindowclass MainWindow(QMainWindow):def __init__(self):super().__init__()label = QLabel(self)label.setText(self.tr("Hello, World!"))  # 可翻译文本label.move(100, 100)label.resize(200, 50)self.setWindowTitle(self.tr("Main Window"))

在这个例子中,self.tr("Hello, World!") 会自动被翻译成当前语言。

4. 切换语言

你可以在程序中动态切换语言。为了支持语言切换,可以实现一个方法重新加载不同的 .qm 文件并更新界面。

def switch_language(self, language_code):# 创建新的翻译器translator = QTranslator()translation_file = f"translations/your_app_{language_code}.qm"if translator.load(translation_file):self.installTranslator(translator)# 更新界面文本self.retranslateUi()

retranslateUi() 方法中,你可以刷新界面上的所有文本,以便根据新语言重新加载。

5. 处理动态文本(例如按钮、菜单等)

除了 QLabel 之外,其他界面元素(如按钮、菜单等)也需要通过 tr() 方法进行翻译。

from PyQt6.QtWidgets import QPushButton, QVBoxLayout, QWidgetclass MainWindow(QMainWindow):def __init__(self):super().__init__()layout = QVBoxLayout()button = QPushButton(self.tr("Click me"))layout.addWidget(button)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.tr("Main Window"))

6. 完整示例代码

from PyQt6.QtCore import QCoreApplication, QTranslator, QLocale
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidgetclass MyApp(QApplication):def __init__(self, argv):super().__init__(argv)# 创建翻译器self.translator = QTranslator()# 加载合适的语言翻译文件locale = QLocale.system().name()  # 获取系统的当前语言translation_file = f"translations/your_app_{locale}.qm"if self.translator.load(translation_file):# 如果加载成功,安装翻译器self.installTranslator(self.translator)# 创建主窗口self.main_window = MainWindow()self.main_window.show()class MainWindow(QMainWindow):def __init__(self):super().__init__()layout = QVBoxLayout()button = QPushButton(self.tr("Click me"))layout.addWidget(button)label = QLabel(self.tr("Hello, World!"))layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.tr("Main Window"))# 切换语言按钮switch_button = QPushButton(self.tr("Switch Language"))layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 选择另一种语言,例如切换到中文language_code = "zh_CN"  # 或者根据需要选择其他语言self.retranslateUi(language_code)def retranslateUi(self, language_code):# 重新加载语言文件并更新界面translator = QTranslator()translation_file = f"translations/your_app_{language_code}.qm"if translator.load(translation_file):self.installTranslator(translator)self.setWindowTitle(self.tr("Main Window"))self.centralWidget().children()[1].setText(self.tr("Hello, World!"))self.centralWidget().children()[2].setText(self.tr("Click me"))self.centralWidget().children()[3].setText(self.tr("Switch Language"))if __name__ == '__main__':app = MyApp([])app.exec()

总结

  • QTranslator 用于加载翻译文件。
  • 使用 tr() 方法包装所有要翻译的文本。
  • 通过 lupdatelrelease 工具生成 .ts.qm 文件,并在运行时加载它们。
  • 可以动态切换语言,并刷新界面文本。

2. 自定义字典来管理

除了使用 Qt 提供的 QTranslator.ts 文件来进行国际化,完全可以通过手动管理一个字典来实现多语言支持。这种方法适合简单的应用,尤其是在没有大量文本内容需要翻译的情况下。通过字典匹配不同的语言,你可以实现对 UI 元素的文本翻译。

如何用字典实现多语言支持

假设你想要支持两种语言:英语和中文,可以按以下步骤实现:

1. 创建语言字典

首先,你需要为每种语言定义一个字典,字典的键是文本的标识符,值是对应语言的翻译。

英文字典(en_dict
en_dict = {"greeting": "Hello, World!","click_button": "Click me","window_title": "Main Window","switch_language": "Switch Language",
}
中文字典(zh_dict
zh_dict = {"greeting": "你好,世界!","click_button": "点击我","window_title": "主窗口","switch_language": "切换语言",
}

2. 选择语言并使用字典

在程序中,你可以根据选择的语言切换字典的内容,并使用这些字典来设置 UI 元素的文本。

class MainWindow(QMainWindow):def __init__(self, language_dict):super().__init__()# 保存当前语言的字典self.language_dict = language_dictlayout = QVBoxLayout()# 使用字典翻译文本button = QPushButton(self.language_dict["click_button"])layout.addWidget(button)label = QLabel(self.language_dict["greeting"])layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.language_dict["window_title"])# 切换语言按钮switch_button = QPushButton(self.language_dict["switch_language"])layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 切换语言if self.language_dict == en_dict:self.language_dict = zh_dictelse:self.language_dict = en_dict# 更新界面上的文本self.retranslateUi()def retranslateUi(self):self.setWindowTitle(self.language_dict["window_title"])self.centralWidget().children()[1].setText(self.language_dict["greeting"])self.centralWidget().children()[2].setText(self.language_dict["click_button"])self.centralWidget().children()[3].setText(self.language_dict["switch_language"])

3. 在 QApplication 中选择默认语言

if __name__ == '__main__':# 默认为英语app = QApplication([])window = MainWindow(en_dict)window.show()app.exec()

4. 完整示例代码

from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget# 定义语言字典
en_dict = {"greeting": "Hello, World!","click_button": "Click me","window_title": "Main Window","switch_language": "Switch Language",
}zh_dict = {"greeting": "你好,世界!","click_button": "点击我","window_title": "主窗口","switch_language": "切换语言",
}class MainWindow(QMainWindow):def __init__(self, language_dict):super().__init__()# 保存当前语言的字典self.language_dict = language_dictlayout = QVBoxLayout()# 使用字典翻译文本button = QPushButton(self.language_dict["click_button"])layout.addWidget(button)label = QLabel(self.language_dict["greeting"])layout.addWidget(label)container = QWidget()container.setLayout(layout)self.setCentralWidget(container)self.setWindowTitle(self.language_dict["window_title"])# 切换语言按钮switch_button = QPushButton(self.language_dict["switch_language"])layout.addWidget(switch_button)switch_button.clicked.connect(self.switch_language)def switch_language(self):# 切换语言if self.language_dict == en_dict:self.language_dict = zh_dictelse:self.language_dict = en_dict# 更新界面上的文本self.retranslateUi()def retranslateUi(self):self.setWindowTitle(self.language_dict["window_title"])self.centralWidget().children()[1].setText(self.language_dict["greeting"])self.centralWidget().children()[2].setText(self.language_dict["click_button"])self.centralWidget().children()[3].setText(self.language_dict["switch_language"])if __name__ == '__main__':# 默认为英语app = QApplication([])window = MainWindow(en_dict)window.show()app.exec()

优点和缺点

优点:
  • 简单快捷:如果你的应用程序不需要复杂的翻译工作,使用字典的方式是非常直接的。
  • 灵活性高:可以随时根据需求修改翻译内容。
缺点:
  • 扩展性差:如果应用程序的文本量增加,管理多个字典会变得不易维护。
  • 无法支持标准的国际化工具:比如翻译工具和 .ts 文件生成等,这些都是 Qt 提供的标准方法,方便与其他语言开发者合作。

适用场景

  • 小型应用程序,翻译的文本量较少。
  • 没有复杂的翻译管理需求。
  • 希望手动控制翻译内容的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10439.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第554题砖墙

题目&#xff1a; 题解&#xff1a; func leastBricks(wall [][]int) int {cnt : map[int]int{}for _, widths : range wall {sum : 0for _, width : range widths[:len(widths)-1] {sum widthcnt[sum]}}maxCnt : 0for _, c : range cnt {if c > maxCnt {maxCnt c}}retur…

斯坦福泡茶机器人DexCap源码解析:涵盖收集数据、处理数据、模型训练三大阶段

前言 因为我司「七月在线」关于dexcap的复现/优化接近尾声了&#xff0c;故准备把dexcap的源码也分析下。​下周则分析下iDP3的源码——为队伍「iDP3人形的复现/优化」助力 最开始&#xff0c;dexcap的源码分析属于此文《DexCap——斯坦福李飞飞团队泡茶机器人&#xff1a;带…

高中数学:概率-随机实验、样本空间、随机事件

文章目录 一、随机实验二、样本空间三、随机事件例题 四、事件运算 一、随机实验 二、样本空间 三、随机事件 例如 样本空间 Ω { a , b , c , d , e , f } 则&#xff0c;事件 A { a , b , c } &#xff0c;是一个随机事件 事件 B { d } 是一个基本事件 样本空间Ω\{a,b,c…

w~大模型~合集21

我自己的原文哦~ https://blog.51cto.com/whaosoft/12459590 #大模型~微调~用带反馈的自训练 面对当前微调大模型主要依赖人类生成数据的普遍做法&#xff0c;谷歌 DeepMind 探索出了一种减少这种依赖的更高效方法。大模型微调非得依赖人类数据吗&#xff1f;用带反馈的自训…

利用 Vue.js 开发动态组件的实战指南

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; Vue.js 是现代 Web 开发中非常流行的框架&#xff0c;以其渐进式架构和组件化设计受到广泛欢迎。组件化开发是 Vue.js 的核心优势…

Jmeter中的配置原件(一)

配置原件 1--CSV Data Set Config 用途 参数化测试&#xff1a;从CSV文件中读取数据&#xff0c;为每个请求提供不同的参数值。数据驱动测试&#xff1a;使用外部数据文件来驱动测试&#xff0c;使测试更加灵活和可扩展。 配置步骤 准备CSV文件 创建一个CSV文件&#xff0c…

MCU的OTA升级(未完-持续更新)

1.术语 ISP : In-System Programming 在系统编程&#xff0c;是一种通过MCU&#xff08;微控制器单元&#xff09;上的内置引导程序&#xff08;BootLoader&#xff09;来实现对芯片内部存储器&#xff08;如Flash&#xff09;进行编程的技术。 华大目前对应的ISP IAP&…

让redis一直开启服务/自动启动

文章目录 你的redis是怎么打开的黑窗不能关?必须要自动启动吗?再说说mysql 本文的所有指令都建议在管理员权限下打开cmd控制台 推荐的以管理员身份打开控制台的方式 Win R 打开运行 输入cmdShift Ctrl Enter 你的redis是怎么打开的 安装过redis的朋友都知道, redis的安…

从认识 VNode VDOM 到实现 mini-vue

前言 现有框架几乎都引入了虚拟 DOM 来对真实 DOM 进行抽象&#xff0c;也就是现在大家所熟知的 VNode 和 VDOM&#xff0c;那么为什么需要引入虚拟 DOM 呢&#xff1f;下面就一起来了解下吧&#xff01;&#xff01;&#xff01; VNode & VDOM VNode 和 VDOM 是什么&am…

vue项目实战

1.项目文件夹添加&#xff08;结构如下&#xff09; 2.页面构建 安装路由 npm install react-router-dom 3.页面基本模板 router文件夹下index.js的模板 // 引入组件 import Login from "../views/login"; // 注册路由数组 const routes [{// 首页默认是/path: …

SD-WAN跨境加速专线:打造无缝、高效的全球社交媒体营销网络

在数字化时代&#xff0c;电子商务与社交媒体的融合已成为不可逆转的趋势。亚马逊&#xff0c;作为全球领先的电子商务平台&#xff0c;近期与Facebook、Instagram、Snapchat、Pinterest和TikTok等社交媒体巨头携手&#xff0c;推出了一项革命性的无缝购物体验。这一创新举措不…

yelp商家数据集上使用火算法求解TSP 问题

先简要回顾下什么是TSP问题&#xff0c; 旅行商问题&#xff08;Traveling Salesman Problem&#xff0c;TSP&#xff09;是一个经典的组合优化问题&#xff0c;广泛应用于运筹学、计算机科学和物流等领域。TSP的基本描述如下&#xff1a; 问题描述 定义&#xff1a;假设有一…

【深度学习目标检测|YOLO算法1】YOLO家族进化史:从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析...

【深度学习目标检测|YOLO算法1】YOLO家族进化史&#xff1a;从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析… 【深度学习目标检测|YOLO算法1】YOLO家族进化史&#xff1a;从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析… 文章目录 【深度学习目标检测|YOL…

星期-时间范围选择器 滑动选择时间 最小粒度 vue3

星期-时间范围选择器 功能介绍属性说明事件说明实现代码使用范例 根据业务需要&#xff0c;实现了一个可选择时间范围的周视图。用户可以通过鼠标拖动来选择时间段&#xff0c;并且可以通过快速选择组件来快速选择特定的时间范围。 功能介绍 时间范围选择&#xff1a;用户可以…

Java | Leetcode Java题解之第554题砖墙

题目&#xff1a; 题解&#xff1a; class Solution {public int leastBricks(List<List<Integer>> wall) {Map<Integer, Integer> cnt new HashMap<Integer, Integer>();for (List<Integer> widths : wall) {int n widths.size();int sum 0…

牛客小白月赛104 —— C.小红打怪

C.小红打怪 1.题目&#xff1a; 2.样例 输入 5 1 2 3 4 5 输出 2 说明 第一回合&#xff0c;小红攻击全体怪物&#xff0c;队友1攻击5号怪物&#xff0c;队友2攻击4号和5号怪物&#xff0c;剩余每只怪物血量为[0,1,2,2,2]。 第二回合&#xff0c;小红攻击全体怪物&#…

python画图|text()和dict()初探

【1】引言 在进行hist()函数的学习进程中&#xff0c;了解到了subplot_mosaic()函数&#xff0c;在学习subplot_mosaic()函数的时候&#xff0c;又发现了text()和dict()函数。 经探究&#xff0c;text()和dict()函数有很多一起使用的场景&#xff0c;为此&#xff0c;我们就一…

BUG: scheduling while atomic

▌▌上篇文章的内容还没有结束 中断处理函数中如果执行了调度&#xff0c;会发生什么 ▌这次&#xff0c;我修改了程序&#xff0c;在中断处理函数中调用了msleep 程序执行后&#xff0c;会有这样的日志 ▌关键就是这句 BUG: scheduling while atomic 我们追代码&#xff0c;可…

算法 -选择排序

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【算法】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 文章目录 &#x1f4a1;选择排序1. &#x1f504; 选择排序&#x1f5bc;️示意图&#x1f4d6;简介&#x1f4a1;实现思路1&#x1f4bb;代码实现1&#x1f4a1;实现思路2…

ubuntu 22.04 镜像源更换

双11抢了个云服务器&#xff0c;想要整点东西玩玩&#xff0c;没想到刚上来就不太顺利 使用sudo apt update更新软件&#xff0c;然后发生了如下报错 W: Failed to fetch http://mirrors.jdcloudcs.com/ubuntu/dists/jammy/InRelease 理所当然想到可能是镜像源连接不是很好&…