Interesuję się od pewnego czasu pythonem a od niedawna PyQt4. Dokumentacja jest naprawdę dobre zrobiona, co prawda nie jest to msdn ale jest dobrze. Postanowiłem się zabrać za tłumaczenie aplikacji przy użyciu właśnie PyQt4, może lepiej napisać Qt4. Nie potrafiłem znaleźć nic pomocnego w internecie więc zabrałem sie za czytanie książek i teraz wiem i mam zamiar się podzielić z ludźmi którzy mają taki sam problem jaki miałem ja: brak przykładów i jasnych instrukcji jak użyć funkcji tr() i translate().
Załóżmy, że posiadasz mały formularz stworzony w QtDesigner i dopisałeś do tego trochę swojego kodu.
from PyQt4 import QtCore, QtGui
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName('MainWindow')
MainWindow.resize(365, 222)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName('centralwidget')
self.pushButton = QtGui.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(110, 70, 114, 27))
self.pushButton.setObjectName('pushButton')
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate('MainWindow', 'MainWindow', None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate('MainWindow', 'Click', None, QtGui.QApplication.UnicodeUTF8))
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
Powyższy kod powstał już po edycji pliku z QTDesignera, do pliku wynikowego przetworzonego w pyuic4 dorzuciłem dwa dodatkowe bloki kodu. Inicjalizację formatki oraz klasę MyForm. Teraz ten plik zawiera całość kodu, który otwiera mini formatkę z jednym przyciskiem nad czym będziemy pracować. Pozwolę sobie omijać fragmenty kodu i podawać tylko istotne zmiany. Wiem, że w wypadku częstych zmian formatki lepiej jest ją trzymać w osobnym pliku i importować ale na potrzeby tego tutoriala jest to jeden plik.
Do pliku dodajemy kod podpinający sygnał clicked() do naszego przycisku i wykonujący stworzoną przez nas akcję. Dodajemy to do klasy MyForm.
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.MessageBox)
Następnie piszemy funkcję MessageBox która wyświetli okienko potwierdzające, że akcja została wykonana.
def MessageBox(self):
box = QtGui.QMessageBox(self)
box.setWindowTitle(self.tr('information'))
box.setText(self.tr('You have clicked button'))
box.setStandardButtons(QtGui.QMessageBox.Ok)
box.exec_()
Ten plik po uruchomieniu wyświetli okno z jednym przyciskiem po kliknięciu którego wyświetli się messagebox. Teraz zabierzemy się za tłumaczenie programu. Przechodzimy do sedna.
Wymienione przeze mnie funkcje odpowiadają za tworzenie plików .ts do tłumaczeń. Konwencja używania funkcji jest następująca, translate() używane jest dla tekstów będących poza klasami (QTDesigner wszystko wsadza do funkcji translate(), funkcja wymaga podnia kontekstu w jakim znajduje sie łańcuch), funkcja tr() jest dla wszelkich łańcuchów będących w środku klas a trUtf8() dla łańcuchów UTF8. Proste jak drut a przykłady użycia są w kodzie.
Następnym krokiem jest zmodyfikowanie aplikacji aby ładowała tłumaczenie automatycznie na podstawie zmiennej &LANG. Dodajemy kod do funkcji inicjalizującej (jako, że nie jestem pewny o czym piszę to mam na myśli if __name__ == „__main__”:)
locale = QtCore.QLocale.system().name()
appTranslator = QtCore.QTranslator()
if appTranslator.load('okno_ui_' + locale):
app.installTranslator(appTranslator)
Dzięki temu program będzie uruchamiał odpowiednie tłumaczenie, jeśli plik z tłumaczeniem nie zostanie odnaleziony zostanie załadowany domyślny język(w tym wypadku angielski gdyż taki został użyty w kodzie). Dla języka polskiego program będzie próbował załadować tłumaczenie z pliku okno_ui_pl_PL.qm. Nie jest konieczne dodawanie rozszerzenia .qm. Takich plików jeszcze nie mamy, najpierw należy stworzyć plik .pro zawierający wszelkie pliki .ui, .py, .pyw oraz .ts (co ładnie rozwija się w translation source). Ja zazwyczaj nie dodaję plików .ui z powodu tego, że formularze przerabiam potem troszkę na własną rękę poprawiając kod i później mam zamieszanie w pliku .ts. Trudno mi powiedzieć czy jest to dobra czy zła praktyka, mam zbyt małe doświadczenie. Drobne uaktualnienie odnośnie dodawania plików .ui, w tej chwili jednak wolę trzymać formularz stworzony w QtDesigner w osobnym pliku, przyspiesza to dokonywanie zmian. Jednak dla potrzeb tego poradnika jest to wsadzone do jednego pliku, mniej plików = mniejsze zamieszanie. Oto plik .pro.
SOURCES = okno_ui.py TRANSLATIONS = okno_ui_pl_PL.ts
W wypadku dodawania plików .ui potrzebna jest linijka FORMS =. Następnie wykonujemy polecenie pylupdate4 a jako argument podajemy stworzony plik .pro i otrzymujemy gotowy plik .ts który mozna przetłumaczyć. Tłumaczenia robimy w programie QtLinguist, a gotowe pliki .ts przetwarzamy programem lrelease-qt4 który tworzy nam pliki .qm. Koniec pracy. Jeśli w katalogu aplikacji znajdzie się plik .qm dla odpowiedniego języka systemowego to tłumaczenie zostanie załadowane w innym wypadku program otworzy się w języku angielskim.
W wypadku jeśli chcemy dołożyć tłumaczenie nalęzy po prostu dodać odpowiedni plik .ts do posiadanego pliku .pro i ponownie uruchomić pylupdate4, QtDesigner, lrelease-qt4 i tak w koło Macieju.
Dziękuję za uwagę.
0 Responses to “Jak tłumaczyć łatwo w PyQt4 aplikacje”