PyQt5 Belgelendirmesi Gitbook’da

Uzun zamandır elimi sürmediğim PyQt5 Belgelendirmesi‘ni Gitbook‘a taşıdım. Böylece elimdeki raw belgeleri kaybetme riski olmadan Gitbook’da muhafaza etmiş olacağım. Kısa süre içerisinde de belgelere göz gezdirip; eksik bilgi, hatalı kod vb. gibi düzenlemeleri yaptıktan sonra yeni belgeler eklemeye başlayacağım. Belgelendirmeyi Sphinx‘den Gitbook’a taşıdığım için de disqus yorumları(yaklaşık 6-7 adet) silinmiş oldu.

PyQt5 ile Değişken Parametreli Sinyal Oluşturmak

PisiLinux için yardım ettiğim sıralarda package-manager adlı yazılımı PyQt4 den PyQt5 e geçirmeye çalışmıştım. Bu geçişin en önemli kısmı da sinyallerdi. Çünkü Qt5 ile gelen en önemli değişiklik sinyal yapısındaydı. PyQt4’ün son sürümlerinde eski ve yeni diye tabir edeceğimiz iki farklı sinyal-yuva yapısı vardı ve PyQt5(Qt5) ile eski sinyal yapısı artık kullanımdan çıkmış oldu. Tam bu noktada package-manager yazılımında bir sinyal yaratımı ve kullanımı beni zor duruma soktu ve bunun çözümü için uğraştım.

Şimdi eski sinyal yapısına bir göz atalım:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys

class Pencere(QMainWindow):

    def __init__(self):
        super().__init__()
        self.widget = QWidget(self)
        self.setCentralWidget(self.widget)

        self.buton = QPushButton(self.widget)
        self.buton.setText("Buton")
        self.connect(self.buton, SIGNAL("clicked()"), self.sinyalCalistir)
        self.connect(self, SIGNAL("ornekSinyal(str"), self.yazdir)
        self.connect(self, SIGNAL("ornekSinyal(int, str, int, str"), self.yazdir)

    def yazdir(self, *args):
        print(*args)

    def sinyalCalistir(self):
        self.emit(SIGNAL("ornekSinyal(str)"), "Merhaba Dünya!")
        self.emit(SIGNAL("ornekSinyal(int, str, int, str"), 1, "Merhaba Dünya!", 2, "Merhaba!")

uygulama = QApplication(sys.argv)
pencere = Pencere()
pencere.show()
uygulama.exec_()

Okumaya devam et

Python ile Hole Punching Yöntemi

Hole Punching denilen yöntem, nat arkasındaki iki cihazı birbirine doğrudan bağlamaya yarar. Skype, Google Hangouts gibi görüntü ve ses gibi verilerin aktarımını yapan programların kullandığı bir yöntemdir.

Görüntü ve ses verisi içeren veriler sunuculara çok büyük bir yük getireceği için bu tarz programlar bu verilerin karşılıklı iki istemci(client) arasında aktarılmasını sağlayarak sunucularını büyük bir yükten kurtarırlar.

Peki nat bu işi arka planda nasıl hallediyor? İç ve dış ip olmak üzere iki aşamalı ip kullandırıyor. Her makine kendi içerisinde 192.168.1.2 gibi iç ip kullanır ve dış dünya ile bu ip üzerinden iletişim kurduğunu sanır.  İstemci ile bir sunucuya veri yolladığımızda nat, yerel ip ve portu dış ip ve port ile değiştirir. Nat bu bilgileri bir tabloda tutarak, 192.168.1.2 iç ip’li istemcinin 88.76.128.62 dış ip’si ile 1234 portu ile bağlandığını aklında tutuyor. Böylece dışarıdan bir veri bu dış ip ve porta geldiğinde nat bu verinin 192.168.1.2 iç ip’li istemciye  geldiğini anlayarak veriyi bu istemciye yönlendiriyor.

Siz bu şekilde bir sunucuya, istemci ile bağlandığınızda nat’ın açtığı dış port sayesinde başka istemcilerin bu dış ip ve port ile sizinle doğrudan iletişim kurmasını sağlayabiliyorsunuz. İşte bu yönteme Hole Punching deniyor. Tabii bu yöntem en kolay UDP protokolü ile yapılabiliyor.

Çok basit olan bu yöntemi basit bir örnek ile açıkladıktan sonra Python ile basit bir uygulama yazarak anlatalım.

1. istemci Metehan.

2. istemci Konuray

ve sunucu…

Metehan ve Konuray sunucuya bağlanarak kendi dış ip ve portlarını sunucuya bildirmiş oluyorlar. Metehan ve Konuray birbirleriyle sesli görüşme yapmak istediklerinde sunucu bu istemcilere birbirlerinin ip ve portunu bildiriyor ve istemciler karşılıklı olarak birbirlerinin ip ve portunu öğreniyorlar.

Sıra geldi karşılıklı iletişimi başlatmaya…

1. Metehan, Konuray’a test mesajı yolluyor. Konuray’ın nat’ı sunucudan veri beklediği için kafası karışıyor ve bu gelen test verisini çöpe atıyor. Yani Metehan ilk veriyi kendisini Konuray’a tanıtmak için yolluyor.

2. Konuray’ın nat’ı bu gelen test verisini iletmese de Metehan’ın ip ve portunu tablosunda tutuyor ve Metehan’dan gelebilecek veriyi beklemeye koyuluyor.

3. Konuray’ da Metehana test mesajı yolluyor, ama Metehan’ın nat’ı zaten Konuray’ı sunucu olarak bellediği için Konuray’dan gelen veriyi Metehan’a iletiyor.

4. Hem Metehan, hem de Konuray birbirlerini sunucu olarak kabul edip birbirlerinden gelecek veriyi beklemeye başlıyorlar. Gelen veriler nat’ları tarafından ilgili yerel ip’lere yollanacak ve karşılıklı veri alışverişi başlamış olacaktır.

Şimdi açıkladığımız bu yöntemi Python ile kodlayalım. Öncelikle sunucu uygulamamız ile başlayalım. Okumaya devam et

Domestic Okuyucu 0.5.1.1 – Özgür RSS/Atom Okuyucusu

Python ve PyQt ile geliştirdiğim özgür bir RSS/Atom okuyucusu olan Domestic Okuyucu adlı uygulamam 0.5.1.1 sürümüne ulaştı ve indirilmeye hazır. Uygulama basit bir arayüze sahip ve oldukça kullanışlıdır. Bu sürümle tespit edilen hatalar giderildi ve hızlandırıldı. Ayrıca bu sürüm ile beraber podcast içeren beslemeler için indirme özelliği eklendi.

Domestic İndirici

Domestic Okuyucu uygulaması, ilgilenen arkadaşların desteğini hala istiyor. Windows için çalıştırılabilir hale getirilmesi lazım. Hata ve öneri bildirisine de ihtiyacı var. Eğer Hata ve öneride bulunmak isterseniz burayı, ben uğraşamam kullanırım diyorsanız burayı tıklayınız. Yalnız indirdiğiniz uygulama kodlarını çalıştırabilmeniz için Python3.x üzerinde PyQt5, feedparser ve beautifulsoup4 kütüphanelerine ihtiyacınız olacak.

Domestic Okuyucu 0.4.3.8 – Özgür RSS/Atom Okuyucusu

Python3.4 ve PyQt5 ile geliştirdiğim, RSS ayrıştırmak için feedparser modülünü kullandığım özgür bir RSS/Atom okuyucusu olan Domestic Okuyucu adlı uygulamam 0.4.3.8 sürümü ile indirilmeye hazır. Uygulama basit bir arayüze sahip ve oldukça kullanışlıdır. Bu sürümle tespit edilen hatalar giderildi. Ayrıca bu sürüm ile beraber podcast içeren beslemeler için de podcast dinleme desteği geldi.

Haber görüntü ekranı

Domestic Okuyucu’nun diğer özelliklerine gelince: Sistem çekmecesine yerleşir ve siz simge durumuna uygulamayı düşürdüğünüzde aralıklarla beslemeleri kontrol eder ve bildirim olarak bilgi verir. Ayrıca sistem çekmecesi simgesine fare okunu götürdüğünüzde Okunmamış, Silinmiş ve Saklanmış haber miktarınının bilgisini verir.

Domestic Okuyucu uygulaması, ilgilenen arkadaşların desteğini istiyor. Windows için çalıştırılabilir hale getirilmesi lazım. Hata ve öneri bildirisine de ihtiyacı var. Eğer Hata ve öneride bulunmak isterseniz burayı, ben uğraşamam kullanırım diyorsanız burayı tıklayınız. Yalnız indirdiğiniz uygulama kodlarını çalıştırabilmeniz için Python3.x üzerinde PyQt5, feedparser ve beautifulsoup4 kütüphanelerine ihtiyacınız olacak.

Domestic Okuyucu 0.3.1.8 – Özgür RSS/Atom Okuyucusu

Python3.4 ve PyQt5 ile geliştirdiğim, RSS ayrıştırmak için feedparser modülünü kullandığım özgür bir RSS/Atom okuyucusu olan Domestic Okuyucu adlı uygulamam 0.3.1.8 sürümü ile indirilmeye hazır. Uygulama basit bir arayüze sahip ve oldukça kullanışlıdır.

Domestic Okuyucu

Domestic Okuyucu

Domestic Okuyucu’nun özelliklerine gelince: Sistem çekmecesine yerleşir ve siz simge durumuna uygulamayı düşürdüğünüzde aralıklarla beslemeleri kontrol eder ve bildirim olarak bilgi verir. Ayrıca sistem çekmecesi simgesine fare okunu götürdüğünüzde Okunmamış, Silinmiş ve Saklanmış haber miktarınının bilgisini verir.

Sistem simgesi bilgisi.

Domestic Okuyucu uygulaması ilgili arkadaşların desteğini istiyor. Windows için çalıştırılabilir hale getirilmesi lazım. Hata ve öneri bildirisine de ihtiyacı var. Eğer Hata ve öneride bulunmak isterseniz burayı, ben uğraşamam kullanırım diyorsanız burayı tıklayınız. Yalnız indirdiğiniz uygulama kodlarını çalıştırabilmeniz için Python3.x üzerinde PyQt5, feedparser ve beautifulsoup kütüphanelerine ihtiyacınız olacak.

Unutmadan, kullanımı engelleyen hata göremesemde bazı ufak hatalar sizi şaşırtabilir 🙂

PyQt’de Eski ve Yeni Sinyal Yapısı ve Kendi Sinyalimizi Oluşturmak

Bir PyQt uygulamasında mevcut tüm widgetler kullanıcı eylemi ya da bir durum değişikliğini belirtmek için sinyaller yayar. Örneğin QPushButton, kendisine tıklandığında bir clicked() sinyali yayar. Bir sinyali kullanabilmek için bir yuvaya(slot) bağlamamız gerekir. Böylece sinyalin yayılmasına yol açan bir durum olduğunda yuva(slot) çalıştırılır. PyQt4 de kullanılan eski tip sinyal yapısı şu şekildedir:

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        "..."
        button = QPushButton(self)
        button.setText("Kapat")

        QObject.connect(button, SIGNAL("clicked()"), self, SLOT("close()"));

QObject, SIGNAL ve SLOT, QtCore içinde mevcuttur… Örnek kodda görüldüğü gibi sinyal ve yuva bir QObject sınıfında belirtiliyor. Tabii connect() methodu QMainWindow içinde de mevcut olduğu için(QObject her sınıfın bir alt sınıfıdır) QObject.connect() yerine self.connect() de kullanabilirsiniz. Qt Designer ile bir pencere tasarladığınızda ayarladığınız sinyaller yukarıdaki kodda yazıldığı gibi dönüştürülür.

Yine PyQt4 de gelen ve PyQt5 de tek tercih olarak sunulan yeni sinyal yapısı ise geliştiricilerin işini kolaylaştıran ve Qt’yi Python ile kullananlar için daha Pythonic bir kodlama yapısı sunan yeni sinyal/yuva yapısı ise şöyledir: Okumaya devam et

Domestic RSS Okuyucu

