20
Eki

Uzun süredir geliştirmediğim Parçala adlı uygulamamın yeni sürümünü çıkarmış bulunuyorum. Parçala, Hj-Split ile aynı işi gören büyük boyutlu dosyaları parçalara ayırır, birleştirir ve dosya özetini çıkarır; bu sayede birleşen dosya doğru birleşmiş mi diye kontrol etmiş olursunuz. Aşağıda kullanımını gösteren bir video paylaşıyorum…

Doğrulama yaparken neden ikinci sefer dialogu açtığıma gelirsek; dosya özetinin değişmemesi kullanıcıları yanıltabilir diye doğruluğunu kanıtlamak için. Ayrıca gtk-qt tema dönüşümünden kaynaklanan bir sorundan dolayı(sanırım) dosya özetini görebilmek için girdi alanına tıklamam gerekti. Kde üzerinde ve Windows altında sorun yaşanmayacağını düşünüyorum. Uygulamanın kaynak kodlarına buradan ulaşabilirsiniz. Uygulamayı dener, hata alırsanız ve/veya şunu şöyle yap demek isterseniz proje sayfasından istekte bulunabilirsiniz(issue).

Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Virux – GNU/Linux için bir antivirüs yazılımı :P
23
Eyl

QLineEdit’e girdiğimiz bilgiyi kontrol ederek string verilerden oluşan bir listede arama yapıp eşleşen verileri listeleyebiliriz. Bu sayede; bir arama işlemi yapıyorsanız geçmiş kaydı tutabilirsiniz.

Listede arama yapıp eşleşen sonuçları bulan sınıf ise QCompleterdir. Bu sınıfa vereceğimiz bir liste argümanı ile QLineEdit’te otomatik tamamlama yapabiliriz.

import sys
from PyQt4.QtGui import QApplication, QLineEdit, QCompleter

meyveler = ["elma", "armut", "karpuz", "ayva", "erik"]

class LineEdit(QLineEdit):
    def __init__(self, parent = None):
        QLineEdit.__init__(self, parent)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = LineEdit()
    completer = QCompleter(meyveler)
    window.setCompleter(completer)
    window.show()
    sys.exit(app.exec_())

Çok kısa bir kod ile işimizi hallettik. “meyveler” adında bir liste tanımladık ve bu listeye mevye isimlerini girdik. if blokunda ise “completer” adında bir QCompleter nesnesi oluşturduk ve argüman olarak “meyveler” adlı listeyi verdik. QLineEdit’in setCompleter() methoduyla QCompleter nesnemizi tanıttık. Yukarıdaki kodu çalıştırdığınızda girdiğini karaktere göre sonuçları QLineEdit’in altında listeleyecektir. Örneğin ilk karakteri “e” olarak girerseniz “elma” ve “erik” verileri alt alta sıralanacaktır.

Şimdi buna TAB yani sekme tuşuna basıldığında ilk sıradaki verinin QLineEdit’e yazılmasını sağlayalım…

import sys
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication, QLineEdit, QCompleter

meyveler = ["elma", "armut", "karpuz", "ayva", "erik"]

class LineEdit(QLineEdit):
    def __init__(self, parent = None):
        QLineEdit.__init__(self, parent)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Tab:
            for item in meyveler:
                if item.startswith(self.text()):
                    self.setText(item)
                    break
            event.accept()
        else:
            QLineEdit.keyPressEvent(self, event)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = LineEdit()
    completer = QCompleter(meyveler)
    window.setCompleter(completer)
    window.show()
    sys.exit(app.exec_())

QLineEdit sınıfının keyPressEvent() methodunu kullanarak klavyeden basılan tuşları kontrol edecek kodlarımızı yazdık. Eğer klavyeden sekme tuşuna basarsak if bloku işlenecek ve listedeki elemanları sırayla kontrol edip girdiğiniz karakterlerle başlayan bir eleman varsa QLineEdit’e yazdırdık. Sekme tuşuna basılmaması durumunda da ekrana karakter yazmaya devam edebilmek için else blokunu yazdık. Eğer bu kısım olmaz ise klavyeden basılan hiç bir tuş ile QLineEdit’e veri girişi yapamayız.

