【PySide6】单Python文件嵌入语言文件和UI文件,支持切换界面语言

查看 21|回复 3
作者:PythonPan   
今天写教程的时候,灵光一现,写出这么一个综合多个知识点的示例代码,感觉很有启发性,所以分享出来。
示例代码基于嵌入语言文件和UI文件的示例修改,额外实现了系统参数`--lang`,并使用该系统参数加载指定语言文件。此外,还添加了一个双语版本的询问对话框,允许用户后悔重启程序,并实现了基于选择重启程序、传入指定系统参数的代码。主窗口添加了与系统参数相关的两个按钮。
对PySide6有一定兴趣且有一定基础的可以研究一下,和其他坛友交流一下代码中涉及到的知识点,我就不一一解释了,权当抛砖引玉。
代码如下:
from PySide6.QtWidgets import QApplication,QPushButton,QMessageBox
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QTranslator,QLocale
# 添加 --lang 参数,用于指定程序界面的语言
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--lang',help='界面的语言,目前支持:zh,en(留空则与系统语言一致)')
args = parser.parse_args()
from PySide6 import QtCore
qt_resource_data = b"\
\x00\x00\x00v\
\x0d\x0a\x0d\x0a Main\x0d\
\x0a \x0d\x0a  \x0d\x0a   \x0d\
\x0a    0\x0d\x0a \
   0\x0d\x0a   \
400\x0d\x0a    300\x0d\x0a \
  \x0d\x0a  \x0d\x0a  \x0d\x0a   Main\x0d\x0a  \x0d\x0a  \x0d\x0a   \x0d\x0a  \
\x0d\x0a  \x0d\x0a   \x0d\x0a    C\
lick\x0d\x0a \
  \x0d\x0a \
\x0d\x0a \x0d\x0a \x0d\x0a \x0d\x0a
\x0d\x0a\
"
qt_resource_name = b"\
\x00\x0a\
\x04~\xc5}\
\x00m\
\x00a\x00i\x00n\x00_\x00z\x00h\x00.\x00q\x00m\
\x00\x07\
\x03\x80\x15Y\
\x00m\
\x00a\x00i\x00n\x00.\x00u\x00i\
"
qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00z\
\x00\x00\x01\x98\xe0I\xa8\xd4\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x98\xdf\x1f\x89\xd2\
"
def qInitResources():
    QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
    QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()
app = QApplication()
# 启动时自动切换的关键代码
translator = QTranslator()
if translator.load(QLocale(args.lang) if args.lang else QLocale(),'main','_',':/'):
    QApplication.instance().installTranslator(translator)
window = QUiLoader().load(':/main.ui')
def restart(lang=''):
    msg_box = QMessageBox(
        QMessageBox.Icon.Question,
        '消息',
        '确定要重启程序吗?',
        QMessageBox.Yes | QMessageBox.No,
        window
    ) if lang=='zh' else QMessageBox(
        QMessageBox.Icon.Question,
        'Info',
        'Do you want to restart application?',
        QMessageBox.Yes | QMessageBox.No,
        window
    )
    # 修改标准按钮的文本
    yes_button = msg_box.button(QMessageBox.Yes)
    yes_button.setText('确认'if lang=='zh' else 'Yes')
    no_button = msg_box.button(QMessageBox.No)
    no_button.setText('取消'if lang=='zh' else 'No')
    # 将默认选择的按钮修改为取消按钮
    msg_box.setDefaultButton(no_button)
    msg_box.exec()
    # 结果转换为标准值
    result = msg_box.standardButton(msg_box.clickedButton())
    if result == QMessageBox.Yes:
        # 接受,使用指定lang参数重启程序
        app.quit()
        import sys,os,subprocess
        python_exec = sys.executable
        script_path = os.path.abspath(__file__)
        subprocess.Popen([python_exec, script_path,'--lang',lang])
    else:
        # 忽略
        return
button_zh = QPushButton('切换为中文',window)
button_zh.clicked.connect(lambda :restart('zh'))
button_zh.move(0,50)
button_default = QPushButton('Change to English',window)
button_default.clicked.connect(lambda :restart('en'))
button_default.move(100,50)
window.show()
app.exec()
运行截图:



语言, 文件

PythonPan
OP
  

我先来说一个知识点:将语言文件和UI文件嵌入Python文件的方法是使用资源集合文件编译为Python代码,然后嵌入到Python源代码中。这样做的好处是不用外置语言文件和UI文件,可以在打包Python文件时将语言文件和UI文件一并打包,不像单独文件需要提供文件夹或者随打包成品显式提供(成品中不容易看到这语言文件和UI文件的明文)。虽然编译为Python文件还是能隐约看到原文、防不住高手修改,但是一般的小白对于这样嵌入的语言文件和UI文件无能为力,打消了小白用户想要修改版权信息或者显示文本的想法。
schips   

好思路,谢谢分享
sun2night   

原来,实践才是最好的老师
您需要登录后才可以回帖 登录 | 立即注册

返回顶部