python arayüz oluşturma / Python ile Kullanıcı Arayüzü Tasarımı (GUI) – DATAI TEAM

Python Arayüz Oluşturma

python arayüz oluşturma

Öğretici: Visual Studio'da Python ile çalışma

Şunun için geçerlidir:evetVisual Studio hayır Mac için Visual Studio hayır Visual Studio Code

Python güvenilir, esnek, öğrenmesi kolay ve tüm işletim sistemlerinde kullanımı ücretsiz olan popüler bir programlama dilidir. Python hem güçlü bir geliştirici topluluğu hem de birçok ücretsiz kitaplık tarafından desteklenir. Dil; web uygulamaları, web hizmetleri, masaüstü uygulamaları, betik oluşturma ve bilimsel bilgi işlem dahil olmak üzere her türlü geliştirmeyi destekler. Birçok üniversite, bilim adamı, gündelik geliştirici ve profesyonel geliştirici Python kullanır.

Visual Studio, Python için birinci sınıf dil desteği sağlar. Bu öğretici aşağıdaki adımlarda size yol gösterir:

Önkoşullar

Visual Studio için Python Araçları yüklü olarak Visual Studio'nun önceki bir sürümünü de kullanabilirsiniz. Bkz . Visual Studio'da Python desteğini yükleme.

1. Adım: Yeni bir Python projesi oluşturma

Proje, Visual Studio'un tek bir uygulama oluşturmak için bir araya gelen tüm dosyaları yönetme şeklidir. Uygulama dosyaları kaynak kodunu, kaynakları ve yapılandırmaları içerir. Proje, tüm proje dosyaları arasındaki ilişkileri resmileştirir ve korur. Proje, birden çok proje arasında paylaşılan dış kaynakları da yönetir. Proje, uygulamanızın zahmetsizce genişletilmesine ve büyümesine olanak tanır. Projeleri kullanmak planlanmamış klasörlerde, betiklerde, metin dosyalarında ve belleğinizde ilişkileri el ile yönetmekten çok daha kolaydır.

Bu öğretici, tek bir boş kod dosyası içeren basit bir projeyle başlar.

  1. Visual Studio'daDosya Yeni>Proje 'yi (Ctrl+Shift+N) seçerek>Yeni Proje iletişim kutusunu açın. Burada farklı dillerdeki şablonlara göz atıp projeniz için bir şablon seçip Visual Studio'da dosyaların nereye yerleştirileceğini belirtebilirsiniz.

  2. Python şablonlarını görüntülemek için sol taraftaki Yüklü>Python'ı seçin veya "Python" araması yapın. Arama özelliğini kullanmak, diller ağacındaki konumunu anımsayamıyorsanız şablonu bulmanın harika bir yoludur.

    Python proje şablonlarıyla Yeni proje oluştur iletişim kutusunu gösteren ekran görüntüsü.

    Visual Studio'daki Python desteği Bottle, Flask ve Django çerçevelerini kullanan web uygulamaları da dahil olmak üzere çeşitli proje şablonları içerir. Ancak bu kılavuzun amaçları doğrultusunda boş bir projeyle başlayalım.

  3. Python Uygulaması şablonunu seçin, proje için bir ad belirtin ve Tamam'ı seçin.

  4. Birkaç dakika sonra Visual Studio, proje yapısını Çözüm Gezgini penceresinde (1) gösterir. Varsayılan kod dosyası düzenleyicide (2) açıktır. Özellikler penceresi (3) diskteki tam konumu da dahil olmak üzere Çözüm Gezgini'de seçilen öğeler için ek bilgiler de gösterir.

    Visual Studio'da açılan yeni projeyi gösteren ekran görüntüsü.

  5. Projenizdeki dosya ve klasörlere göz attığınız Çözüm Gezgini hakkında bilgi edinmek için birkaç dakikanızı ayırın.

    Özellikleri göstermek için genişletilmiş Çözüm Gezgini ekran görüntüsü.

    (1) Yeni Proje iletişim kutusunda belirttiğiniz adı kullanarak projeniz kalın olarak vurgulanır. Diskte, bu proje proje klasörünüzdeki bir .pyproj dosyasıyla temsil edilir.

    (2) En üst düzeyde, varsayılan olarak projenizle aynı ada sahip olan bir çözüm bulunur. Disk üzerindeki bir .sln dosyasıyla temsil edilen bir çözüm, bir veya daha fazla ilgili proje için bir kapsayıcıdır. Örneğin, Python uygulamanız için bir C++ uzantısı yazarsanız, bu C++ projesi aynı çözümde olabilir. Çözüm, ayrılmış test programlarına yönelik projelerle birlikte bir web hizmeti projesi de içerebilir.

    (3) Projenizin altında kaynak dosyaları görürsünüz, bu durumda yalnızca tek bir .py dosyası görürsünüz. Bir dosya seçildiğinde , özellikler Özellikler penceresinde görüntülenir. Bir dosyaya çift tıklandığında dosya o dosyaya uygun şekilde açılır.

    (4) Ayrıca projenin altında Python Ortamları düğümü bulunur. Genişletildiğinde, kullanabileceğiniz Python yorumlayıcılarını görürsünüz. Bu ortama yüklenen kitaplıkları görmek için yorumlayıcı düğümünü genişletin (5).

    geçerli komutların menüsüne erişmek için Çözüm Gezgini herhangi bir düğüme veya öğeye sağ tıklayın. Örneğin, Yeniden Adlandır komutu, proje ve çözüm de dahil olmak üzere herhangi bir düğümün veya öğenin adını değiştirmenize olanak sağlar.

  1. Visual Studio'da Dosya>Yeni Proje'yi> seçin veya Ctrl ShiftNtuşlarına++ basın. Farklı dillerde şablonlarda arama yapabileceğiniz ve şablonlara göz atabileceğiniz Yeni proje oluştur ekranı görüntülenir.

  2. Python şablonlarını görüntülemek için python araması yapın. Arama, diller ağacındaki konumunu anımsayamıyorsanız şablonu bulmanın harika bir yoludur.

    Python proje şablonlarıyla Yeni proje oluştur iletişim kutusunu gösteren ekran görüntüsü.

    Visual Studio'daki Python web desteği Bottle, Flask ve Django çerçevelerindeki web uygulamaları gibi çeşitli proje şablonları içerir. Python'ı Visual Studio Yükleyicisi yüklerken bu şablonları yüklemek için isteğe bağlı altındaki "Python Web Desteği" seçeneğini işaretleyin. Bu öğretici için boş bir projeyle başlayın.

  3. Python Uygulaması şablonunu ve ardından İleri'yi seçin.

  4. Yeni projenizi yapılandırın ekranında proje için bir ad ve dosya konumu belirtin ve oluştur'u seçin.

    Yeni proje Visual Studio'da açılır.

    • Visual Studio Çözüm Gezgini penceresinde proje yapısı (1) gösterilir.
    • Varsayılan kod dosyası düzenleyicide (2) açılır.
    • Özellikler penceresinde, diskteki tam konumu (3) dahil olmak üzere Çözüm Gezgini'de seçilen öğeyle ilgili daha fazla bilgi gösterilir.

    Visual Studio'da açılan yeni projeyi gösteren ekran görüntüsü.

  5. Projenizdeki dosya ve klasörlere göz atabileceğiniz Çözüm Gezgini hakkında bilgi sahibi olun.

    Özellikleri göstermek için genişletilmiş Çözüm Gezgini ekran görüntüsü.

    • En üst düzeyde, varsayılan olarak projenizle (1) aynı ada sahip olan çözüm bulunur.

      Diskte .sln dosyası olarak gösterilen bir çözüm, bir veya daha fazla ilgili proje için bir kapsayıcıdır. Örneğin, Python uygulamanız için bir C++ uzantısı yazarsanız, bu C++ projesi aynı çözümde olabilir. Çözüm, bir web hizmeti için bir proje ve ayrılmış test programlarına yönelik projeler de içerebilir.

    • Yeni proje oluştur iletişim kutusunda belirttiğiniz adla projeniz kalın (2) olarak görüntülenir. Diskte proje, proje klasörünüzdeki bir .pyproj dosyasıdır.

    • Projenizin altında kaynak dosyalar vardır; bu durumda yalnızca tek bir .py dosyası (3). Bir dosya seçildiğinde özellikler, Özellikler penceresinde görüntülenir (Özellikler penceresini görmüyorsanız, Çözüm Gezgini başlığındaki anahtara tıklayın). Bir dosyaya çift tıklandığında dosya o dosyaya uygun şekilde açılır.

    • Ayrıca projenin altında Python Ortamları düğümü (4) bulunur. Kullanılabilir Python yorumlayıcılarını göstermek için düğümü genişletin.

    • Bu ortamda yüklü kitaplıkları görmek için yorumlayıcı düğümünü genişletin (5).

    geçerli komutların bağlam menüsünü göstermek için Çözüm Gezgini herhangi bir düğüme veya öğeye sağ tıklayın. Örneğin, Yeniden Adlandır , proje ve çözüm dahil olmak üzere bir düğümün veya öğenin adını değiştirmenize olanak tanır.