Örnek olarak verdiğim listeyi veritabanından çektiğiniz verilerden de oluşturabilirsiniz ve aklınızı kullanarak girdiğiniz verileri veritabanına kayıt ederek kalıcı olmasını ve sonraki kullanımlarda hatırlanmasını sağlayabilirsiniz.

Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. QThread ile QProgressBar Kullanımında Uygulamanın Çökmesi
  2. Virux – GNU/Linux için bir antivirüs yazılımı :P
14
Eyl

PyQt kullanarak bir uygulama geliştiriyor ve bu uygulamaya ayarlar ekliyecekseniz QtCore modülünde bulunanan QSettings sınıfını kullanabilirsiniz. QSettings sınıfı ile *.ini-*.conf uzantılı dosya formatlarında ayarlarınızı saklayabilirsiniz.

QSettings sınıfı ayar dosyanızı olağan şeklinde GNU/Linux sistemlerde /home/kullanıcı/.config/ dizini altında kaydeder. Verdiğiniz parametrelere göre uygulamanızın adıyla bir dizin oluşturulup ayar dosyanız bu dizinde saklanabilir.

#-*- coding:utf-8 -*-
from PyQt4.QtCore import *

ayarlar = QSettings("AyarDizini", u"AyarDosyasi")
ayarlar.setValue(u"PencereAyarlari/PencereBoyutu", QSize(300, 300))

print ayarlar.value(u"PencereAyarlari/PencereBoyutu").toSize()

PyQt4.QtCore.QSize(300, 300) # çıktı

Örneğimizde; ayar dosyasını .config/ içerisine AyarDizini adında dizin oluşturup AyarDosyasi.conf adında olacak şekilde ayarladık. QSettings modülünün setValue() methodu ile değer yazdırmadan ne dizin oluşur, ne de dosya. Örnekte ise bu methodu kullanarak ayar bilgilerimizi yazdırdık ve value() methodu ile bu değerimizi yazdırdık. Burada value() methodu bize QVariant nesnesi döndürür ve biz bunu toSize() methoduyla QSize nesnesine çeviririz. Yazdırdığınız değere göre dönüştürme yapmanız gerekir. Bunun için QVariant dökümanını inceliyebilirsiniz.

Bu örnekte dikkat edilecek nokta “PencereAyarlari/PencereBoyutu” kısmıdır. Bu string değer ile ayar dosyamızda PencereAyarlari adında bir grup oluşturmuş ve bu grubun bir üyesi olarak PencereBoyutu‘nu eklemiş olduk. PencereBoyutu’nun değerini ise QSize(300, 300) olarak atamış olduk. Bu kodun ayar dosyasındaki çıktısı ise şöyle olur:

[PencereAyarlari]
PencereBoyutu=@Size(300 300)

Eğer setValue() methodunu kullanırken bölü(/) karakteriyle gruplamayı istemiyorsanız beginGroup() methoduyla grup oluşturabilirsiniz. Devamında yazacağınız değerlerde sadece ayarın ismini ve değerini girerek grup üyesi ayarları tanımlayabilirsiniz. Gruba son vermek için ise endGroup() methodunu kullanabilirsiniz.

#-*- coding:utf-8 -*-
from PyQt4.QtCore import *

ayarlar = QSettings("AyarDizini", u"AyarDosyasi")
ayarlar.beginGroup("PencereAyarlari")
ayarlar.setValue("PencereBoyutu", QSize(300, 300))
ayarlar.endGroup()

print ayarlar.value(u"PencereAyarlari/PencereBoyutu").toSize()
# veya
ayarlar.beginGroup("PencereAyarlari")
print ayarlar.value(u"PencereAyarlari/PencereBoyutu").toSize()
ayarlar.endGroup()

PyQt4.QtCore.QSize(300, 300) # çıktı

Genelde setValue() ile değer tanımladığınızda ayar dosyaya yazılır ve okunmaya hazır hale getirilir. Ancak herhangi bir nedenden dolayı dosyaya yazma işlemi yapılmıyorsa(Hata oluşmadıysa) sync() methodunu kullanarak senkronizasyon işlemi yapabilirsiniz.

