Python Belgelerim
  • Kapak
  • Django ile Çevirimiçi Ziyaretçi Sayacı Yapımı
  • elementtree Modülü
  • tarfile Modülü
  • zipfile Modülü
  • Python'da Kaynak Kodları Gizlemek
  • Pygame ile Oyun Programlama - Giriş
  • Pygame ile Oyun Programlama - display Modülü
  • Pygame ile Oyun Programlama - draw Modülü
  • Pygame ile Oyun Programlama - surface Modülü
  • Pygame ile Oyun Programlama - image Modülü
  • Pygame ile Oyun Programlama - font Modülü
  • Pygame ile Oyun Programlama - event Modülü
  • Pygame ile Oyun Programlama - rect Modülü
  • Pygame ile Oyun Programlama - music Modülü
  • Pygame ile Oyun Programlama - mixer Modülü
  • Pygame ile Oyun Programlama - time Modülü
  • Pygame ile Oyun Programlama - Sprite 1. Bölüm
  • Pygame ile Oyun Programlama - Sprite 2. Bölüm
  • Pygame ile Oyun Programlama - Sprite 3. Bölüm
  • Pygame ile Oyun Programlama - Sprite 4. Bölüm Son
  • pymunk 2B Fizik Kütüphanesi – Bölüm 1
  • pymunk 2B Fizik Kütüphanesi – Bölüm 2 Son
  • QThread ile QProgressBar Kullanımında Uygulamanın Çökmesi
  • QSettings Sınıfı Kullanımı
  • QLineEdit ile Otomatik ve Sekme ile Tamamlama
  • Qt Designer Kullanımı
  • PyQt Uygulamasında Çoklu Dil Desteği
  • PyQt'de Eski ve Yeni Sinyal Yapısı ve Kendi Sinyalimizi Oluşturmak
  • PyQt5 ile Değişken Parametreli Sinyal Oluşturmak
  • Python da Sonsuz Alt Kategori Sıralama
  • Python ile Hole Punching Yöntemi
Powered by GitBook
On this page

Was this helpful?

QThread ile QProgressBar Kullanımında Uygulamanın Çökmesi

Previouspymunk 2B Fizik Kütüphanesi – Bölüm 2 SonNextQSettings Sınıfı Kullanımı

Last updated 5 years ago

Was this helpful?

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 çözümü bulmuştum. Aradan zaman geçti ve bu sefer 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 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.

Virux