Sonraki adım

Daha derine git


Ek kaynaklar

Nesne Tabanlı Programlama (Devamı)¶

Uyarı

Bu makale yoğun bir şekilde geliştirilmekte, içeriği sık sık güncellenmektedir.

Geçen bölümde verdiğimiz bilgiler sayesinde miras alma konusunun temelini oluşturan taban sınıf, alt sınıf ve türeme gibi kavramlarla birlikte ve object gibi araçların ne olduğunu ve ne işe yaradığını da öğrendik. Dolayısıyla artık miras alma mekanizmasına dair daha renkli, daha teşvik edici örnekler verebiliriz. Böylece, belki de gözünüze ilk bakışta pek de matah bir şey değilmiş gibi görünen bu ‘miras alma’ denen mekanizmanın aslında ne kadar önemli bir konu olduğuna sizleri ikna edebiliriz.

Bu bölümde ayrıca geçen bölümlerde incelemeye fırsat bulamasak da nesne tabanlı programlama kapsamında incelememiz gereken başka konuları da ele alacağız.

Nesne tabanlı programlamadan ilk bahsettiğimiz derste, nesne tabanlı programlama yaklaşımının grafik arayüz tasarımı için biçilmiş kaftan olduğundan söz etmiştik hatırlarsanız. Bu bölümde inceleyeceğimiz konuların bazılarını grafik arayüz tasarımı eşliğinde anlatacağız. Grafik arayüz programlamanın bize sunduğu düğmeli-menülü görsel programların, nesne tabanlı programlamaya ilişkin soyut kavramları somut bir düzleme taşımamıza imkan tanıması sayesinde, nesne tabanlı programlamaya ilişkin çetrefilli konuları daha rahat anlama fırsatı bulacağız.

Tkinter Hakkında¶

Hatırlarsanız, önceki derslerimizde birkaç kez Tkinter adlı bir modülden söz etmiştik. Tkinter, Python kurulumu ile birlikte gelen ve pencereli-menülü modern programlar yazmamızı sağlayan grafik arayüz geliştirme takımlarından biridir.

Tkinter bir standart kütüphane paketi olduğu için, Python programlama dilini kurduğunuzda Tkinter de otomatik olarak kurulur1.

Elbette Python’da grafik arayüzlü programlar yazmamızı sağlayacak tek modül Tkinter değildir. Bunun dışında PyQt, PyGI ve Kivy gibi alternatifler de bulunur. Ancak Tkinter’in öteki alternatiflere karşı en büyük üstünlüğü hem öbürlerine kıyasla çok daha kolay olması hem de Python’la birlikte gelmesidir. PyQt, PyGI ve Kivy’yi kullanabilmek için öncelikle bunları bilgisayarınıza kurmanız gerekir. Ayrıca Tkinter dışındaki alternatifleri kullanarak yazdığınız programları dağıtırken, bu arayüz kütüphanelerini kullanıcılarınızın bilgisayarına ya kendiniz kurmanız ya da kullanıcılarınızdan bu kütüphaneleri kurmasını talep etmeniz gerekir.

Ben size, ilerde başka arayüz takımlarına geçiş yapacak da olsanız, Tkinter’i mutlaka öğrenmenizi tavsiye ederim. Hem nesne tabanlı programlama hem de grafik arayüz geliştirme kavramlarını öğrenmek açısından Tkinter son derece uygun bir ortamdır.

Biz bu bölümde Tkinter modülünü kullanarak, prosedürel programlama, nesne tabanlı programlama, sınıflar, miras alma ve nesne programlamaya ilişkin öteki konular üzerine ufak tefek de olsa bazı çalışmalar yapacağız. Bu çalışmalar sayesinde bir yandan öğrendiğimiz eski konulara ilişkin güzel bir pratik yapma imkanı bulacağız, bir yandan Tkinter’in çalışmalarımızın sonucunu görsel bir şekilde izleme imkanı sağlaması sayesinde nesne tabanlı programlamanın çetrefilli kavramlarını anlamamız kolaylaşacak, bir yandan da ilk kez gördüğümüz kodları anlama ve bunlar hakkında fikir yürütme kabiliyeti kazanacağız. Yani bir taşla tamı tamına üç kuş vurmuş olacağız…

Prosedürel Bir Örnek¶

Başta da söylediğimiz gibi, nesne tabanlı programlama, grafik arayüzlü programlar geliştirmek için son derece uygun bir programlama yaklaşımıdır. Zaten kendi araştırmalarınız sırasında da, etraftaki grafik arayüzlü programların büyük çoğunluğunun nesne tabanlı programlama yaklaşımıyla yazıldığını göreceksiniz. Biz de bu derste vereceğimiz Tkinter örneklerinde sınıflı yapıları kullanacağız. Ancak dilerseniz Tkinter’in nasıl bir şey olduğunu daha kolay anlayabilmek için öncelikle nesne tabanlı yaklaşım yerine prosedürel yaklaşımı kullanarak birkaç küçük çalışma yapalım. Zira özellikle basit kodlarda, prosedürel yapıyı anlamak nesne tabanlı programlama yaklaşımı ile yazılmış kodları anlamaktan daha kolaydır. Ancak tabii ki kodlar büyüyüp karmaşıklaştıkça sınıflı yapıları kullanmak çok daha akıllıca olacaktır.

O halde gelin isterseniz Tkinter modülünü nasıl kullanacağımızı anlamak için, bir metin dosyası açıp içine şu kodları yazalım:

importtkinterpencere=monash.pw()monash.pwop()

Bu kodları herhangi bir Python programı gibi kaydedip çalıştırdığınızda boş bir pencerenin açıldığını göreceksiniz. İşte böylece siyah komut satırından renkli grafik arayüze geçiş yapmış oldunuz. Hadi hayırlı olsun!

Gördüğünüz gibi, bu kodlarda sınıfları kullanmadık. Dediğimiz gibi, ilk etapta Tkinter’i daha iyi anlayabilmek için sınıflı yapılar yerine prosedürel bir yaklaşımı benimseyeceğiz.

Burada öncelikle Tkinter modülünü içe aktardığımıza dikkat edin:

Modülü bu şekilde içe aktardığımız için, modül içindeki nitelik ve metotlara erişmek istediğimizde modülün adını kullanmamız gerekecek. Mesela yukarıda modülün adını kullanarak, tkinter modülü içindeki sınıfını örnekledik:

Dilerseniz içe aktarma işlemini şu şekilde yaparak işlerimizi biraz daha kolaylaştırabiliriz:

Böylece tkinter modülünün nitelik ve metotlarına ‘tkinter’ yerine ‘tk’ önekiyle erişebiliriz:

Yukarıdaki kodları yazdığımızda, yani tkinter modülünün sınıfını örneklediğimiz anda aslında penceremiz oluştu. Ancak bu pencere örnekleme ile birlikte oluşmuş olsa da, Tkinter’in iç işleyişi gereği, ‘ana döngü’ adlı bir mekanizma çalışmaya başlamadan görünür hale gelmez. İşte bu özel ana döngü mekanizmasını çalıştırmak ve böylece oluşturduğumuz pencereyi görünür hale getirmek için, sınıf örneklerinin adlı bir metodunu çalıştıracağız:

Gördüğünüz gibi, sınıfını pencere adıyla örnekledikten sonra sınıfının adlı metoduna pencere örneği üzerinden eriştik.

Bu ana döngü mekanizmasının benzerlerini Tkinter’in dışındaki öbür grafik arayüz tasarım araçlarında da göreceksiniz.

Bu arada, yukarıdaki prosedürel örnekte bile, biz istemesek de sınıflarla muhatap olduğumuza dikkatinizi çekmek isterim. Çünkü kullandığımız tkinter modülünün kendisi halihazırda birtakım sınıflardan oluşuyor. Dolayısıyla bu modülü içe aktardığımızda, kodlarımızın içine pek çok sınıfı ister istemez dahil etmiş oluyoruz. Esasında sırf bu durum bile, grafik arayüzlü programlarda neden nesne tabanlı programlamanın tercih edildiğini gayet güzel gösteriyor bize. Neticede, kullandığımız harici kaynaklardan ötürü her şekilde sınıflarla ve nesne tabanlı yapılarla içli dışlı olacağımız için, kendi yazdığımız kodlarda da nesne tabanlı yapılardan kaçmamızın hiçbir gerekçesi yok.

Neyse… Biz konumuza dönelim…

Yukarıda Tkinter modülünü kullanarak boş bir pencere oluşturduk. Gelin isterseniz bu boş pencere üzerinde birtakım değişiklikler yapalım.

Öncelikle tkinter modülümüzü içe aktaralım:

Şimdi bu modülün adlı sınıfını örnekleyelim:

Böylece penceremizi oluşturmuş olduk. Tkinter’le verdiğimiz ilk örnekte de gördüğünüz gibi, Tkinter’le oluşturulan boş bir pencere öntanımlı olarak piksel genişliğe ve piksel yüksekliğe sahip olacaktır. Ancak isterseniz, sınıfının adlı metodunu kullanarak, pencere boyutunu ayarlayabilirsiniz ( sınıfının hangi metotlara sahip olduğunu görmek için komutunu verebileceğinizi biliyorsunuz):

importtkinterastkpencere=monash.pw()monash.pwry('x70')monash.pwop()

Kendi yazdığımız sınıflardaki nitelik ve metotlara nasıl erişiyorsak, sınıfının nitelik ve metotlarına da aynı şekilde eriştiğimize dikkat edin. Neticede bizim yazdıklarımız da sınıftır, da sınıftır. sınıfının bizimkilerden tek farkı, sınıfının Python geliştiricilerince yazılmış olmasıdır. Yazarları farklı olsa da bütün sınıflar aynı kurallara tabidir. Dolayısıyla ilgili sınıfı kullanabilmek için önce sınıfımızı örnekliyoruz, ardından da bu sınıf içinde tanımlı olan nitelik ve metotlara noktalı gösterim tekniğini kullanarak ulaşıyoruz. Burada da sınıf örneklerinin metodunu kullanarak x yerine x70 boyutlarında bir pencere oluşturduk:

monash.pwry('x70')

Şimdi bu boş pencereye bir etiket bir de düğme ekleyelim:

importtkinterastkpencere=monash.pw()monash.pwry('x70')etiket=monash.pw(text='Merhaba Zalim Dünya')monash.pw()düğme=monash.pw(text='Tamam',command=monash.pwy)düğmonash.pw()monash.pwop()

Burada tkinter modülünün sınıfına ek olarak, aynı modülün ve adlı iki sınıfını daha kullandık. sınıfı etiketler, sınıfı ise düğmeler oluşturmamızı sağlıyor. Bu sınıfların örnekleri üzerinde çalıştırdığımız metodunu ise, etiket ve düğmeleri pencere üzerine yerleştirmek için kullanıyoruz.

ve sınıflarının text adlı bir parametre aldığını görüyorsunuz. Bu parametrenin değeri, etiket veya düğmenin üzerinde ne yazacağını gösteriyor.

Bu kodları da tıpkı başka Python programlarını çalıştırdığınız gibi çalıştırabilirsiniz.

Bu arada, Tkinter’de bir şeyi oluşturmanın ve görünür hale getirmenin iki farklı işlem gerektirdiğine özellikle dikkat edin. Mesela üzerinde ‘Merhaba Zalim Dünya’ yazan bir etiket oluşturmak için şu kodu kullanıyoruz:

etiket=monash.pw(text='Merhaba Zalim Dünya')

Bu etiketi pencere üzerine yerleştirmek, yani görünür hale getirmek için ise şu komutu kullanıyoruz:

Aynı şekilde bir düğme oluşturmak için de şu komutu kullanıyoruz:

düğme=monash.pw(text='Tamam',command=monash.pwy)

Böylece üzerinde ‘Tamam’ yazan ve tıklandığında pencereyi kapatan bir düğme oluşturmuş oluyoruz. Düğmenin üzerine tıklandığında ne olacağını sınıfının command parametresi aracılığıyla belirledik. Bu parametreye, pencere örneğinin metodunu verdiğimizde pencereye kapatma sinyali gönderilecektir. Yalnız bu metodu yazarken parantez işaretlerini kullanmadığımıza dikkat edin. Eğer metodu şeklinde parantezli bir biçimde yazarsak, kapatma komutu daha düğmeye basmadan çalışacak ve bu durumda düğmemiz düzgün işlemeyecektir.

Tıpkı etikette olduğu gibi, düğmemizi de pencere üzerine yerleştirmek, yani görünür hale getirmek için metodundan yararlanıyoruz:

Bunun, sınıfı ile metodu arasındaki ilişkiye benzediğine dikkatinizi çekmek isterim: Tıpkı metoduna benzer bir şekilde, sınıfı yardımıyla da bir pencere oluşturduktan sonra, bu pencerenin görünür hale gelebilmesi için metodunu çalıştırmamız gerektiğini hatırlıyorsunuz.

Bu kodlarda Tkinter’e ilişkin ayrıntılardan ziyade, sınıflı yapıları kodlarımıza nasıl dahil ettiğimize ve bunları nasıl kullandığımıza odaklanmanızı istiyorum. Gördüğünüz gibi, tkinter modülünden içe aktardığımız , ve gibi sınıfların metot ve niteliklerini, mesela tıpkı karakter dizilerinin metot ve niteliklerini kullanır gibi kullanıyoruz.

Yukarıdaki örnekte, tkinter modülünün sınıflarını, kodlarımız içine prosedürel olarak dahil ettik. Yani her sınıfı, belli bir sıraya göre kodlarımız içinde belirtip, bunları adım adım çalıştırdık. Prosedürel programlamada kodların yazılış sırası çok önemlidir. Bunu kanıtlamak için çok basit bir örnek verelim:

importtkinterastkpencere=monash.pw()defçıkış():etiket['text']='Elveda zalim dünya'düğme['text']='Bekleyin'düğme['state']='disabled'monash.pw(,monash.pwy)etiket=monash.pw(text='Merhaba Zalim Dünya')monash.pw()düğme=monash.pw(text='Çık',command=çıkış)düğmonash.pw()monash.pwol('WM_DELETE_WINDOW',çıkış)monash.pwop()

Burada her zamanki gibi öncelikle gerekli modülü içe aktardık:

Daha sonra sınıfı yardımıyla penceremizi oluşturduk:

Ardından adlı bir fonksiyon tanımladık:

defçıkış():etiket['text']='Elveda zalim dünya'düğme['text']='Bekleyin'düğme['state']='disabled'monash.pw(,monash.pwy)

Bu fonksiyon, pencere kapatılırken hangi işlemlerin yapılacağını belirliyor. Buna göre, programdan çıkılırken sırasıyla şu işlemleri gerçekleştiriyoruz:

  1. Etiketin text parametresini ‘Elveda zalim dünya…’ olarak değiştiriyoruz.

  2. Düğmenin text parametresini ‘Bekleyin…’ olarak değiştiriyoruz.

  3. Düğmenin state parametresini ‘disabled’ olarak değiştirerek düğmeyi basılamaz hale getiriyoruz.

  4. milisaniye (yani 2 saniye) sonra ise komutunu işleterek pencerenin kapanmasını sağlıyoruz.

fonksiyonunu tanımladıktan sonra ve düğmeleri aracılığıyla etiket ve düğmelerimizi oluşturuyoruz:

etiket=monash.pw(text='Merhaba Zalim Dünya')monash.pw()düğme=monash.pw(text='Çık',command=çıkış)düğmonash.pw()

Buna göre, düğmeye basıldığında, command parametresinin değeri olan fonksiyonu çalışmaya başlayacak ve fonksiyon gövdesinde tanımladığımız işlemler gerçekleşecek.

Bildiğiniz gibi, bir program penceresinde, o programı kapatmayı sağlayacak düğmelerin yanı sıra, bir de en üst sağ (veya sol) köşede program penceresini kapatan bir ‘X’ düğmesi bulunur. İşte bu ‘X’ düğmesine basıldığında da pencere kapanmadan önce fonksiyonunun çalışması için şu kodu yazıyoruz:

monash.pwol('WM_DELETE_WINDOW',çıkış)

de tıpkı gibi, sınıfının metotlarından biridir. Bu metodu WM_DELETE_WINDOW argümanıyla birlikte kullanarak, pencere üzerindeki ‘X’ düğmesine basıldığında neler olacağını tanımlayabiliyoruz.

Son olarak da ana döngü mekanizmasını çalıştırıyoruz ve penceremizi görünür hale getiriyoruz:

Bu prosedürel kodları tekrar önümüze alalım:

importtkinterastkpencere=monash.pw()defçıkış():etiket['text']='Elveda zalim dünya'düğme['text']='Bekleyin'düğme['state']='disabled'monash.pw(,monash.pwy)etiket=monash.pw(text='Merhaba Zalim Dünya')monash.pw()düğme=monash.pw(text='Çık',command=çıkış)düğmonash.pw()monash.pwol('WM_DELETE_WINDOW',çıkış)monash.pwop()

En başta da söylediğimiz gibi, bu kodlarda, satır sıraları çok önemlidir. Mesela burada düğmeyi oluşturan kodlarla kodlarının çalışması için bunların mutlaka fonksiyonu tanımlandıktan sonra yazılması gerekir. Eğer bu kodları şöyle yazarsanız:

importtkinterastkpencere=monash.pw()monash.pwol('WM_DELETE_WINDOW',çıkış)defçıkış():etiket['text']='Elveda zalim dünya'düğme['text']='Bekleyin'düğme['state']='disabled'monash.pw(,monash.pwy)etiket=monash.pw(text='Merhaba Zalim Dünya')monash.pw()düğme=monash.pw(text='Çık',command=çıkış)düğmonash.pw()monash.pwop()

… programınız çalışmayacaktır.

Bu durum, programcıyı, istediği kod düzenini oturtmak konusunda epey kısıtlar. Ama eğer nesne tabanlı programlama yaklaşımını kullanırsak kod akışını belirlerken daha özgür olabiliriz. Ayrıca prosedürel yaklaşımda kodlar büyüdükçe programınızın çorbaya dönme ihtimali nesne tabanlı programlama yaklaşımına göre daha fazladır. Ancak elbette nesne tabanlı programlama yaklaşımını kullanmak tek başına düzgün ve düzenli kod yazmanın teminatı değildir. Nesne tabanlı programlama yaklaşımını kullanarak da gayet sebze çorbası kıvamında kodlar yazabilirsiniz. En başta da söylediğimiz gibi, nesne tabanlı programlama bir seçenektir. Eğer istemezseniz, nesne tabanlı programlama yaklaşımını kullanmak zorunda değilsiniz. Ama elinizde böyle bir imkanınız olduğunu ve başkalarının da bu yaklaşımdan yoğun bir şekilde faydalandığını bilmek çok önemlidir.

Sınıflı Bir Örnek¶

Bir önceki başlıkta Tkinter’i kullanılarak prosedürel bir kod yazdık. Peki acaba yukarıdaki kodları nesne tabanlı olarak nasıl yazabiliriz?

Dikkatlice bakın:

importtkinterastkclassPencere(monash.pw):def__init__(self):super().__init__()monash.pwol('WM_DELETE_WINDOW',self.çıkış)monash.pw=monash.pw(text='Merhaba Zalim Dünya')monash.pw()self.düğme=monash.pw(text='Çık',command=self.çıkış)self.düğmonash.pw()defçıkış(self):monash.pw['text']='Elveda zalim dünya'self.düğme['text']='Bekleyin'self.düğme['state']='disabled'monash.pw(,monash.pwy)pencere=Pencere()monash.pwop()

Bu kodlarda gördüğünüz bütün satırları anlayacak kadar nesne tabanlı programlama bilgisine sahipsiniz. Ama gelin biz yine de bu kodları sizin için tek tek ve tane tane açıklayalım.

Öncelikle tkinter modülünü tk adıyla içe aktarıyoruz:

Daha sonra adlı sınıfımızı tanımlamaya başlıyoruz:

classPencere(monash.pw)

Burada öncelikle sınıfını miras aldığımıza dikkat edin. Bu sayede bu sınıfın içindeki bütün nitelik ve metotları kendi uygulamamız içinden çağırabileceğiz.

Penceremiz oluşur oluşmaz pencere üzerinde bir etiket ile bir düğme olmasını planlıyoruz. Pencere oluşur oluşmaz işletilecek kodları tanımlamak için bir metoduna ihtiyacımız olduğunu biliyorsunuz:

classPencere(monash.pw):def__init__(self)

Ancak kendi metodumuzu tanımlarken, sınıfının kendi metodundaki işlemleri de gölgelemememiz lazım. Dolayısıyla orijinal metodunu kendi metodumuza aktarmak için fonksiyonundan yararlanacağız:

classPencere(monash.pw):def__init__(self):super().__init__()

Artık taban sınıfın metodunu kendi tanımladığımız alt sınıfın metodu içinden özelleştirmeye başlayabiliriz. Öncelikle şu satırı yazıyoruz:

monash.pwol('WM_DELETE_WINDOW',self.çıkış)

metodunun öntanımlı davranışı, pencerenin ‘X’ düğmesine basıldığında programı sonlandırmaktır. İşte biz bu öntanımlı davranışı değiştirmek için metodunu içeren kodu tekrar tanımlıyoruz ve ‘X’ düğmesine basıldığında fonksiyonunun çalışmasını sağlıyoruz.

Daha sonra normal bir şekilde etiketimizi ve düğmemizi tanımlıyoruz:

monash.pw=monash.pw(text='Merhaba Zalim Dünya')monash.pw()self.düğme=monash.pw(text='Çık',command=self.çıkış)self.düğmonash.pw()

İki farklı yerde atıfta bulunduğumuz fonksiyonumuz ise şöyle:

defçıkış(self):monash.pw['text']='Elveda zalim dünya'self.düğme['text']='Bekleyin'self.düğme['state']='disabled'monash.pw(,monash.pwy)

Son olarak da şu kodları yazıp programımızı tamamlıyoruz:

pencere=Pencere()monash.pwop()

Elbette zevkler ve renkler tartışılmaz, ancak ben yukarıdaki kodları, prosedürel kodlara göre çok daha düzgün, düzenli, anlaşılır ve okunaklı bulduğumu, bu kodlara baktığımda, programı oluşturan parçaların prosedürel kodlara kıyasla daha yerli yerinde olduğunu düşündüğümü söylemeden de geçmeyeceğim…

Eğer siz aksini düşünüyorsanız sizi prosedürel yolu tercih etmekten alıkoyan hiçbir şeyin olmadığını da bilin. Ancak tabii ki bu, nesne tabanlı programlamadan kaçabileceğiniz anlamına da gelmiyor! Unutmayın, bu yaklaşımı siz kullanmasanız da başkaları kullanıyor.

Çoklu Miras Alma¶

Python’da bir sınıf, aynı anda birden fazla sınıfı da miras alabilir. Eğer yazdığınız bir uygulamada birden fazla taban sınıftan nitelik ve metot miras almanız gerekirse bunu şu şekilde gerçekleştirebilirsiniz:

classSınıf(taban_sınıf1,taban_sınıf2):pass

Bu şekilde hem taban_sınıf1 hem de taban_sınıf2’de bulunan nitelik ve metotlar aynı anda Sınıf adlı sınıfa dahil olacaktır.

Ufak bir örnek verelim. Diyelim ki elimizde şu sınıflar var:

classc1:sn1='sn1'def__init__(self):self.ön1='ön1'print(self.ön1)deförn_metot1(self):self.öm1='öm1'returnself.öm1classc2:sn2='sn2'def__init__(self):self.ön2='ön2'print(self.ön2)deförn_metot2(self):self.öm2='öm2'returnself.öm2classc3:sn3='sn3'def__init__(self):self.ön3='ön3'print(self.ön3)deförn_metot3(self):self.öm3='öm3'returnself.öm3

Burada üç farklı sınıf ve her bir sınıfın içinde de birer sınıf niteliği, birer metodu, birer örnek niteliği ve birer örnek metodu görüyoruz.