Bir ayarı silmek istiyorsanız value() methodunu kullandığınız mantıkla remove() methodunu kullanarak ayar silebilirsiniz.

ayarlar.remove("PencereAyarlari/PencereBoyutu")
# veya
ayarlar.beginGroup("PencereAyarlari")
ayarlar.remove("PencereBoyutu")
ayarlar.endGroup()

Windows’ta ise QSetting sınıfı ayarları regeditte tutar, ama deneyimime dayanarak regedit kaydının sorunlu olduğunu söyleyebilirim. Bu yüzden Windows için de *.ini dosyası kullanmak isteyebiliriz. O zaman QSettings nesnemizi tanımlarken şu şekilde yazmalıyız.

ayarlar =  QSettings("DosyaYolu\dosya.ini", QSettings.IniFormat)

QSettings’e verdiğimiz ilk parametre dosya yolunu, ikinci parametre ise ayar formatının nasıl olacağını belirtir. Burada QSettings.IniFormat ile bir *.ini dosyası formatında olmasını sağladık.

Ayar dosyasının nerede tutulduğunu fileName() methoduyla öğrenebilirsiniz. Bu bilgiyle başlangıç ayarlarını yazmak için dosyanın varlığını kontrol etmenize olanak tanımış olur…

Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. QThread ile QProgressBar Kullanımında Uygulamanın Çökmesi
2
Eyl

Bir çok kez PyQt de QProgressBar’ı uygulama donmadan ilerletmek için QThread kullanmayı denedim, ama her seferinde uygulama çöküyordu. Bunun sebebini öğrenmek ve çözümünü bulmak için zamanında çok araştırma yapmıştım ve ODUN projesiyle uğraşırken çözümü bulmuştum. Aradan zaman geçti ve bu sefer Virux projemde QThread ve QProgressBar kullanmam icap etti. Zaman aralığı çok olduğundan çözümü unutmuştum ve aynı hataları almamla timer event kullanmak zorunda kaldım. Bugün jeton düştü ve ODUN projesinde ilgili koda bakarak nasıl yaptığımı tekrar hatırladım ve yeni sinyal yapısıyla cebelleştikten sonra uygun bir kodla sorunumu hallettim.

Bu konuda QProgressBar’ın uygulamayı dondurmadan ve çökertmeden nasıl kullanacağımızı göreceğiz… Öncelikle basit bir dialog oluşturup QProgressBar ekleyeceğiz ve uygulama çalıştığında QThread sayesinde ilerlemesini sağlayacağız.

import sys
from PyQt4.QtGui import QDialog, QApplication, QProgressBar
from PyQt4.QtCore import QThread

class Thread(QThread):
    def __init__(self, parent):
        QThread.__init__(self, parent)
        self.parent = parent
        self.sayac = 0

    def run(self):
        while self.sayac<1000000:
            self.parent.progress.setValue(self.sayac)
            self.sayac += 1

class Dialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.resize(400,250)
        self.progress = QProgressBar(self)
        self.progress.setGeometry(100,75,200,25)
        self.progress.setProperty("value", 0)
        self.progress.setMaximum(1000000)
        self.thread = Thread(self)
        self.thread.start()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = Dialog()
    gui.show()
    sys.exit(app.exec_())

Dialog sınıfımızda dialogumuzu oluşturduk ve QProgressBar’ı ekledik. setGeometry() methodu ekrandaki konumunu ayarlamayı, setProperty() methodu ile QProgressBar’ın nasıl ilerleme yapacağını(%0-%100, 1/100 gibi), setMaximum() methodu ile de ilerleyişin en fazla hangi rakama kadar çıkacağını ayarladık. Yukarıda oluşturduğumuz Thread sınıfımızı tanımladık ve start() methodu ile de süreçi başlatmış olduk.

Thread sınıfını olabilecek en basit şekilde oluşturmaya çalıştım. Dialog sınıfında kullandığımız start() methodu Thread sınıfımızdaki run() methodunu çalıştıracaktır. Biz bu run() methodunda bir while döngüsü oluşturduk ve sayacı her döngüde +1 artırarak sonucu QProgressBar’ın setValue() methodu aracılığıyla aktardık.

