Çözüldü PyQt'de sistem diline göre yazı değiştirme nasıl yapılır?

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.

BayCoder

Hectopat
Katılım
8 Mart 2021
Mesajlar
531
Makaleler
4
Çözümler
4
Daha fazla  
Cinsiyet
Erkek
Merhabalar, belki bilenler vardır bir süredir PyQt ile uğraşıyorum ve bir program yapıyorum. Bu programda olan buton ve label kısımlarının sistem diline göre değişmesini istiyorum. Mesela sistem İngilizce ise "Merhaba" olan kısım "Hello" olacak. Bunu nasıl yapabilirim? Cevabınız değişir mi bilmiyorum ama programı Debian ile geliştiriyorum.
 
Çözüm
Öncelikle sistem dilini öğrenmekle başlayalım.

Aşağıdaki kodun çıktısı "en_US", "tr_TR" gibi şekillerde olacaktır.

[CODE lang="python" title="Örnek"]import locale

print(locale.getdefaultlocale()[0]) # getdefaultlocale() fonksiyonundan gelen ('en_US', 'UTF-8') şeklindeki çıktıdan [0] yazarak ilk elemeanı alıp 'en_US' kısmını elde ettik.[/CODE]

Uygulama için dil oluşturmakla devam edelim. Dil dosyası oluşturan program için ayrı bir .py dosyası oluşturalım. Dil dosyası oluşturma kısmı için ben dictionary oluşturup JSON ile saklamayı tercih ediyorum.

[CODE lang="python" title="dil_olusturucu.py"]import json

# İngilizce dil için dictionary.
lang_en = {
"hello": "Hello World!",
"detected_lang": "Detected language is"
}

# Türkçe dil için dictionary.
lang_tr = {
"hello": "Merhaba Dünya!",
"detected_lang": "Algılanan dil"
}

# Dosya açıp JSON ile yazma işlemleri. Özellikle dosya adını locale.getdefaultlocale()'in döndürdüğü değerlere göre oluşturuyoruz.