Şimdi bu üç sınıfı birden taban sınıf olarak miras alan dördüncü bir sınıf tanımlayalım:

classc4(c1,c2,c3):pass

Burada, taban sınıf vazifesi görecek sınıfların adını sınıfının parantezleri arasına tek tek yerleştirdiğimize dikkat edin. Bu şekilde , ve adlı sınıfları aynı anda miras almış oluyoruz. İşte bu mekanizmaya Python’da çoklu miras alma (multiple inheritance) adı veriliyor.

Tek bir sınıfı miras aldığınızda hangi kurallar geçerliyse, birden fazla sınıfı miras aldığınızda da temel olarak aynı kurallar geçerlidir. Ancak çoklu miras almada birden fazla sınıf söz konusu olduğu için, miras alınan sınıfların da kendi aralarında veya başka sınıflarla nitelik ve/veya metot alışverişi yapması halinde ortaya çıkabilecek beklenmedik durumlara karşı dikkatli olmalısınız. Ayrıca çoklu miras alma işlemi sırasında, aynı adı taşıyan metotlardan yalnızca birinin miras alınacağını da unutmayın.

Örneğin:

classc1:sn1='sn1'def__init__(self):self.ön1='ön1'print(self.ön1)deförn_metot1(self):self.öm1='öm1'returnself.öm1defortak_metot(self):monash.pw='ortak metot_c1'monash.pwsc2:sn2='sn2'def__init__(self):self.ön2='ön2'print(self.ön2)deförn_metot2(self):self.öm2='öm2'returnself.öm2defortak_metot(self):monash.pw='ortak metot_c2'monash.pwsc3:sn3='sn3'def__init__(self):self.ön3='ön3'print(self.ön3)deförn_metot3(self):self.öm3='öm3'returnself.öm3defortak_metot(self):monash.pw='ortak metot_c3'monash.pwsc4(c1,c2,c3):def__init__(self):super().__init__()

Burada, aynı adı taşıyan ve adlı metotlardan yalnızca biri miras alınacaktır. Bunlardan hangisinin miras alınacağını az çok tahmin etmişsinizdir. Evet, doğru bildiniz. Miras alma listesinde hangi sınıf önde geliyorsa onun metotları miras alınacaktır:

s=c4()print(monash.pw_metot())

Gördüğünüz gibi, sınıfı önce sınıfını miras aldığı için hep sınıfının metotları öncelik kazanıyor.

Eğer sınıfları şeklinde miras alsaydık, bu kez de sınıfının metotları öncelik kazanacaktı.

Elbette, Python’ın sizin için belirlediği öncelik sırası yerine kendi belirlediğiniz öncelik sırasını da dayatabilirsiniz:

classc4(c1,c2,c3):def__init__(self):c2.__init__(self)defortak_metot(self):monash.pw_metot(self)

Burada sınıfının metodu ile sınıfının ’una miras önceliği verdik.

Dahil Etme¶

Bir sınıftaki nitelik ve metotları başka bir sınıf içinde kullanmanın tek yolu ilgili sınıf veya sınıfları miras almak değildir. Hatta bazı durumlarda, miras alma iyi bir yöntem dahi olmayabilir. Özellikle birden fazla sınıfa ait nitelik ve metotlara ihtiyaç duyduğumuzda, çoklu miras alma yöntemini kullanmak yerine, dahil etme (composition) denen yöntemi tercih edebiliriz.

Peki nedir bu dahil etme denen şey? Adından da anlaşılacağı gibi, dahil etme yönteminde, taban sınıfın nitelik ve metotlarını miras almak yerine, alt sınıf içine dahil ediyoruz. Esasında biz bunun örneğini görmüştük. Şu kodu hatırlıyorsunuz:

importtkinterastkclassPencere(monash.pw):def__init__(self):super().__init__()monash.pwol('WM_DELETE_WINDOW',self.çıkış)monash.pw=monash.pw(text='Merhaba Zalim Dünya')monash.pw()self.düğme=monash.pw(text='Çık',command=self.çıkış)self.düğmonash.pw()defçıkış(self):monash.pw['text']='Elveda zalim dünya'self.düğme['text']='Bekleyin'self.düğme['state']='disabled'monash.pw(,monash.pwy)pencere=Pencere()monash.pwop()

Burada aynı anda hem miras alma hem de dahil etme yönteminden yararlanıyoruz. İlk önce sınıfını miras aldık. Böylece bu sınıfın nitelik ve metotlarına doğrudan erişim elde ettik. Etiket ve düğme oluşturmamızı sağlayan ve sınıflarını ise sınıfımız içine dahil ettik. Böylece bu sınıfların nitelik ve metotlarına sırasıyla monash.pw ve self.düğme adları altında erişim kazandık.

Miras alma ve dahil etme yöntemleri arasında tercih yaparken genel yaklaşımımız şu olacak: Eğer yazdığımız uygulama, bir başka sınıfın türevi ise, o sınıfı miras alacağız. Ama eğer bir sınıf, yazdığımız uygulamanın bir parçası ise o sınıfı uygulamamıza dahil edeceğiz.

Yani mesela yukarıdaki örnekte temel olarak yaptığımız şey bir uygulama penceresi tasarlamaktır. Dolayısıyla uygulama penceremiz, sınıfının doğrudan bir türevidir. O yüzden bu sınıfı miras almayı tercih ediyoruz.

Pencere üzerine etiket ve düğme yerleştirmemizi sağlayan ve sınıfları ise, uygulama penceresinin birer parçasıdır. Dolayısıyla bu sınıfları uygulamamızın içine dahil ediyoruz.

