Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
PyQt5

О локализации стандартных диалогов PyQt(PyQt5/PyQt6/PySide2/PySide6 и т.д.)

20.06.2022, 14:24. Показов 3347. Ответов 3
Метки pyqt (Все метки)

Студворк — интернет-сервис помощи студентам
Поднималась тут недавно тема Переименовать кнопку "setDetailedText". Смысл всей заварушки, как я понял, был в том, что стандартные диалоги PyQt, такие как QColorDialog, QFileDialog, QFontDialog, QMessageBox и некоторые виджеты типа QDialogButtonBox "в диком виде" упорно объясняются исключительно на английском. И ладно, если бы это случалось повсеместно, но ведь есть и исключения. Например, в Linux OpenSUSE с русской локалью начальный пример, приведённый в той теме, прекрасно объясняется по-русски без всяких дополнительных телодвижений.

Решение этой проблемы неочевидно, но хорошо известно - достаточно просто установить транслятор с загруженным файлом локализации (который уже есть в системе с момента установки PyQt). Но прямого указания на это решение в документации нет.

И вот, ковыряя потихоньку эту тему в поисках универсального решения с учётом практики OpenSUSE, я и упёрся в дно .

Проиллюстрирую сказанное:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Locale Probe v0.07
 
import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QFontDialog
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
 
    header = '({!s}:{!s}) Требуется добавить транслятор'
    tr_num = len(app.findChildren(QtCore.QTranslator))
    lang = QtCore.QLocale().name()[0:2]
    if tr_num > 0 or lang == 'en':
        header = '({!s}:{!s}) Добавлять транслятор не требуется'
 
    (newfont, ok) = QFontDialog.getFont(
        QApplication.font(), None, header.format(tr_num, lang))
 
# ---> начало кода, обязательного для употребления в __main__
    if (len(app.findChildren(QtCore.QTranslator)) == 0 and
        QtCore.QLocale().name()[0:2] != 'en'):
        # если язык операционной системы - английский или
        # какие-то трансляторы уже установлены, то добавлять
        # ещё один не требуется (сюрприз от некоторых операционных
        # систем, например, Linux OpenSUSE этим грешит;
        # однако, бывают случаи, когда нужные файлы локализации
        # неполные или отсутствуют, но это совсем другая песня)
 
        qtrn = QtCore.QTranslator(app)
        # родителя транслятору лучше назначать;
        # можно и имя дать с помощью setObjectName();
        # транслятор можно не только устанавливать,
        # но и удалять с помощью removeTranslator();
        # если потребуется, проще и надёжней отыскать
        # его среди детей нашего единственного экземпляра
        # QApplication (см. QApplication.instance()),
        # чем обеспечивать глобальный доступ к нему
        if qtrn.load(
                'qtbase_' + QtCore.QLocale().name()[0:2],
                # подсунем транслятору ресурс, соответствующий языковым
                # настройкам операционной системы, явным образом;
                # (для русского языка будет загружен qtbase_ru.qm)
                QtCore.QLibraryInfo.location(
                    QtCore.QLibraryInfo.TranslationsPath)):
 
            app.installTranslator(qtrn)
# <--- конец кода, обязательного для употребления в __main__
 
            (newfont, ok) = QFontDialog.getFont(
                QApplication.font(),
                None,
                '({!s}:{!s}) Вид после добавления транслятора'.format(
                    len(app.findChildren(QtCore.QTranslator)),
                    QtCore.QLocale().name()[0:2]))
 
    sys.exit(0)
Картинки, кроме схем и формул, тут нельзя заливать, если кому интересно, можете в блоге посмотреть К вопросу о локализации приложений PyQt. (я там сначала порезвился).

В заголовках окон (в скобочках слева от основного текста) отображается количество установленных трансляторов и язык системы.

С Windows - всё понятно. Нет установленных трансляторов - значит ставим нужный и наслаждаемся результатом. И, самое главное, этот процесс контролируется со стороны приложения.

А к OpenSUSE вопросы есть. Вот чего она там целых 32 штуки трансляторов нацепляла-то? Какие файлы она там прогрузила? Как это узнать? Перерыл всё, что мог и до чего дотянулся - не нашёл, как это делается. Такое ощущение, что "нету у нас методов против QTranslator-а" .

Ну и второй вопрос связан с файлом локализации, который требуется грузить. Может лучше грузить qt_ru.qm? Но как правильно загрузить этот каталог файлов локализации, чтобы всё перечисленное в нём тоже загрузилось - я так и не понял.

Если знаете - подскажите, пожалуйста...
1
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.06.2022, 14:24
Ответы с готовыми решениями:

Ошибка QPaintDevice: Cannot destroy paint device that is being painted в PyQt6 и PySide6
Здравствуйте! В книге Create GUI Applications with Python &amp; Qt5 в разделе про 2D-графику представлен такой код: from PyQt5 import...

Как менять цвет текста в listWidget, lineEdit итд. PyQt6, PySide6
Как можно для каждого слова отдельно применить свой цвет? Допустим items = str('Привет, как дела') item =...

С Pyqt5 на Pyqt6
Подскажите, делаю кнопку скрыть/открыть пароль на Pyqt6, что не так? Жалуется на QtCore.Qt.Checked ...

3
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
20.06.2022, 15:50
Лучший ответ Сообщение было отмечено iamvic как решение

Решение

iamvic, около ответ:

