Örnek¶
Tek Pencere¶
İçinde tek pencere olan basit uygulama yazacağız. İki buton, bir metin giriş alanı, bir etiket bulunan pencer içinde, nesnelerin birbiriyle nasıl etkileştiğini göreceğiz. Ayrıca oluşturduğumuz ekran tasarımını nasıl uygulamaya çevireceğimizi de ilerleyen sayfalarda bulacaksınız.
Designer ile ui dosyasını kullanabilmek için pyside2-uic uygulamasını kullanırız. Linux için aşağıdaki gibi çağırılır:
pyside2-uic ornek.ui > ui_ornek.py
Windows sistemlerde aynı uygulama python dizininin içindeki Scripts dizinindedir. Python kurulumunuz C:\Python3.7 olsun. pyside-uic uygulamasını aşağıdaki gibi çağırırız:
C:\Python3.7\Scripts\pyside2-uic.exe ornek.ui > ui_ornek.py
Şimdi, bu ekran tasarımını python koduna çeviriyoruz. Pyside2-uic yerine qt5 ile gelen uic uygulamasını kullanabilirsiniz. Yukarıdaki komut sonrasında elimizde ui_ornek.py dosyası olacaktır. Bu ui_ornek dosyasının içine hiçbir ek yapılmamalıdır.
import sys
from PySide2.QtWidgets import QApplication, QDialog
from ui_ornek import Ui_DlgOrnek
class MainWindow(QDialog, Ui_DlgOrnek):
def __init__(self, app=None):
super(MainWindow, self).__init__()
self.app = app
self.setupUi(self)
self.show()
def etiket_guncelle(self):
self.lblMetin.setText(self.editMetin.text())
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow(app)
ret = app.exec_()
app.exit()
sys.exit(ret)
Değişikliklerin yapılabileceği main.py dosyasının içeriği yukarıdaki gibidir. Designer ile oluşturulan arayüz dosyasından üretilen sınıf, kendi penceremizi oluşturmak için kullanılmıştır. Ui_DlgOrnek, uic ile üretilen ui_ornek.py içindedir.
Görüldüğü üzere, pencere içindeki yerleşim düzensizdir. Şimdi yapacağımız işlem, pencere boyutlandırıldığında içindekilerin de bu boyutlandırma işlemine uymasını sağlayacaktır. Pencere içinde Layout ayarlaması yapacağız. Bunun için yeniden ornek.ui dosyasını designer uygulamasi ile düzenleyeceğiz.
Tasarıma küçük ekle yapıyoruz. Burada iki buton arasına yatay spacer ekliyoruz. Ardından, iki buton ve yatay spacer’i mouse ile seçerek, sağ mouse tuşuna tıkladığımızda, çıkan popup menünün en alt seçeneğinde Layout görürüz. Üzerine geldiğimizde, Horizontal Layout seçeriz. Böylece, bu iki buton ve spacer, bir yatay layout grubu oluştururlar. Ardından, pencerede boş bir alana sağ tuş ile tıklayıp, yine Layout kısmında ‘Layout Vertically’ seçersek, editbox, label, dikey spacer ve az önce oluşturduğumuz yatay layout grubu yeni bir Layout grubu oluşturur. Designer içinde yapılacaklar bitmiştir. Kaydedip çıkarız.
Bu aşamada, elimizde yeni bir ui dosyası ve yazılmış uygulama bulunmaktadır. Yeni ornek.ui dosyasını pysideuic (ya da pyqt5 icin pyuic) uygulamasından geçirip yeni ui_ornek.py dosyasını oluştururuz. Bu aşamada sadece görsel değişiklik yaptığımız için, main.py içinde değişiklik gerekmez. Uygulamayı yeniden çalıştırırsak, pencerenin boyutlanması ile içindeki nesnelerin de ona göre hareket ettiklerini göreceğiz.
Resim Kullanımı¶
Bir uygulamada nasıl resim kullanabileceğimizi göreceğiz.
Designer kullanarak bir buton, iki label bulunan bir ekran tasarlayacağız. Layout yerleşimi gibi konular yukarıda bahsedildiği için doğruca uygulamaya geçeceğiz.
Şekilde görüldüğü gibi, içini doldurmamız gereken dosyaSec fonksiyonumuz bulunmaktadır. Bu fonksiyon, btnDosyaSec butonu tıklandığında çalışacaktır. Şekilde sağ altta görülen signal/slot editor kısmındadır.
Seçilen resim dosyasını QLabel tipindeki lblResim nesnesinin üzerine yerleştireceğiz. Seçilen dosya adını da yine QLabel tipindeki lblDosyaAdi nesnesi görüntüleyecektir.
Linux sistemlerde:
~$ pyside2-uic resimgosterici.ui > ui_resimgosterici.py
Windows sistemlerde aynı uygulama python dizininin içindeki Scripts dizinindedir. Python kurulumunuz C:\Python3.7 olsun. pyside-uic uygulamasını aşağıdaki gibi çağırırız:
C:\Python3.7\Scripts\pyside2-uic.exe resimgosterici.ui > ui_resimgosterici.py
Yukarıdaki komut ile ekran tasarımını import edebileceğimiz python kaynak koduna çeviririz. Çok yapılan hatalardan birisi de, üretilen bu dosya içine kendi kodlarımızı yazmaya başlamaktır. Dosyanın giriş kısmında ‘WARNING! All changes made in this file will be lost!’ uyarısını dikkate almak gerekir. Arayüz ile kendi yazdığımız kısımları farklı dosyada tutmamız, arayüzde yapılacak değişikliklerden kendi yazdığımız kısmın etkilenmemesini, aynı zamanda da designer ile yaptığınız görsel değişikliklerin devreye alınmasını sağlar.
Aşağıda, üretilmiş olan arayüzü kullanan ve bu haliyle pencereyi görüntüleme dışında hiçbir şey yapmayan kod parçası bulunmaktadır. dosyaSec fonksiyonunu yazarak, uygulamanın istediğimiz işi yapmasını sağlayacağız.
from PySide2.QtWidgets import QApplication, QDialog, QFileDialog
from PySide2.QtGui import QPixmap
from ui_resimgosterici import Ui_dlgResimGosterici
import sys
class MainWindow(QDialog, Ui_dlgResimGosterici):
def __init__(self, app = None):
super(MainWindow, self).__init__()
self.app = app
self.setupUi(self)
self.show()
def dosyaSec(self):
fname, ftype = QFileDialog.getOpenFileName(self, 'Open file',
'',"Image files (*.jpg *.gif)")
self.lblResim.setPixmap(QPixmap(fname))
self.lblDosyaAdi.setText(fname)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow(app)
ret = app.exec_()
app.exit()
sys.exit(ret)
QFileDialog nesnesi, bize dosya seçim penceresi sunar. getOpenFileName metodu ise dosya adı ve dosya tipi içeren ikili sonuc döndürür. Yukarıdaki uygulamada dosyaSec metodunu aşağıdaki kod bloğu ile değiştirdiğimizde, seçtiğimiz dosyanın lblResim nesnesi üzerinde görüntülendiğini görürüz.
def dosyaSec(self):
fname, ftype = QFileDialog.getOpenFileName(self, 'Open file',
'',"Image files (*.jpg *.gif)")
self.lblResim.setPixmap(QPixmap(fname))
Çoklu Pencere¶
İçinde birden fazla pencere olan, bir butonla diğer pencereyi açabildiğimiz uygulamayı yazacağız. Yukarıda yazdığımız resim gösteren uygulamasına ek yaparak, resim bilgilerini gösteren ve resmi boyutlandırmamızı sağlayan bir slider içeren yeni pencere kullanacağız.
Yukarıdaki bilgilerle designer uygulamasını kullanabildiğinizi düşünerek, sadece pencerenin bitmiş halini paylaşacağız. Belgelerin arasına sadece designer kullanımına ayırılmış bir bölüm ekleyeceğiz.
Aşağıdaki resmi kullanarak, resimbilgi.ui adında yeni bir arayüz dosyası oluşturun. Resimdeki nesne isimlendirmesini aynı şekilde oluşturmazsanız, aşağıdaki uygulama düzgün çalışmayacaktır.
from PySide2.QtWidgets import QApplication, QDialog, QFileDialog
from PySide2.QtGui import QPixmap
from PySide2.QtCore import Qt
from ui_resimgosterici import Ui_dlgResimGosterici
from ui_resimbilgi import Ui_dlgResimBilgi
import sys
class BilgiWindow(QDialog, Ui_dlgResimBilgi):
def __init__(self, parent=None, gorsel=None):
super(BilgiWindow, self).__init__()
self.parent = parent
self.resim = gorsel
self.setupUi(self)
self.editDosyaAdi.setText( self.parent.lblDosyaAdi.text())
self.editYukseklik.setText(str(self.resim.height()))
self.editGenislik.setText(str(self.resim.width()))
def resimBoyutlandir(self):
oran = self.sldBuyutme.value()
eski_yukseklik = int(self.editYukseklik.text())
eski_genislik = int(self.editGenislik.text())
yeni_yukseklik = eski_yukseklik * ( oran / 100.0)
yeni_genislik = eski_genislik * (oran / 100.0)
self.parent.lblResim.setPixmap(self.resim.scaled(yeni_genislik, yeni_yukseklik, Qt.KeepAspectRatio))
class MainWindow(QDialog, Ui_dlgResimGosterici):
def __init__(self, app = None):
super(MainWindow, self).__init__()
self.app = app
self.resim = None
self.bilgipenceresi = None
self.setupUi(self)
self.show()
def dosyaSec(self):
if self.bilgipenceresi is not None:
self.bilgipenceresi.close()
fname, ftype = QFileDialog.getOpenFileName(self, 'Open file',
'',"Image files (*.jpg *.gif)")
self.resim = QPixmap(fname)
self.lblResim.setPixmap(self.resim)
self.lblDosyaAdi.setText( fname)
self.bilgipenceresi = BilgiWindow(self, self.lblResim.pixmap())
self.bilgipenceresi.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow(app)
ret = app.exec_()
app.exit()
sys.exit(ret)
Uygulama içinde yeni pencere açmak için, önce o pencereyi tanımlayan sınıfı yazıyoruz. Sınıfı yazarken, arayüz dosyasından ürettiğimiz python dosyasında bulunan sınıftan faydalanıyoruz. Yeni yazdığımız sınıf, arayüz dosyasından üretilen kod içindeki sınıfı miras alarak oluşturulur. Böylece arayüz dosyasında bulunan ve pencerenin nasıl görünmesi gerektiğini, hangi nesnelerin arasında ne tür signal/slot bağlantıları olduğunu, arayüze yerleştirdiğiniz her türlü nesnenin bütün ince ayarları, esas işi yazacağınız kısımdan bağımsız olacaktır.
Nesne isimlerini değiştirmeden yapacağımız bütün arayüz değişikliklerinde, ana uygulamamızda hiçbir şey değiştirmeden pencerenin görünümünü düzenlemek mümkündür.