Gayet basit, ama bir kaç tesadüf dışında anlam veremediğiniz hata çıktılarıyla uygulamanızın çöktüğünü göreceksiniz. Buna neden olan şey ise tek satır koddur:

self.parent.progress.setValue(self.sayac)

Nedenini bilmeme rağmen bu kodun varlığı hata oluşmasına ve uygulamanın ölmesine-çökmesine neden oluyor. Bu yüzden hatasız bir ilerleme için döngü içinde bu kodu kullanmayacağız…

QThread’ın msleep() methodu ile milisaniye olarak döngü arasında bekletme yaparak ilerleme çubuğunun hareket etmesini izleme fırsatı yakalayabilirsiniz, ama %99 ihtimal ile çökme yaşayacaksınız. Bu sorunu ortadan kaldırmak için kendi sinyalimizi oluşturacağız(PyQt ye yabancıysanız konuyu bile okumayın bence ;) ). Ve sinyalimizin bir değeri yaymasını sağlayacağız. Dialog sınıfında yazacağımız kod ile bu sinyali yakalayıp taşıdığı değeri QProgressBar’a aktaracağız. Bunu radyo sinyalini yakalayıp sesi duymaya benzetebiliriz…

import sys
from PyQt4.QtGui import QDialog, QApplication, QProgressBar
from PyQt4.QtCore import QThread, SIGNAL

class Thread(QThread):
    def __init__(self, parent):
        QThread.__init__(self, parent)
        self.parent = parent
        self.sayac = 0

    def run(self):
        while self.sayac<1000000:
            self.emit(SIGNAL("setValue(int)"), self.sayac)
            self.sayac += 1

class Dialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.resize(400,250)
        self.progress = QProgressBar(self)
        self.progress.setGeometry(100,75,200,25)
        self.progress.setProperty("value", 0)
        self.progress.setMaximum(10000)
        self.thread = Thread(self)
        self.thread.start()

        self.connect(self.thread, SIGNAL("setValue(int)"), self.progress.setValue)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = Dialog()
    gui.show()
    sys.exit(app.exec_())

Thread sınıfımızda yukarıda söylediğimiz kodu çıkardık ve QThread’ın emit() methodunu kullandık. İlk parametreye SIGNAL() i kullanarak yayılacak sinyalin adını belirledik ve son parametreye ise yayılacak bilgiyi girdik. Biz burada tek bilgi yaymasını sağladık, ama bunu çoğaltabilirsiniz…

Dialog sınımızda self.thread.start() kod parçasıyla sürecimizi başlattık ve sinyay yaymaya başladık. QDialog’ sınıfının connect() methodu ile bu işlemi gerçekleştirdik. İlk parametreye hangi nesnenin sinyalini dinleyeceğimizi yazdık; ikinci parametrede ise hangi sinyali dinleyeceğimizi; son parametremizde ise sinyalin taşıdığı bilgiyi nereye aktaracağımızı yazdık. setValue() methodu tek parametre aldığına göre ve “setValue(int)” sinyali tek bilgi taşıdığına göre taşınan bilgi QProgressBar’ aktarılmış oldu ve sorunsuz bir şekilde ilerleme çubuğunun ilerleyişini görme imkanımız doğdu.

Ek olarak sinyal ismine bakıpta fonksiyon ismi gibi bir isim vermek, kaç bilgi taşıyacaksa o kadar argüman yazmak(“setValue(int1, int2, intN)” gibi…) gibi bir zorunluluk varmış sanmayın. Bu şekilde sinyalimiz hem anlaşılır, hemde şık durmuş oluyor…

PyQt ile ilgili sorularınıza ileri düzey olmadığı sürece yanıtlamaya çalışabilirim…

Yazım hatası varsa bildiriniz.
Bu yazı Creative Commons-BY-SA ile lisanslanmıştır. Bu yazıyı ilk sahibini belirtmek ve aynı lisansla dağıtmak koşuluyla kullanabilirsiniz.

Benzer Yazılar:

  1. Virux – GNU/Linux için bir antivirüs yazılımı :P