Столкнувшись с сие бедой, потратив кучу времени на изучение QTranslator и прочего с ним связанного, пришел к решению что легче написать свою функцию, которая при инициализации будет считывать из файла все строки с переводом, а ее вызов будет переводить сие строку, метод не новый, но зато рабочий, плюс в том что ничего лишнего в файлах не будет, редактировать перевод можно на лету, и можно дать пользователям тоже его править.
2
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
20.06.2022, 18:27  [ТС]
Fudthhh, спасибо! Значит из QTranslator-а действительно ничего выдавить не удастся. А идея своей функции - годная!
0
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
21.06.2022, 20:08  [ТС]
И ещё раз, спасибо, Fudthhh!!! Какую богатую идею Вы подкинули! Я попробавал, возможно, это не совсем то, о чём Вы говорили, но то, что получилось, мне тоже очень нравится. Сделал ts-файл ручками в одном контексте, lrelease напустил - получил qm, положил рядом головным файлом (в данном случае, locale_probe.py) и всё. Запусти и получи результат. А этот ts и грамотный пользователь править сможет, для lrelease можно пакетник соорудить, запустить этот пакетник у такого пользоателя тоже рука не дрогнет

locale_probe_ru.ts
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS><TS version="2.0" language="ru" sourcelanguage="en">
<context>
    <name>locale_probe_main</name>
    <message>
        <source>Need to install a translator</source>
        <translation type="finished">Требуется добавить транслятор</translation>
    </message>
    <message>
        <source>No translator required</source>
        <translation type="finished">Добавлять транслятор не требуется</translation>
    </message>
    <message>
        <source>View after installing the translator</source>
        <translation type="finished">Вид после добавления транслятора</translation>
    </message>
</context>
</TS>
Пакетник из одной строки:
Code
1
lrelease locale_probe_ru.ts -qm locale_probe_ru.qm
locale_probe.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Locale Probe v0.08
 
import sys, os
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QFontDialog
 
def tr_app(text):
    return QApplication.instance().translate(
        QApplication.instance().objectName(), text)
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setObjectName('locale_probe_main')
 
    header = '({!s}:{!s}) ' + tr_app('Need to install a translator')
    tr_num = len(app.findChildren(QtCore.QTranslator))
    lang = QtCore.QLocale().name()[0:2]
    if tr_num > 0 or lang == 'en':
        header = '({!s}:{!s}) ' + tr_app('No translator required')
 
    (newfont, ok) = QFontDialog.getFont(
        QApplication.font(), None, header.format(tr_num, lang))
 
# ---> начало кода, обязательного для употребления в __main__
    if (len(app.findChildren(QtCore.QTranslator)) == 0 and
        QtCore.QLocale().name()[0:2] != 'en'):
        # если язык операционной системы - английский или
        # какие-то трансляторы уже установлены, то добавлять
        # ещё один не требуется (сюрприз от некоторых операционных
        # систем, например, Linux OpenSUSE этим грешит;
        # однако, бывают случаи, когда нужные файлы локализации
        # неполные или отсутствуют, но это совсем другая песня)
 
        qtrn = QtCore.QTranslator(app)
        # родителя транслятору лучше назначать;
        # можно и имя дать с помощью setObjectName();
        # транслятор можно не только устанавливать,
        # но и удалять с помощью removeTranslator();
        # если потребуется, проще и надёжней отыскать
        # его среди детей нашего единственного экземпляра
        # QApplication (см. QApplication.instance()),
        # чем обеспечивать глобальный доступ к нему
        if qtrn.load(
                'qtbase_' + QtCore.QLocale().name()[0:2],
                # подсунем транслятору ресурс, соответствующий языковым
                # настройкам операционной системы, явным образом;
                # (для русского языка будет загружен qtbase_ru.qm)
                QtCore.QLibraryInfo.location(
                    QtCore.QLibraryInfo.TranslationsPath)):
 
            app.installTranslator(qtrn)
# <--- конец кода, обязательного для употребления в __main__
 
            qtrn_extra = QtCore.QTranslator(app)
            qtrn_extra.load(
                'locale_probe_' + QtCore.QLocale().name()[0:2],
                os.path.dirname(os.path.abspath(sys.argv[0])))
            QApplication.installTranslator(qtrn_extra)
 
            (newfont, ok) = QFontDialog.getFont(
                QApplication.font(),
                None,
                ('({!s}:{!s}) ' + tr_app(
                    'View after installing the translator')).format(
                        len(app.findChildren(QtCore.QTranslator)),
                        QtCore.QLocale().name()[0:2]))
 
    sys.exit(0)
И теперь, как положено, заголовок в первом диалоге тоже на английском (нет ещё установленных трансляторов, хотя перевод уже есть), а второй, в данном случае, будет на русском. И ничто не мешает наваять файлы и для других языков. Подтолкнули в нужном направлении, спасибо!
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.06.2022, 20:08
Помогаю со студенческими работами здесь

Pyside2/PyQt5 events
Доброго времени форумчане :) Интересует понимание как реализовать свою систему событий. Как они реализованы в pyside2 или pyqt5 ? ...

Python Pyside2 PyQt5 Qtdesigner
Программа запускается, но кнопки не работают (на pyside 1) все работало. #Изначально подключаются необходимые библиотеки #from graphics...

Python PyQt5 PySide2 Loading
Всем привет, делаю программу. При нажатие кнопки старта, происходят вычисления, хотел сделать в это время интерфейс загрузку. Но никак...

Python Pyside2 PyQt5 Qtdesigner
Помогите сделать так, чтобы сначала определялись центры кластеров, а затем рандомное создание точек вокруг этих кластеров.

QT, PyQT, wxPython, PyCairo, PySide, PySide2, PySimpleGUI, Thinter
Что из этого можно, а что нельзя преобразовать в exe (после создания GUI) или сделать портабельным для удобного переноса другому...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru