20 Ağustos 2014 Çarşamba

PyQt Akıllı Diyaloglar

     Akıllı diyalogların akılsız diyaloglardan oluşturulma yönünde bir farkı yoktur. Sadece akılsız diyaloglara oranlara birtakım avantajları vardır. Bu avantajlar ise kullanılacak duruma göre dezavantaj da olabilir. Akıllı ve akılsız diyalogların farklılıklarına kısaca değinelim.

Akılsız diyaloglarda bir pencere açıldığında onay butonları veya çarpı işaretinden kapatılması sonucu sadece kullanıcıya görünmez olur; ama bellekte yer kaplar. Ve her yeni çağrılışında yeni bir pencere oluşturmaktadır. Bunu diyalog sonuna ekleyebileceğimiz del diyalog komutu ile çözebiliriz.
Ayrıca akılsız diyaloglar kendisini çağıran pencere ile etkileşim içinde değildir. Yani yapılan değişiklikler onaylanmadan görüntülenemez. Onaylandığında da kalıcı olarak değişiklik yapılmış olur. Bu durumda önceki duruma dönülemez.

İşte bu bahsettiğimiz durumları akıllı diyaloglar giderir. Akılsız diyaloglarda yapılan değişiklikler, kendisini çağıran pencerede gerçekleşmekte; fakat akıllı diyaloglarda yapılan değişiklikler diyaloğun kendisinde yapılır.
Diyalog kapatıldıktan sonra kendisini sildiğinden bellekte yer kaplama durumu da söz konusu değildir. Bunu da örneğimizde self.setAttribute(Qt.WA_DeleteOnClose) kodu ile sağlayacağız. Bu kodu akılsız diyaloglara koyamıyoruz; çünkü akılsız diyaloglar kendisini çağıran pencereye değişikliklere dair veri aktarmaktadır. Oysaki bu değişiklikler akıllı diyaloglarda kendi içinde halledilmiştir.

Şimdi bir metnin yazı tipini akıllı diyalog ile değiştirebileceğimiz bir örnek yapalım. Kodlarımız şu şekilde:
from PyQt4.QtCore import *
from PyQt4.QtGui import *

simgeler = 'D:/Simgeler/orange-moonlight-icons/png/64x64/'
# simgeler => http://dryicons.com/free-icons/preview/orange-moonlight-icons/

class yaziTipiDiyalogu(QDialog):
    def __init__(self, parent=None):
        super(yaziTipiDiyalogu, self).__init__(parent)
        self.parent = parent

        self.setAttribute(Qt.WA_DeleteOnClose)
        # Üst satırda yazmış olduğumuz kod pencere kapatılırken doğrudan silinmesini sağlar.
        # Böylelikle bellekte yer kaplamamış olur.

        self.yaziTipiListesi = QFontComboBox()
        self.yaziTipiListesi.setCurrentFont(QFont(self.parent.yaziTipi))

        butonKutusu = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        #Butonların üstündeki yazıları Tamam ve İptal olarak değiştirelim.
        butonKutusu.button(QDialogButtonBox.Ok).setText('Tamam')
        butonKutusu.button(QDialogButtonBox.Cancel).setText('İptal')
        self.connect(butonKutusu, SIGNAL('accepted()'), self.kabul)
        self.connect(butonKutusu, SIGNAL('rejected()'), self.reject)

        pencere = QGridLayout() # Izgara pencere düzeni
        pencere.addWidget(QLabel('Yazı Tipi Seçimi: '), 0, 0)
        pencere.addWidget(self.yaziTipiListesi, 0, 1)
        pencere.addWidget(butonKutusu, 1, 0, 1, 2)
        self.setLayout(pencere)

        self.setWindowTitle("Yazı Tipini Ayarla")
        self.setWindowIcon(QIcon(simgeler + 'edit.png'))

    def kabul(self):
        self.parent.yaziTipi = self.yaziTipiListesi.currentFont().family()
        self.parent.label.setText(self.parent.metin % self.parent.yaziTipi)
        QDialog.accept(self)

class akilliDiyaloglar(QDialog):
    def __init__(self, parent=None):
        super(akilliDiyaloglar, self).__init__(parent)
        self.yaziTipi = 'Comic Sans MS'
        self.metin = '
