Рассмотрена возможность добавления на виджеты русских надписей при создании графического интерфейса к программам, написанным на Python, с использованием "обёртки" pyQt
Интерпретируемый язык Python завоёвывает всё большую популярность в среде программистов, что обусловлено его простотой, большими возможностями и объектной ориентированностью. Для создания графического интерфейса пользователя Python может использовать значительное число внешних библиотек, среди которых выделяются Tkinter (написанная на языке Tk/Tcl) и Qt (написанная на C++), предоставляющие богатый набор стандартных виджетов (компонентов, если пользоваться терминологией Windows). Хотя, на мой взгляд, использование Tkinter при программировании на Python несколько удобнее, нежели Qt, однако для C++ программистов может оказаться предпочтительнее перевод старых наработок, выполненных с использованием классов Qt. Для меня, например, это весьма актуально, т.к. в своих поектах для Linux и Windows я активно использую эту библиотеку.
Для перевода кода, использующего классы Qt на язык Python используется так называемая привязка (или, по другому, обёртка) - pyQt. Проверить наличие pyQt в системе можно, запустив интерпретатор Python и напечатав в приглашении командной строки:
>>> import qt
В случае, если не было выведено сообщение об ошибке, pyQt установлен и сконфигурирован правильно.
В том случае, если для разработки пользовательского интерфейса вы используете среду быстрого проектирования Qt Designer, то перевод создаваемых файлов форм с расширением *.ui с языка разметки XML на язык C++ осуществляет утилита uic, которая при компиляции проекта вызывается автоматически. В состав pyQt входит утилита pyuic, которая осуществляет перевод XML - Python. Вызов утилиты осуществляется напрямую (естественно, из каталога, в котором находятся ui-файлы форм):
$ pyuic SomeForm.ui -o SomeForm.py
В этом случае перевод в кодировку по умолчанию осуществляется автоматически.
Однако в случае, когда программирование ведётся "с чистого листа" без вспомогательных инструментов, могут возникнуть трудности при отображении русских надписей на виджетах.
Рассмотрим простейший пример.
Создадим экземпляр класса приложения QApplication - MyProgramme, в котором главным виджетом будет менеджер вертикальной компоновки класса QVBox, дочерними виджетами для которого будут являться надпись QLabel и кнопка QPushButton. Завершение работы приложения будет осуществляться стандартным сигналом - clicked() - щелчок по кнопки, приёмником (слотом) для которого будет функция закрытия приложения - close()
Исходный код:
#------------------------------------------------------
# GUIHello.py - 22.06.2006
#------------------------------------------------------
import sys
from qt import *
#------------------------------------------------------
MyProgramme = QApplication(sys.argv)
MainWidget = QVBox(None)
MainWidget.setCaption("Hello!")
HelloLabel = QLabel("Hello World!", MainWidget)
CloseButton = QPushButton("Quit", MainWidget)
MyProgramme.setMainWidget(MainWidget)
MyProgramme.connect(CloseButton, SIGNAL("clicked()"), MainWidget, SLOT("close()"))
MainWidget.show()
MyProgramme.exec_loop()
Убедимся, что приложение работает, и что окно закрывается при щелчке по кнопке. Однако при попытке заменить английские надписи на виджетах на русские, в окне на этапе выполнения будут отображаться кракозябли. Казалось бы, решение очевидно: по аналогии с C++ воспользоваться функцией-членом класса QObject - QObject.trUtf8, которая осуществит перевод строки-источника в кодировку UTF8. Однако при попытке использования функции в тексте, написанном на Python, выдаётся сообщение об ошибке. Дело в том, что функция trUtf8 не соответствует стандарту C++, используя макрокоманды. Для перевода функции в стандартный C++ используется утилита moc, входящая в поставку Qt, вызываемая макрокомандой Q_OBJECT. При этом функция trUtf8 в получившемся moc-файле переопределяется. В Python переопределение функции приходится делать вручную. Аргументами функции QObject.trUtf8 выступают экземпляр (instance) класса QObject, для которого выполняется перевод, и собственно строка-источник - экземпляр класса QString. Определим переменную, которая будет хранить ссылки на виджеты, подвергаемые переводу ;)
Instanse = QObject
Тогда саму функцию можно переопределить следующим образом:
def trUtf8(Instance, SourceText):
return QObject.trUtf8(Instance, SourceText)
Тогда полный код приложения будет следующим:
#------------------------------------------------------
# GUIHelloRU.py - 22.06.2006
#------------------------------------------------------
import sys
from qt import *
#------------------------------------------------------
Instanse = QObject
def trUtf8(Instance, SourceText):
return QObject.trUtf8(Instance, SourceText)
#------------------------------------------------------
MyProgramme = QApplication(sys.argv)
MainWidget = QVBox(None)
MainWidget.setCaption(trUtf8(MyProgramme, "Привет"))
HelloLabel = QLabel(trUtf8(MyProgramme, "Привет, мир!"), MainWidget)
CloseButton = QPushButton(trUtf8(MyProgramme, "Выход"), MainWidget)
MyProgramme.setMainWidget(MainWidget)
MyProgramme.connect(CloseButton, SIGNAL("clicked()"), MainWidget, SLOT("close()"))
MainWidget.show()
MyProgramme.exec_loop()<pre>
Убедитесь, что программа работает правильно, а русский текст на виджетах отображается без ошибок.
P.S. Если кто-то знает лучший способ, нежели предложенный, пишите в комментарии. А вообще, надеюсь, на Бегине появится раздел форума, посвящённый Python.
Источник: http://prog-begin.net.ru