Wiki

Русификация в pyQt

Рассмотрена возможность добавления на виджеты русских надписей при создании графического интерфейса к программам, написанным на 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