PythonDersleri.com
' self.label = QLabel(self.metin % self.yaziTipi) yatayKutu = QVBoxLayout() yatayKutu.addWidget(self.label) yaziTipiDugme = QPushButton('Yazı Tipini Değiştir') self.connect(yaziTipiDugme, SIGNAL('pressed()'), self.yaziTipiDegistir) yatayKutu.addWidget(yaziTipiDugme) self.setLayout(yatayKutu) self.setWindowTitle("Akıllı Diyaloglar") self.setWindowIcon(QIcon(simgeler + 'page.png')) def yaziTipiDegistir(self): diyalog = yaziTipiDiyalogu(self) diyalog.show() uygulama = QApplication([]) anaPencere = akilliDiyaloglar() anaPencere.show() uygulama.exec_()
Kodlarımızı çalıştırdığımızda karşımıza şöyle bir pencere gelecektir:
"Yazı Tipini Değiştir" butonuna tıkladığımızda ise pencere şu şekle gelecektir:
Buradaki kodlarımızda "Tamam" butonuna tıkladığımızda oluşan kabul durumunu kabul metodu ile bu diyalog içinde gerçekleştirdik. Bu sayede pencereyi kapattıktan sonra bellekten silebiliyoruz. İptal denildiğinde ise hiç bir değişiklik olmadan pencereyi kapatıp bellekten silebiliyoruz.

Akıllı diyaloglarla ilgili dikkatinizi çekmek istediğim bir nokta daha var. "Yazı Tipini Ayarla" penceremizi sürükleyip ana pencere üzerinden başka bir yere çektikten sonra ana pencere üzerinde "Yazı Tipini Değiştir" butonuna tekrar tıklamanıza yani ana pencere üzerinde işlem yapmanıza izin verir, bu durum akılsız diyaloglarda yoktur. Bu durum yapacağınız uygulamalara göre avantaj ya da dezavantaj oluşturabilir. Buna dikkat etmekte fayda var.

Akıllı diyaloglarda bir de kullanıcının yaptığı değişikliklerin kalıcı olmadığından bahsettik. Peki bu durum nasıl oluyor? Penceremize bazı uygulamalarda görmüş olabileceğiniz "Uygula" ve "Sıfırla" isminde iki buton daha eklememiz gerekiyor. Bu butonları da ekledikten sonra bütün butonları metotlara bağlamamız gerekiyor.
# Butonların eklenmiş hali
butonKutusu = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Apply | QDialogButtonBox.Reset)
butonKutusu.button(QDialogButtonBox.Apply).setText('Uygula')
# Butonun üzerindeki yazıyı "Uygula" yaptık
butonKutusu.button(QDialogButtonBox.Reset).setText('Sıfırla')
# Butonun üzerindeki yazıyı "Sıfırla" yaptık 


# Eklediğimiz butonların sinyallerini metotlara bağlıyoruz
self.connect(butonKutusu.button(QDialogButtonBox.Apply), SIGNAL('clicked()'), self.uygula)
self.connect(butonKutusu.button(QDialogButtonBox.Reset), SIGNAL('clicked()'), self.sifirla)


# Tüm butonlara ait metotların son hali de bu şekilde olmalı
def kabul(self):
        self.parent.yaziTipi = self.yaziTipiListesi.currentFont().family()
        self.parent.label.setText(self.parent.metin % self.parent.yaziTipi)
        QDialog.accept(self)

def uygula(self):
        self.parent.label.setText(self.parent.metin % self.yaziTipiListesi.currentFont().family())

def sifirla(self):
        self.parent.label.setText(self.parent.metin % self.parent.yaziTipi)
        self.yaziTipiListesi.setCurrentFont(QFont(self.parent.yaziTipi))

def reject(self):
        self.parent.label.setText(self.parent.metin % self.parent.yaziTipi)
        QDialog.reject(self)
Uygulamamıza yukarıdaki kodları da ekleyip çalıştırdığımızda bahsetmiş olduğumuz durumları gerçekleştirebilir hale gelmekteyiz. Pencerelere ait ekran görüntüsü de şu şekilde olacaktır:
Burada listeden yazı tipini seçtikten sonra Uygula diyerek kalıcı değişiklik yapmadan ve pencere kapanmadan yaptığımız değişiklikleri görebiliriz. Sıfırla diyerek de pencereyi açtığımızdaki ilk haline döndürebiliriz.


Kaynaklar:
http://zetcode.com/gui/pyqt4/dialogs/
Mustafa Başer - Python Kitabı

0 yorum :

Yorum Gönder