Domestic RSS Okuyucu, Python kullanılarak yazılmış bir uygulamadır. Python’un 3.4 sürümünü kullanır. Arayüz kütüphanesi olarak PyQt5 ve rss ayıklamak için feedparser modülünü kullanır.

Uygulamayı çalıştırabilmek için Python3.4 üzerine PyQt5, BeautifulSoup4 ve feedparser modülünü kurmalısınız. Domestic RSS Okuyucu sürekli geliştirilmektedir. Şu an 0.1.4.0 sürümü kullanılabilir durumda. Gerekli modülleri kurduktan sonra

pip3 install domestic-reader

komutu verilerek sisteminize kurabilirsiniz. Henüz Windows kullanıcıları için çalıştırılabilir hali mevcut olmadığından Python kullanıcıları için itici gelebilir. İlgilenen birileri çıkar da *.exe’ye çevirirse memnun olurum. Hata, öneri ve katkılarınızı beklerim.

Kullanımına dair görüntüler:

Proje sayfası: https://github.com/mthnzbk/domestic/

PyPi: https://pypi.python.org/pypi/domestic-reader

PyQt Uygulamasında Çoklu Dil Desteği

PyQt ile bir seviyeye kadar ilerledikten sonra insan yaptığı programın kendi dilini konuşmayan kişilerinde kullanmasını isteyebilir.

Python’u öğrendiniz, bir çok hata ve zorlukla karşılaşarak PyQt de ortalama bir seviyeye geldiniz ve artık bir çok insanın kullanacağı bir program yazmaya karar verdiniz. Tabii Türk kullanıcıları size az geldi ve programınızın yurtdışına açılmasını istiyorsunuz. Yani kısaca programınız için dil desteği eklemek istiyorsunuz. PyQt ya da Qt bu konuda ihtiyacımız olan modülleri içeriyor.

Örnek, basit bir uygulama üzerinden anlaşılır bir şekilde nasıl yapılacağını anlatacağım… Uygulamamız bir kullanıcı kayıt dialogu olsun:

Qt Designer ile bu şekilde bir dialog tasarladık ve projeyi kaydedip dosyanın bulunduğu dizinde

pyuic5 proje_dosyası.ui -o dialog.py

komutunu girip Python dosyasını elde ettiniz(PyQt4 kullanıcıları pyuic4 yazmalıdır). Üretilen kod hemen kullanıma hazır olmadığı için ve işimize yaramayan kodlar barındırdığı için ben çalışır duruma getirdiğim kodu buraya koyuyorum. Okumaya devam et

Python da Sonsuz Alt Kategori Sıralama

RSS okuyucu yazılımım için kategorileme özelliği eklemek istiyordum ve bunun sınırsız alt kategori alabilecek şekilde kodlamak istiyordum, ama yazdığım kod sadece bir alt kategoriyi gösterecek şekilde iç içe geçmiş iki for döngüsünden ibaretti. Google da arama yaptığımda karşıma %90 PHp %10 aspx ve diğer dillerde örnekler çıkıyordu ve çoğu kendine has fonksiyon gibi özellikler içerdiğinden kodu anlayamıyordum. Sorumu bir kaç Python forumunda dile getirdim ve çeşitli cevaplar aldım. Yalnız bunlar ya sql koduyla hallediliyordu ya da karışık bir kod kümesiydi. Yine istihzadaki bir konu da php bilen bir arkadaşın örnek kod istemesi üzerine araştırma yaptığımda en kısa ve anlaşılır bir php koduna ulaştım.

function menu ($ust) {
    $git=mysql_query("SELECT * FROM menu WHERE ust_id='$ust'");
    echo "<ul>\n";
    while ($getir=mysql_fetch_array($git)) {
        echo "<li><a href=\"index.php?sayfa=".$getir[id]."\">".$getir[ism]."</a>";
        $ust_git=mysql_query("SELECT * FROM menu WHERE ust_id='$getir[id]'");
        $ust_say=mysql_num_rows($ust_git);
        if ($ust_say > 0) {
            menu ($getir[id]);
        }
        echo "</li>\n";
    }
    echo "</ul>\n";

Bu fonksiyonu Python’a uyarladım ve başarılı oldum.  Okumaya devam et