PYQT Denemeleri-7
Wiki.Pardus-Linux.Org sitesinden
Giriş
Bu çalışmamızda 4. ve 5. denemelerimizdeki resim gösteren programlarımızdan daha rahat kullanılabilir bir program yapacağız.Bu çalışmamızda bir dizin içindeki resimleri "listwidget" parçacığı içine listeleyeceğiz ve o isimlerden hangisine tıklarsak o isimdeki resim görünecek. Bir resim her şeye bedeldir.Yani şöyle bir şey yapacağız:
Arayüzün Oluşturulması
Öncelikle qt designer ile arayüzümüzü kolayca oluşturalım.Programı açınca açılan ilk pencerede "main window" u seçip "olustur" a tıklayalım.
Soldaki parçacık kutusu bölümünden "Buttons" kısmından iki adet "push button" , "display widgets" bölümünden bir adet "label", "Item widgets" bölümünden bir adet "list widget" parçalarını farenin sol tuşu ile tıklayıp ana pencere "main window" üzerine sürükleyerek bırakın ve resimde olduğu gibi yerleştirin.Üstteki "label" in boyutunu büyütmek için üstüne tıklayın.Tıkladığınızda üstünde mavi noktalar oluşur.Bu noktalara tıkladığınızda boyutlarını değiştirebilirsiniz.
Daha sonra yerleştirdiniz parçacıklara çift tıklayarak isimlerini resimdeki gibi değiştirin.
Şimdi sıra düğmelere görev atamakta."Düzenle > Sinyal slot düzenle" yi tıklayın yada "f4" e basın."Kapat" tuşuna tıklayıp tuşu bırakmadan biraz sürükleyip boşluk üzerinde bırakın.Sakın başka bir parçacık üzerine bırakmayın.
Yeni bir pencere açılacak.Açılan pencerede birinci bölümden "clicked()" seçip, aşağıdaki "Tüm sinyal ve slotları göster" tıklayıp, sağdaki bölümden "close()" seçip, tamam deyip kapatıyoruz.
Aynı işlemi "Ekle" için de yapın.
Son olarak "list widget" parçacığına tıklayıp sürükleyin ve "label" parçacığı üzerinde bırakın.
Yeni bir pencere açılacak.Açılan pencerede birinci bölümden "currentTextChanged(QString)" seçip,, sağdaki bölümden "setText(QString)" seçip, tamam deyip kapatıyoruz.
Bu yaptığımız atama sayesinde "list widget" parçacığında yer alan elemanlardan hangisine tıklarsak o elemanın adı aynı anda "label" parçacığına yazacak.Bu ne işimize yarayacak sorusuna biraz sonra geleceğiz.
Arayüzle işimiz bitti.Şimdi yaptığımız bu formu bir yere resim.ui uzantısı ile kaydedin.İsim önemli değil ama son ek ".ui" olmalı.Eğer kaydettiğiniz yerde aynı isimde başka dosya varsa üzerine yazmaya çalışır.Buna dikkat edin.
Kodların Ayarlanması
resim.ui adıyla kaydedilmiş dosyanın olduğu dizine gidip konsolda şu komutu verin:
| Kod: |
pyuic4 resim.ui -o resim.py |
Artık elimizde az önce yaptığımız formun kodları var.Ancak bu kodların henüz hazır olmadığını ve bir kaç düzenleme yapmamız gerektiğini önceki denemelerden biliyorsunuz.
resim.py dosyasını açıp en altına şu kodları yapıştırıyoruz:
| Kod: Dosyanın sonuna bu kodları ekleyin |
app = QtGui.QApplication(sys.argv) window = QtGui.QMainWindow() ui = Ui_MainWindow() ui.setupUi(window) window.show() sys.exit(app.exec_()) |
Şimdi sıra düğmelere atayacağımız görevlerin kodlarını ayarlamakta.
Daha önceki denemelerimizden tuşlara görev atayabilmemiz için bu kodları fonksiyon içinde yazacağımızı biliyoruz.Ancak bazı sorularımız var:
Soru 1: Bir dizin içindeki dosyaları "list widget" parçacığına nasıl ekleyeceğiz?
Öncelikle Pythonda bir dizinin içeriğini nasıl aldığımızı hatırlayalım:" os.listdir("./") " Bu bu bir ada atayalım:" dizin =os.listdir("./") " Bu komut bize resim.py dosyasının içinde bulunduğu dizinin içindeki dosyaları verir.Ancak benim resimlerim ve resim.py dosyam aynı dizinde değil.Resim.py dosyamın olduğu dizin içinde "lost dizininde.O zaman kodum şöyle olacak:" dizin =os.listdir("./lost")
Ancak ben bu dizin içinde yer alan dosyalardan sadece".jpg" dosyalarını eklemek istiyorum.Bunun için şu kodu kullanıyoruz:"string.find()".Bo kod bize o dosyanın istediğimiz dosya olup olmadığını farklı bir yolla söyleyecek.Yani istediğiz dosya ise "1" değil ise "0" cevabını verecek.Bu kodu dizin içindeki her dosya için uygulamamız gerektiğinden bir "for loop" yazıyoruz:
| Kod: |
dizin = os.listdir("./lost")
for resim in dizin:
res = string.find(resim, ".jpg")
|
Bu kod bize dosyada yer alan her ".jpg" uzantılı dısya için "1" cevabını verecek.O zaman bu cevap üzerinden kodumuza devam edebiliriz:
| Kod: |
if res > 0: ui.listWidget.insertItem(0,resim) |
Bu kod da ".jpg" uzantılı dosyaları "list widget" parçacağına ekler.Ancak dosyaları uzantılarıyla beraber ekler.Yani elimizde:
ali.jpg
veli.jpg
deli.jpg
şeklinde bir liste oluşur.Bu ".jpg" uzantılarını da basit bir kodla listemizden çıkartabiliriz:
| Kod: |
resim = string.strip(resim, ".jpg") |
"list widget" parçacığına dizin içindekileri eklemek için yazmamız gereken kodların hepsi bu kadar.Kodlarımızın son hali şöyle:
| Kod: |
def sor1(self):
dizin = os.listdir("./lost")
for resim in dizin:
res = string.find(resim, ".jpg")
if res > 0:
resim = string.strip(resim, ".jpg")
ui.listWidget.insertItem(0,resim)
|
Soru 2:"list widget" içinde yer alan elemanlara tıkladığımızda resim göstermesini nasıl sağlayacağız?
Bu soruya cevap bulana kadar göbeğim çatladı dersem yalan olmaz.Çok hayati bir soru ama cevap hiç bir yerde yok.Ne yapalım bizde deneme yanılma yoluyla şunu dene bunu dene yapmadığımız şey kalmadı.
Resim göstermek için resmi "QtGui.QPixmap( "resim-1.jpg" )" olarak tanımlayıp "label" parçacığına atayacağımızı "ui.label.setPixmap(res1 )" daha önceki denemelerimizden biliyoruz.Burada resimlerimiz dizin içinde olduğu için " QtGui.QPixmap("./lost/clare.jpg") " yazacağız.Ancak dosyamızın adı her tıklamada değişeceği için sabit bir isim atayamayız ve bu değişen adı bir yerden almalıyız.Malesef bu adı "list widget" dan almayı başaramadım ama başka bir yöntem buldum.Bu yöntem arayüzü hazırlarken en sonunda yaptığımız "List widget" a tıklayıp dosyanın adını "label" parçacığına yazan yöntem.Her tıklamada değişen adın "label" parçacığına yazması bize gerekli dosyanın adını verecek ve biz bu adı "ui.label.text()" yardımıyla alacağız.Yani ikinci fonksiyonumuzun son hali şöyle olacak:
| Kod: |
def sor2(self):
resim = QtGui.QPixmap("./lost/"+ui.label.text()+".jpg")
ui.label.setPixmap(resim)
|
Fonksiyonlarımızı bir sınıf içine yazıyoruz:
| Kod: |
class resim:
def __init__(self, ui):
self.ui = ui
def sor1(self):
dizin = os.listdir("./lost")
for resim in dizin:
res = string.find(resim, ".jpg")
if res > 0:
resim = string.strip(resim, ".jpg")
ui.listWidget.insertItem(0,resim)
def sor2(self):
resim = QtGui.QPixmap("./lost/"+ui.label.text()+".jpg")
ui.label.setPixmap(resim)
|
Şimdi sıra yazdığımız kodları "Ekle" tuşuna ve "list widget" parçacığına atamak da.Aslında daha önceki bölümleri okumuşsanız buradan sonra neler yapacağımızı artık çok iyi biliyorsunuzdur.Dosyadan aşağıda verdiğim bölümü bulun:
| Kod: |
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.pushButton_2,QtCore.SIGNAL("clicked()"),MainWindow.close)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"),MainWindow.close)
QtCore.QObject.connect(self.listWidget,QtCore.SIGNAL("currentTextChanged(QString)"),self.label.setText)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
Biz "def retranslateUi(self, MainWindow):" yardımıyla biliyoruz ki:
| Kod: |
ui.pushButton = (Ekle tuşu) |
Bu tuşun içinde geçtiği komutun en son bölümünü
| Kod: |
MainWindow.close |
silip (ui.pushButton_2 = (kapat) a dokunmuyoruz o zaten kapatmak için kullanılacak)
| Kod: |
self.resim.sor1 (resim sınıfımız, sor1 bu sınıf içindeki fonksiyonumuz: Yukarıda yazdığımız kodlar) |
kodunu yazıyoruz. Burayı :
| Kod: |
QtCore.QObject.connect(self.listWidget,QtCore.SIGNAL("currentTextChanged(QString)"),self.label.setText)
|
kopyalayıp
bir altına yapıştırıyoruz ve son bölümünü
| Kod: |
self.label.setText |
şununla
| Kod: |
self.resim.sor2 |
değiştiriyoruz. Bu kopyalama ile yaptığımız şey "List widget" a tıkladığımızda "label " a isim yazmamızı sağlayan sinyalin aynı zamanda o " label" da resim göstermek için yazdığımız fonksiyonun da çalışması için sinyal göndermesini sağlamak.Bu tek sinyalle iki işi ("label"a isim yazmak ve orada resim göstermek) o kadar hızlı yapacak ki siz birincisini göremeyeceksiniz.Yani siz sadece resim göreceksiniz.
Son olarak da
| Kod: |
self.retranslateUi(MainWindow) |
yazısını hemen altına
| Kod: |
self.resim = resim(self) |
yazıyoruz.
Yani son hali şöyle:
| Kod: |
self.retranslateUi(MainWindow)
self.resim = resim(self)
QtCore.QObject.connect(self.pushButton_2,QtCore.SIGNAL("clicked()"),MainWindow.close)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"),self.resim.sor1)
QtCore.QObject.connect(self.listWidget,QtCore.SIGNAL("currentTextChanged(QString)"),self.label.setText)
QtCore.QObject.connect(self.listWidget,QtCore.SIGNAL("currentTextChanged(QString)"),self.resim.sor2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
Son olarak dosyanın en üstüne şu kodları ekliyoruz:
| Kod: |
import sys, os, string |
Artık programımız çalışır durumda.Programı çalıştırmak için resim.py dosyasının olduğu dizinde konsolda şu komutu verin:
| Kod: |
python resim.py |
Karşılaştığınız sorunlar için forumda açtığım konuya yazabilirsiniz.
Adres: http://forum.pardus-linux.org/viewtopic.php?p=86032#86032
Bu yazı PYQT Denemeleri bölümünün bir parçasıdır.
| 1. PYQT Denemeleri-1 | 2. PYQT Denemeleri-2 |
| 3. PYQT Denemeleri-3 | 4. PYQT Denemeleri-4 |
| 5. PYQT Denemeleri-5 | 6. PYQT Denemeleri-6 |
| 7. PYQT Denemeleri-7 | 8. PYQT Denemeleri-8 |