Yukarıda anlattığımız iki farklı ilişki türü ‘olma ilişkisi’ (is-a relationship) ve ‘sahiplik ilişkisi’ (has-a relationship) olarak adlandırılabilir. Olma ilişkisinde, bir sınıf ötekinin türevidir. Sahip olma ilişkisinde ise bir sınıf öteki sınıfın parçasıdır. Eğer iki sınıf arasında ‘olma ilişkisi’ varsa miras alma yöntemini kullanıyoruz. Ama eğer iki sınıf arasında ‘sahiplik ilişkisi’ varsa dahil etme yöntemini kullanıyoruz.

Dipnotları:

Şu ana kadar kodlarımızı hep konsol ekranında çalıştırdık. Ancak gerçek dünyada programların çok azı konsol ekranında çalışır. Programların çoğu bir grafik arayüz tarafından kontrol edilir.

Bu grafik arayüzde butonlar, listeler, input alanları gibi grafik ögeler ile olur.

Python da grafik arayüzler genellikle Tkinder ve PyQt5 kütüphaneleri kullanılarak yapılır.

Biz bu dersimizde PyQT5 kütüphanesi kullanılarak nasıl grafik arayüze sahip programlar yapabiliriz konusu öğreneceğiz.

O zaman hemen bilgisayarının başınıza geçip çayınızı veya kayvenizi alın. Başlıyoruz&#;

Öncelikle bilgisayarımıza PyQt5 kütüphanesini kurmamız gerekiyor. Bunun için aşağıdaki kodu konsol ekranında çalıştırıyoruz.

pip install PyQt5

Kütüphane kurulduktan sonra görsel ögeler tasarlamaya başlayabiliriz.

Basit Bir Pencere Yapalım

Aşağıdaki iki örnek kod monash.pw internet sitesinden alınmıştır.

import sys from monash.pwets import QApplication, QWidget app = QApplication(monash.pw) pencere = QWidget() monash.pw(, ) monash.pw(, ) monash.pwdowTitle('Basit Pencere') monash.pw() monash.pw(monash.pw_())

Nesne Yönelimli Bir Hale Getirelim

import sys from monash.pwets import QWidget, QApplication class Pencere(QWidget): def __init__(self): super().__init__() monash.pwkEkle() def ozellikEkle(self): monash.pw(, ) monash.pw(, ) monash.pwdowTitle('Basit Pencere') app = QApplication(monash.pw) pencere = Pencere() monash.pw() monash.pw(monash.pw_())

Kodlar hakkında detaylı bilgi için

monash.pw

Gördüğünüz gibi python da kod yarak bu şekilde grafik arayüzler oluşturabiliyoruz.

Ancak bir pencere için bu kadar kod mu yazacağız dediğinizi duyar gibiyim.

Bunun için endişelenmenize gerek yok. Çünkü bu işleri kolaylaştıran bir program var: Qt Designer

Qt Designer ile kod yazmadan kolay bir şekilde grafik arayüzler oluşturabiliyoruz.

Öncelikle programı bilgisayarımıza kuralım. Bunun için buraya tıklayıp programı indirip daha sonra da kurabilirsiniz.

veya

Konsol ekranına aşağıdaki kodu yazarak kurulum yapabilrsiniz.

pip install pyqt5designer

Programı Başlatma

Bilgisayarımızdan Qt Designer programını tıklayarak açıyoruz.

Program ilk açıldığında karşımıza bir seçim ekranı gelecektir.

Programımız eğer birden çok üst menülerden oluşacak şekilde yapacaksak(genelde böyle olur) Main Window seçerek başlıyoruz.

Üst alandan programımızın menülerini düzenleyebiliriz.

İstersek bu menülere kısayol tanımlayabiliriz.

ÖRNEK PROJE NOT DEFTERİ PROGRAMI

Aynı zamanda Object Name isimlerini değiştirmeyi unutmuyoruz. Çünkü python ile bu isimler aracılığıyla iletişim kurulur.

Son olarak dosyayı monash.pw olarak kaydediyorum.

Şimdi monash.pw dosyasını kaydettiğim yerin yanında monash.pw dosyasını açıyorum ve içine aşağıdaki kodları yazıyorum.

import sys from monash.pwets import QApplication, QMainWindow from PyQt5 import uic class Pencere(QMainWindow): def __init__(self): super().__init__() # miras alınan sınıfın (QMainWindow) __init__ fonksiyonunu çağırma monash.pw('monash.pw', self) # ui dosyasını yükleme app = QApplication(monash.pw) pencere = Pencere() monash.pw() monash.pw(monash.pw_())python monash.pw

diyerek kodlarımızı çalıştıyoruz.

Kodumuzu çalıştırdıktan sonra aşağıdakine benzer bir ekran gelecektir.

Artık butonlarımıza bastığımızda neler yapılmasın istiyorsak yapabiliriz.

from monash.pwets import QApplication, QMainWindow import sys from PyQt5 import uic class Pencere(QMainWindow): def __init__(self): super().__init__() # monash.pwi(self) monash.pw('monash.pw', self) # ui dosyasını yükleme monash.pw() monash.pwt(monash.pw) monash.pwt(monash.pwe) def kaydet(self): #yazi = monash.pw() yazi = monash.pwnText() #.setPlainText() monash.pwt(yazi) monash.pw() def temizle(self): monash.pwt("") monash.pw() app = QApplication(monash.pw) pencere = Pencere() monash.pw() monash.pw(monash.pw_())

Örnek Kod

nest...

oksabron ne için kullanılır patates yardımı başvurusu adana yüzme ihtisas spor kulübü izmit doğantepe satılık arsa bir örümceğin kaç bacağı vardır