with open("en_US.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_en, dosya)

with open("tr_TR.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_tr, dosya)[/CODE]

Şimdi asıl Python programımızda dili algılayıp, ilgili dosyayı okuyup, kullanalım.

[CODE lang="python" title="ornek_program.py"]import locale
import json
from os import path

# Sistem dilini öğrenme.
sistem_dili = locale.getdefaultlocale()[0]

# Dil dosyasının varlığını kontrol edip varsa okuma ve içeriğini "dil" isimli değişkene atma.
if path.isfile("{}.json".format(sistem_dili)):
try:
with open("{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
dil = json.load(dosya)
except:
print("Hata.")
else:
print("{} için dil dosyası bulunamadı, varsayılan dil dosyası yükleniyor.".format(sistem_dili))
try:
sistem_dili = "tr_TR"
with open("{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
dil = json.load(dosya)
except:
print("Hata.")

# dil.get("dictionary_anahtarı") yapısı ile anahtarın karşılığı olan değeri alabiliyoruz. Bulamazsa boş dönüş yapıyor. Eğer dil["dictionary_anahtarı"] şeklinde kullansaydık bulamadığı zaman hata verecekti.
print("{} {}.".format(dil.get("detected_lang"), sistem_dili))

print(dil.get("hello"))[/CODE]

PyQt için ise önceden dil dosyasını okuyup, değişkene atıp daha sonra Qt5 Designer'in oluşturduğu retranslateUi fonksiyonu altındaki değerleri dil.get("anahtar") yapısı ile değiştiriyorum.

[CODE lang="python" title="Örnek"]self.themeLabel.setText(_translate("DialogPreferences", language.get("theme")))
[/CODE]

Yazdığım koddaki yorum satırlarını okumayı unutmayın. Ben bu şekilde çoklu dil yapıyorum. Değiştirilebilir yapmak istiyorsanız bir ayarlar dosyası da oluşturup onu okuyabilir, dili değiştirirken ise bir ayarlar menüsündeki ComboBox'a dil klasöründeki bütün dillerin isimlerini yazdırıp seçilen dili ayarlar dosyasına yazabilirsiniz. Bu sayede dil için sınırsız JSON dosyası oluşturabilir ve asıl programın kodunu değiştirmeden dinamik bir şekilde bütün dilleri kullanabilmesini sağlayabilirsiniz.

Türkçe kısmını deneyemedim ama eğer locale.getdefaultlocale()[0], tr_TR olarak çıktı veriyorsa JSON dosyasını da okuyacaktır.

Sorunuz olursa yazmaktan çekinmeyin.
@BayCoder anlattığım şekilde yapabildiniz mi? Yapabildiyseniz çözüm olarak işaretlerseniz sevinirim.

Hocam iyi ki etiketlemişsiniz yeni bildirim geldi. Deneyip çözüm işaretleyeyim. :)
Öncelikle sistem dilini öğrenmekle başlayalım.

Aşağıdaki kodun çıktısı "en_us", "tr_tr" gibi şekillerde olacaktır.

[CODE lang="python" title="Örnek"]import locale.

print(locale.getdefaultlocale()[0]) # getdefaultlocale() fonksiyonundan gelen ('en_US', 'UTF-8') şeklindeki çıktıdan [0] yazarak ilk elemeanı alıp 'en_US' kısmını elde ettik.[/CODE]

Uygulama için dil oluşturmakla devam edelim. Dil dosyası oluşturan program için ayrı bir .py dosyası oluşturalım. Dil dosyası oluşturma kısmı için ben dictionary oluşturup json ile saklamayı tercih ediyorum.

[CODE lang="python" title="dil_olusturucu.py"]import json.

# İngilizce dil için dictionary.
lang_en = {
"hello": "Hello World!",
"detected_lang": "Detected language is"
}

# Türkçe dil için dictionary.
lang_tr = {
"hello": "Merhaba Dünya!",
"detected_lang": "Algılanan dil"
}

# Dosya açıp JSON ile yazma işlemleri. Özellikle dosya adını locale.getdefaultlocale()'in döndürdüğü değerlere göre oluşturuyoruz.

with open("en_US.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_en, dosya)

with open("tr_TR.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_tr, dosya)[/CODE]

Hocam bu kısma kadar bir sıkıntım yok.

PyQt için ise önceden dil dosyasını okuyup, değişkene atıp daha sonra QT5 Designer'in oluşturduğu retranslateUi fonksiyonu altındaki değerleri dil.get("anahtar") yapısı ile değiştiriyorum.

[CODE lang="python" title="Örnek"]self.themeLabel.setText(_translate("DialogPreferences", language.get("theme")))
[/CODE]

Bunu anlayamadım. Ben Qt Designer ile yapıyorum ve daha sonra pyuic5 ile Python dosyasına çeviriyorum. Bu yüzden ben çevirdiğim dosyadaki retranslateUi kısmını mı değiştireyim?

[CODE lang="python" title="Python Kodum;"]self.retranslateUi(EkranGoruntusuAnaWindow)
QtCore.QMetaObject.connectSlotsByName(EkranGoruntusuAnaWindow)

def retranslateUi(self, EkranGoruntusuAnaWindow):

_translate = QtCore.QCoreApplication.translate[/CODE]

Yazdığım koddaki yorum satırlarını okumayı unutmayın. Ben bu şekilde çoklu dil yapıyorum. Değiştirilebilir yapmak istiyorsanız bir ayarlar dosyası da oluşturup onu okuyabilir, dili değiştirirken ise bir ayarlar menüsündeki Combobox'a dil klasöründeki bütün dillerin isimlerini yazdırıp seçilen dili ayarlar dosyasına yazabilirsiniz.

Değiştirilebilir de yapacağım hocam yanına da otomatik sistem diline göre değişmesini istiyorum.
 
Son düzenleme:
retranslateUi fonksiyonunun tamamını atın, nereleri değiştirmeniz gerektiğini göstereyim.
Python:
def retranslateUi(self, EkranGoruntusuAnaWindow):

        _translate = QtCore.QCoreApplication.translate

        EkranGoruntusuAnaWindow.setWindowTitle(_translate("EkranGoruntusuAnaWindow", "Ekran Görüntüsü"))

        self.Sure.setText(_translate("EkranGoruntusuAnaWindow", "Saniye Bekle"))

        self.ImlecGoster.setText(_translate("EkranGoruntusuAnaWindow", "İmleci Göster"))

        self.TamEkranYazi.setText(_translate("EkranGoruntusuAnaWindow", "Tam Ekran"))

        self.PencereYazi.setText(_translate("EkranGoruntusuAnaWindow", "Pencere"))

        self.SecimliYazi.setText(_translate("EkranGoruntusuAnaWindow", "Seçimli"))

        self.menuHakkinda.setTitle(_translate("EkranGoruntusuAnaWindow", "Yardım"))

        self.menuAyarlar.setTitle(_translate("EkranGoruntusuAnaWindow", "Ayarlar"))

        self.Hakkinda.setText(_translate("EkranGoruntusuAnaWindow", "Hakkında"))

        self.Icerik.setText(_translate("EkranGoruntusuAnaWindow", "İçerik"))

        self.actionSistem_Tepsisinde_Kullan.setText(_translate("EkranGoruntusuAnaWindow", "Sistem Tepsisinde Kullan"))
 
Python:
def retranslateUi(self, EkranGoruntusuAnaWindow):
        _translate = QtCore.QCoreApplication.translate
        EkranGoruntusuAnaWindow.setWindowTitle(_translate("EkranGoruntusuAnaWindow", "Ekran Görüntüsü"))
        self.Sure.setText(_translate("EkranGoruntusuAnaWindow", "Saniye Bekle"))
        self.ImlecGoster.setText(_translate("EkranGoruntusuAnaWindow", "İmleci Göster"))
        self.TamEkranYazi.setText(_translate("EkranGoruntusuAnaWindow", "Tam Ekran"))
        self.PencereYazi.setText(_translate("EkranGoruntusuAnaWindow", "Pencere"))
        self.SecimliYazi.setText(_translate("EkranGoruntusuAnaWindow", "Seçimli"))
        self.menuHakkinda.setTitle(_translate("EkranGoruntusuAnaWindow", "Yardım"))
        self.menuAyarlar.setTitle(_translate("EkranGoruntusuAnaWindow", "Ayarlar"))
        self.Hakkinda.setText(_translate("EkranGoruntusuAnaWindow", "Hakkında"))
        self.Icerik.setText(_translate("EkranGoruntusuAnaWindow", "İçerik"))
        self.actionSistem_Tepsisinde_Kullan.setText(_translate("EkranGoruntusuAnaWindow", "Sistem Tepsisinde Kullan"))
Rastgele bir satıra bakarsak self.Hakkinda.setText(_translate("EkranGoruntusuAnaWindow", "Hakkında")) satırının en sonunda "Hakkında" diye bir yazı var ve siz burayı dile göre değiştirmek istiyorsunuz. Dil dosyasını okuyarak oluşturduğunuz dil değişkeninden ilgili anahtarı kullanarak karşılığını alacaksınız.(İlk mesajımda bunu detaylıca anlattım ve örnek kod gösterdim bu yüzden tekrar anlatmıyorum.) Örneğin oluşturduğunuz dictionary aşağıdaki gibiyse "Hakkında" yazan kısma dil.get("hakkinda") yazacaksınız. Hangi dictionary yüklendiyse ona göre sonuç "Hakkında" veya "About" olarak değişecek.

Python:
lang_tr = {
 "hakkinda": "Hakkında",
 "ayarlar": "Ayarlar",
 "yardim": "Yardım"
}

lang_en = {
 "hakkinda": "About",
 "ayarlar": "Settings",
 "yardim": "Help"
}
 
@Kerem00 değerli hocam çok teşekkür ederim başarılı oldum sayenizde ve "Çözüldü" işaretledim. Ama bir sorum var. JSON olarak kaydetmeyi iptal edip direkt JSON dosyalarını bir dizinden alsam nasıl olur ? Yani mesela ~/Downloads/PyQt/Diller/ dosya yolunda olan en_US.json dosyası kullanılacak gibi.
 
Ama bir sorum var. JSON olarak kaydetmeyi iptal edip direkt JSON dosyalarını bir dizinden alsam nasıl olur? Yani mesela ~/Downloads/PyQt/Diller/ dosya yolunda olan en_US.json dosyası kullanılacak gibi.
Zaten bir kere kaydetmeniz yeterli JSON dosyalarını. Yeni bir dil eklemeyeceğiniz sürece dil oluşturan Python dosyasını kullanmanıza gerek yok. Daha sonra JSON dosyalarını nereye koyduysanız oradan okursunuz.

Mesela Python programının çalıştığı dizinde Diller diye bir klasör varsa daha önceden attığım koddaki dosya yollarını böyle değiştirebilirsiniz.

Python:
if path.isfile("Diller/{}.json".format(sistem_dili)):
    try:
        with open("Diller/{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
            dil = json.load(dosya)
    except:
        print("Hata.")
else:
    print("{} için dil dosyası bulunamadı, varsayılan dil dosyası yükleniyor.".format(sistem_dili))
    try:
        sistem_dili = "tr_TR"
        with open("Diller/{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
            dil = json.load(dosya)
    except:
        print("Hata.")

Bir klasördeki bütün JSON dosyalarını listelemek için aşağıdaki kodları kullanabilirsiniz. İleride işinize yarar belki.

[CODE lang="python" title="Örnek"]import glob
from os import path

for dosya in glob.glob("Diller/*.json"):
print(dosya) # tam dosya yolu
print(path.basename(dosya).replace(".json", "")) # uzantısız dosya adı[/CODE]
 
Zaten bir kere kaydetmeniz yeterli JSON dosyalarını. Yeni bir dil eklemeyeceğiniz sürece dil oluşturan Python dosyasını kullanmanıza gerek yok. Daha sonra JSON dosyalarını nereye koyduysanız oradan okursunuz.

Mesela Python programının çalıştığı dizinde Diller diye bir klasör varsa daha önceden attığım koddaki dosya yollarını böyle değiştirebilirsiniz.

Python:
if path.isfile("Diller/{}.json".format(sistem_dili)):
    try:
        with open("Diller/{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
            dil = json.load(dosya)
    except:
        print("Hata.")
else:
    print("{} için dil dosyası bulunamadı, varsayılan dil dosyası yükleniyor.".format(sistem_dili))
    try:
        sistem_dili = "tr_TR"
        with open("Diller/{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
            dil = json.load(dosya)
    except:
        print("Hata.")

Bir klasördeki bütün JSON dosyalarını listelemek için aşağıdaki kodları kullanabilirsiniz. İleride işinize yarar belki.

[CODE lang="python" title="Örnek"]import glob
from os import path

for dosya in glob.glob("Diller/*.json"):
print(dosya) # tam dosya yolu
print(path.basename(dosya).replace(".json", "")) # uzantısız dosya adı[/CODE]
Tamamdır hocam çok teşekkür ederim.
Hocam locale kütüphanesini söz yerinde ise kandırarak en_US kısmını değiştirmek istiyorum diğer dillerde de kullanıldığından emin olmak için,mümkün mü ? @Kerem00
 
Hocam locale kütüphanesini söz yerinde ise kandırarak en_US kısmını değiştirmek istiyorum diğer dillerde de kullanıldığından emin olmak için, mümkün mü? @Kerem00
Diğer dillerin isimlerinin ne olduğundan emin değilim ama /etc/locale.gen dosyasındakileri veriyor gibi geldi bana.(Bu sadece benim tahminim.) Terminale cat /etc/locale.gen yazarak içeriğini görebilirsiniz.(Bu dosya, locale-gen komutu ile birlikte GNU/Linux'ta sistem dillerini aktifleştirmeye yarar.)

Denemek için ise locale kütüphanesini kandırmak yerine sistem_dili değişkenine kendiniz bir değer atayın. Ben denemek için sistem_dili = "tr_TR" yazmıştım mesela.
 
Diğer dillerin isimlerinin ne olduğundan emin değilim ama /etc/locale.gen dosyasındakileri veriyor gibi geldi bana.(Bu sadece benim tahminim.) Terminale cat /etc/locale.gen yazarak içeriğini görebilirsiniz.(Bu dosya, locale-gen komutu ile birlikte GNU/Linux'ta sistem dillerini aktifleştirmeye yarar.)

Denemek için ise locale kütüphanesini kandırmak yerine sistem_dili değişkenine kendiniz bir değer atayın. Ben denemek için sistem_dili = "tr_TR" yazmıştım mesela.
Tamam hocam teşekkür ederim.
Öncelikle sistem dilini öğrenmekle başlayalım.

Aşağıdaki kodun çıktısı "en_us", "tr_tr" gibi şekillerde olacaktır.

[CODE lang="python" title="Örnek"]import locale.

print(locale.getdefaultlocale()[0]) # getdefaultlocale() fonksiyonundan gelen ('en_US', 'UTF-8') şeklindeki çıktıdan [0] yazarak ilk elemeanı alıp 'en_US' kısmını elde ettik.[/CODE]

Uygulama için dil oluşturmakla devam edelim. Dil dosyası oluşturan program için ayrı bir .py dosyası oluşturalım. Dil dosyası oluşturma kısmı için ben dictionary oluşturup json ile saklamayı tercih ediyorum.

[CODE lang="python" title="dil_olusturucu.py"]import json.

# İngilizce dil için dictionary.
lang_en = {
"hello": "Hello World!",
"detected_lang": "Detected language is"
}

# Türkçe dil için dictionary.
lang_tr = {
"hello": "Merhaba Dünya!",
"detected_lang": "Algılanan dil"
}

# Dosya açıp JSON ile yazma işlemleri. Özellikle dosya adını locale.getdefaultlocale()'in döndürdüğü değerlere göre oluşturuyoruz.

with open("en_US.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_en, dosya)

with open("tr_TR.json", "w", encoding="UTF-8") as dosya:
json.dump(lang_tr, dosya)[/CODE]

Şimdi asıl Python programımızda dili algılayıp, ilgili dosyayı okuyup, kullanalım.

[CODE lang="python" title="ornek_program.py"]import locale.
import json.
from os import path.

# Sistem dilini öğrenme.
sistem_dili = locale.getdefaultlocale()[0]

# Dil dosyasının varlığını kontrol edip varsa okuma ve içeriğini "dil" isimli değişkene atma.
if path.isfile("{}.json".format(sistem_dili)):
try:
with open("{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
dil = json.load(dosya)
except:
print("Hata.")
else:
print("{} için dil dosyası bulunamadı, varsayılan dil dosyası yükleniyor.".format(sistem_dili))
try:
sistem_dili = "tr_TR"
with open("{}.json".format(sistem_dili), "r", encoding="UTF-8") as dosya:
dil = json.load(dosya)
except:
print("Hata.")

# dil.get("dictionary_anahtarı") yapısı ile anahtarın karşılığı olan değeri alabiliyoruz. Bulamazsa boş dönüş yapıyor. Eğer dil["dictionary_anahtarı"] şeklinde kullansaydık bulamadığı zaman hata verecekti.
print("{} {}.".format(dil.get("detected_lang"), sistem_dili))

print(dil.get("hello"))[/CODE]

PyQt için ise önceden dil dosyasını okuyup, değişkene atıp daha sonra QT5 Designer'in oluşturduğu retranslateUi fonksiyonu altındaki değerleri dil.get("anahtar") yapısı ile değiştiriyorum.

[CODE lang="python" title="Örnek"]self.themeLabel.setText(_translate("DialogPreferences", language.get("theme")))
[/CODE]

Yazdığım koddaki yorum satırlarını okumayı unutmayın. Ben bu şekilde çoklu dil yapıyorum. Değiştirilebilir yapmak istiyorsanız bir ayarlar dosyası da oluşturup onu okuyabilir, dili değiştirirken ise bir ayarlar menüsündeki Combobox'a dil klasöründeki bütün dillerin isimlerini yazdırıp seçilen dili ayarlar dosyasına yazabilirsiniz. Bu sayede dil için sınırsız json dosyası oluşturabilir ve asıl programın kodunu değiştirmeden dinamik bir şekilde bütün dilleri kullanabilmesini sağlayabilirsiniz.

Türkçe kısmını deneyemedim ama eğer locale.getdefaultlocale()[0], tr_tr olarak çıktı veriyorsa json dosyasını da okuyacaktır.

Sorunuz olursa yazmaktan çekinmeyin.

Hocam bir sorum var. Mesela toplam 5000 kelimeden oluşan büyük bir proje var. Bu projedeki 5000 kelimenin hepsini tek tek çevirip json dosyasına yazmak zorunda mıyım? Bunu hızlandırmanın veya bunu otomatik yapmanın bir yolu var mı?
 
Son düzenleme:
Hocam bir sorum var. Mesela toplam 5000 kelimeden oluşan büyük bir proje var. Bu projedeki 5000 kelimenin hepsini tek tek çevirip json dosyasına yazmak zorunda mıyım? Bunu hızlandırmanın veya bunu otomatik yapmanın bir yolu var mı?
Kendiniz çevirmeyecekseniz Python'da kelime çevirisi yapabilen kütüphaneleri araştırabilirsiniz. Benim aklıma bu geldi sadece.
 

Geri
Yukarı