Python ile mail gönderme maceraları

emailKahramanımız geliştirdiği web sitesi üzerinden kullanıcılara mail gönderme olanağı sunmak istiyordu. Nasıl yapayım nasıl yapayım derken, python’a bir bakayım bu iş için neler var diyerekten araştırmaya koyuldu, buna araştırma da denmez aslında “araş” ta kalırsınız anca, o kadar kısa sürdü çünkü.

Onca şey yazdık hala tek satır kod yok, yakışmaz bize diyerekten kullandığım fonksiyonu veriyorum:
Continue reading “Python ile mail gönderme maceraları”

Pymssql, windows 2003

visual_mssqlBir müşterimiz için Python ile Windows 2003 üzerinde çalışacak ve MsSql üzerine işlemler yapacak bir uygulama geliştirmemiz gerekti. Web.py ile server üzerinde çalışacak bir web uygulamasıydı yapacağımız. Burada anlatmak istediğim ise Windows 2003, MsSql ve Python (pymssql) üçlüsünün nasıl çalıştığı.

Pymssql’i kurmaya çalıştığımda kurulumda dll hatası verdi. Eksik olan msvcp90.dll‘i indirip c:\winnt\system32 içerisine kopyaladım. Daha sonra modülü import ettiğimde modül içerisinde kullanılan _mssql kısmını import ederken hata verdi. Bu da bir dll eksikliğinden kaynaklanıyormuş. Bunun için msvcr71.dll doyasını indirip c:\Python26\Lib\site-packages içerisine kopyalıyoruz. Daha sonra mssql sağ ben selamet…

Olur da birinin ihtiyacı olur diye not olsun bu da.

py2exe saçmalarsa

Merhaba, yazdığım uygulamanın windows altında çalıştırabilir halini oluşturmak için sarıldım py2exe’ye. Kodumda herhangi bir hata yok, setup.py dosyamı da oluşturdum, buraya kadar herşey çok güzel. python setup.py py2exe komutunu da çalıştırdım,
aa herşey çok güzel devam ediyor. Çalıştırılabilir dosyamız da hazır.
Oluşan çalıştırılabilir dosyaya çift tıklıyoruz,
eee? Çalışmadı! msvcr71.dll dosyası eksik diyor.
Nasıl olur? (Sistemde python 2.6 bulunmakta).
Arıyoruz tarıyoruz dosyayı C:\WINDOWS\system32 içerisinde buluyoruz,
oradan alıp çalıştırılabilir dosyamızın yanına koyuyoruz,
çift tık –> aa çalıştı.
Oluşturduğumuz klasörü alıp başka bir bilgisayara geçiyoruz,
çift tık –> fıssss.
google amca açmış kollarını bizi bekliyor ve öğreniyoruz ki 2.6 sürümünde böyle bir hata mevcut (çözümü var mı bilmiyorum, ben denk gelmedim)
Çözüm? Sisteme 2.5 sürümünü kuruyoruz. Programımızı başarıyla paketleyip çalışır hale getiriyoruz.

İlk maceramız böyle sonuçlandı ama bitmedi. Diğer yazılardan da anlaşılacağı üzere uygulamanın bir yerinde pyqt ile gif dosyası oynatıyorum.
Programı başarıyla paketledik ama bir eksik daha var.
Programa koyduğumuz gif dosyasının yerinde yeller esiyor.
Oynamayı bırakın hareketsiz hali bile yok.
Aklıma ilk gelen gif dosyasını bulamamış olabileceğiydi.
Kontrol ettim, herşey düzgün.
Allahtan google hala açık :) anahtar kelimeleri değiştirip veriyorum coşkuyu.
Sorun ne bende ne python’da, sorun py2exe’de.
“C:\Python25\Lib\site-packages\PyQt4\plugins” içerisindeki imageformats klasörünü çalıştırılabilir dosyamızın yanına koyuyoruz (içinden ihtiyacınız olmayan dllleri silebilirsiniz),
vee işkence bitti gibi, gif dosyamız Allah ne verdiyse döktürüyor.
setup.py içerisine bu kopyalama işlemini kendisinin yapması için bir düzenleme yapmak gerekiyor mu bilmiyorum. Aradım taradım ben öyle bir şeye rastlamadım. O yüzden suçu py2exe modülüne atmamam için hiçbir neden yok :)

Şimdilik benden bu kadar.
Kalın sağlıcakla…

QFile::seek: IODevice is not open

iodeviceerrorPyQt ile gif oynatıyorsunuz ve uygulamanız bir yerinde QFile::seek: IODevice is not open gibi bir hata verip kilitleniyor ve siz google amcaya nedir bunun sebebi diye sorup buraya geliyorsunuz, merak etmeyin doğru yerdesiniz :) Yapmanız gereken gif dosyası movie nesnesine yüklenirken bütün framelerin cachlenmesini sağlamak. Bu da şöyle oluyor:

self.movie.setCacheMode(QtGui.QMovie.CacheAll)

vee hatadana eser yok..

Sloganımızı da söyleyelim: “Exceptionsız günler sizinle olsun..”

Python ile dosyaya veri yazma

Python ile geliştirdiğim sunucu ve istemci şeklinde çalışan bir uygulamam var. Sunucudan istemciye içeriği binary olan bir dosya transferi yapıyorum. Linux üzerinde denediğimde dosyayı gayet başarılı bir şekilde kaydediyor ancak windows’ta denediğimde dosya hasarlı görünüyor, gelen dosyanın boyutuyla sunucudan gönderdiğim dosyanın boyutu da tutmuyor (istemcideki dosya daha büyük oluyor). Bu durumu görünce “işte çözülmesi gereken harika bir problem, ollleeyyy” naraları ile başladım didiklemeye (bunun öncesinde windows’a ettiğim küfürleri yazmıyorum). Sonra farkettim ki tek suç windows’un değilmiş, dosyayı binary modda açmam gerekiyormuş. Aslında çok bilinmedik bir şey değil, başlangıçta kaçırmışım ve Linux’ta sorun çıkarmaması çözümü görmemi zorlaştırmış biraz. Neyse olur da sizin de başınıza gelir belki diye buraya not düşüyorum. Demedi demeyin :)

f = open("temp.gif", "wb")

Kalın sağlıcakla..

PyQt harikaları

Merhaba PyQt harikaları yazı dizimize hoş geldiniz, bu arada başlık iddialı olmuş biraz ama hak ediyor bence. Bu ara fırsat buldukça bir dizi halinde PyQt ile yapabileceğiniz “değişik” ve “işlevsel” şeylerden bahsedeceğim. İlki bu yazı, gelen tepkileri beğenirsem diğerlerini de yazarım, +rep’lerinizi bekliyorum :) Hemen senaryomuza geçelim. Bir resim gösterici uygulaması geliştiriyorsunuz ama uygulamanızın normal pencere şeklinde görünmesini istemiyorsunuz, formunuzun çerçeve şeklinde olmasını ve içinde resimlerinizin görünmesini istiyorsunuz. PyQt ile çok kolay. Pencerenizi herhangi bir çizim programıyla çizin ve gerisini PyQt’ye bırakın.

Örnek uygulamayı vermeden önce içeriğinden bahsedeyim, örneğimizde ana formumuz, kapatma ve minimize butonları ile ileri – geri butonlarını gösteren toplam 5 adet resim bulunmakta. Amacım pencere dekorasyonunu göstermek olduğu için resim gösterme kısmını yazmadım.

Anlatımı kodun içerisinde uygun yerlerde açıklama satırları ile yaptım. Kafanıza takılan, anlamadığınız bir kısım olursa sormaktan çekinmeyiniz.
Kodumuz şöyle:
Continue reading “PyQt harikaları”

PyQt & Animated Gif Macerası..

Python – PyQt birlikteliğinden swf oynatma yeteneği çıkmayınca geliştirdiğim uygulamada dinamik olarak güncellenebilen bir alanda animated gif oynatmaya karar verdik. Qt ile bunun oluru nedir diye baktığımda pek de zor olmadığını gördüm.

Özetle şöyle:
Önce bir QMovie nesnesi oluşturuyorsunuz, oynatacağınız gif’i QMovie nesnesini oluştururken belirtiyorsunuz. Daha sonra bir QLabel oluşturup setMovie metoduna oluşturduğunuz QMovie nesnesini veriyorsunuz. Son olarak oluşturduğunuz QMovie nesnesinin start() metodunu çağırarak gif’i oynatıyorsunuz. Mantık olarak çok basit olmakla birlikte bir türlü çalıştıramadım. Hata da vermiyor, bir derdi var belli, çok da küçük bişey ama bir türlü göremiyorum. Deneme için oluşturduğum kod aşağıda, oynatmaya çalıştığım gif dosyası da burada. Programı deneyip sonucu bana bildirirseniz çok sevinirim.

Çalıştığım sistem özellikleri:

Pardus 2008.2
PyQt 4.4.4

Cevap:
Aşağıdaki kodda bulunan movie nesnesini self‘e bağlayınca çalıştı. QMovie nesnesinin neden class’a bağlı global bir değişken olarak tanımlanması gerektiğini anlamış değilim. Bu örnek de böyle bir hatayla karşılaşanlar olursa diye dursun burada.

# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys
 
class Ui_MainWindow(object):
   def setupUi(self, MainWindow):
      MainWindow.setObjectName("MainWindow")
      MainWindow.resize(800, 600)
      self.centralwidget = QtGui.QWidget(MainWindow)
      self.centralwidget.setObjectName("centralwidget")
      self.label = QtGui.QLabel(self.centralwidget)
      self.label.setGeometry(QtCore.QRect(210, 90, 351, 231))
      movie = QtGui.QMovie("progress.gif")
      self.label.setMovie(movie)
      movie.start()
 
      """
 
      ** PyQt sürümünüzün gif destegi olup olmadigini commentleri kaldirarak gorebilirsiniz
 
      formats = QtGui.QImageReader.supportedImageFormats ()
      for i in formats:
         print i
 
      """
 
      self.label.setObjectName("label")
      MainWindow.setCentralWidget(self.centralwidget)
      self.menubar = QtGui.QMenuBar(MainWindow)
      self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 29))
      self.menubar.setObjectName("menubar")
      MainWindow.setMenuBar(self.menubar)
      self.statusbar = QtGui.QStatusBar(MainWindow)
      self.statusbar.setObjectName("statusbar")
      MainWindow.setStatusBar(self.statusbar)
 
      self.retranslateUi(MainWindow)
      QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
   def retranslateUi(self, MainWindow):
      MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
 
if __name__ == "__main__":
   app=QtGui.QApplication(sys.argv)
   window=QtGui.QMainWindow()
   ui=Ui_MainWindow()
   ui.setupUi(window)
   window.show()
   sys.exit(app.exec_())

Ev yapımı şifreleme

lock-and-key-icon-thumb355812Merhaba.Bugün size Python ile ev yapımı şifreleme nasıl yapılır ondan bahsedeceğim. Ev yapımı şifrelemeden neyi kastettiğimi yazının devamında daha rahat anlayacaksınız.(Not: Yazar girişte başlığı kullanarak merak uyandırmaya çalışmış ve okuyucuyu yazının devamını okuması için teşvik etmeye çalışmıştır).Programı görmeden önce size bu programı nerede kullanabileceğinizden bahsedeceğim, programın bu bilgiyle incelendiğinde daha kolay anlaşılacağını düşünüyorum.

Bir uygulama geliştirdiniz. Uygulamanız kullanıcı adı ve şifre girişi gerektirmekte ve siz de bu kullanıcı adını ve şifreyi kullanıcının bilgisayarında tutmak durumundasınız. Sadece bir kullanıcının kullanıcı adı ve şifresini tutmak içinde veritabanı kullanmak istemiyorsunuz. Bu durumda bu bilgileri bir dosyada tutmanız gerek. Buraya kadar her şey normal. Sorun bu bilgileri o dosyada nasıl tutacağınız. Bir dosya oluşturup içerisine pattadanak (böyle mi yazılıyor bu?) yazacak değilsiniz. Bu kadarla da kalmıyorsunuz programınız kullanıcınızın izni dışında 3. şahıslar tarafından kopyalandığında da o 3. şahıs programını çaldığı kullanıcınızın bilgileri ile giriş yapamasın istiyorsunuz, yok artık!!! İşte bu yazıda böyle bir ihtiyaç durumunda kullanabileceğiniz bir şifreleme yönteminden, kendi verdiğim isimle “Ev Yapımı Şifreleme” den bahsedeceğim.

Çok konuştuk, kodu görelim. Önce kodun tamamını verip daha sonra parça parça açıklamasını vereceğim.
Continue reading “Ev yapımı şifreleme”

Dosya ve dizin silme işlemi

Sitede bir arkadaşın sormuş olduğu soru üzerinden bu yazıyı eklemeye karar verdim, sorusuna da buradan bir cevap vermiş olurum. Vereceğimiz örnek dosya ve dizin silme işlemi ile ilgili olacak. Program fonksiyona gönderdiğimiz konumdaki (path) dosya ve dizinleri siliyor, her doysa/dizin silme işleminden sonra da bir ses dosyası çalıyor.

Kodumuz şöyle:

import os,audio,e32
sound_lock=e32.Ao_lock()

def sound_callback(onceki_durum,simdiki_durum,hata):
    if simdiki_durum==audio.EOpen:
        sound_lock.signal()

def ses_cal():
    sound=audio.Sound.open("z:\\Nokia\\Sounds\\Digital\\Alarm.mid")
    sound.play(callback=sound_callback)
    sound_lock.wait()
    sound.close()
   

def sil(path):
  for name in os.listdir(path):
     new=path+’\\’+name
     if os.path.isdir(new):
        sil(new)
        try:
            ses_cal()
            os.rmdir(new)
           
        except:
           pass
     else:
        try:
            ses_cal()
            os.remove(new)
           
        except:
           pass

sil("e:\\deneme")

Burada ses_cal() ve sound_callback() metodlarından bahsetmek istiyorum.

def ses_cal():
    sound=audio.Sound.open("z:\\Nokia\\Sounds\\Digital\\Alarm.mid")

sound değişkenine çalmak istediğimiz ses dosyasını atadık.

sound.play(callback=sound_callback)

sound nesnesini çalmaya başlattık ve sound nesnesinin play() metodun bir çağrılabilir fonksiyon (callback function – bildiğimiz fonksiyon ) atadık.

sound_lock.wait()
sound.close()

sound_lock adıyla oluşturduğumuz e32.Ao_lock() nesnesinin wait() metodunu çağırdık, bu metotla bir olay meydana gelmesini beklediğimizi belirttik. Daha sonra sound nesnemizi kapattık ve çalma işlemimiz sona ermiş oldu.

def sound_callback(onceki_durum,simdiki_durum,hata):

sound nesnesinin play() metoduna atadığımız fonksiyon 3 parametreyle çalışır. Burada onceki_durum,simdiki_durum ve hata (bunlar sadece değişken isimleri, istediğiniz ismi verebilirsiniz) değişkenleridir. Bizim bu programda ilgilendiğimiz simdiki_durum parametresine gelen değerdir.

if simdiki_durum==audio.EOpen:
    sound_lock.signal()

Bu if bloğunda simdiki_durum değişkenimize gelen değeri kontrol ediyoruz. Eğer değerimiz audio.EOpen ise, wait durumunda olan sound_lock nesnemize signal() metoduyla bir olay gerçekleştiğini belirten sinyali gönderiyoruz.

Peki değerimizin audion.EOpen olması ne demek?

Play metoduyla çaldığımız ses dosyasının çalınabilir, başlatılabilir durumda olduğunu gösterir bize. Bunun anlamı nedir? Bunun anlamı ses dosyamız bir kere çalmış ve bir daha çalmaya hazır demektir.

Şimdi toparlayacak olursak, yazdığımız metod şu işe yarıyor; ses_cal() metodunda sound_lock nesnesinin wait metodunu çağırarak bir olay beklemesini söyledik. sound.play kısmında ses dosyamız çalmaya başlar ve play metoduna atadığımız fonksiyon çalışır. Bu fonksiyonun çalışmasını anlatmıştık, eğer simdiki_durum audio.EOpen değilse sond_lock nesnesinin wait() metoduna bir sinyal gitmeyecek ve program play işlemi içerisinde kalacaktır, diğer kodlar işletilmeyecektir, taa ki ses dosyası bitene kadar. Ses dosyasının çalma işlemi bittiğinde sinyal gönderilecek ve program kaldığı yerden devam edecektir.

Yazdığımız programda her dosya/dizin silindiğinde ses dosyamızı çalıyoruz ve ses dosyamızın çalma işlemi bitene kadar diğer dosya/dinizini silmiyoruz.

Şimdilik bu kadar, kalın sağlıcakla…

05.02.08 tarihinde yapılan düzenleme:

Arkadaşın sorusu üzerine yolunu verdiğimiz konumda arama yapacak (örneğin c:\\) ve adını verdiğimiz dosyayı bulduğunda silecek, bulamadığında ise böyle bir dosya yoktur mesajı yazacak kodu ekliyorum.

import os
def ara_sil(konum,dosya):
    for root, dirs, files in os.walk(konum):
            for name in files:
                print root+" konumunda araniyor"
                if name==dosya:
                    print name+" dosyasi silindi"
                    os.remove(os.path.join(root, name))
                    return
    print dosya+ " dosyasi bulunamadi"
             
ara_sil("c:\\","yaziyazi.txt")

os.walk() fonksiyonu yolunu verdiğimiz konumdaki dosya/dizinler üzerinde gezinmemizi sağlıyor.
root: O anda içerisinde bulunduğunuz konumu tutuyor, string türünde bir değişkendir.
dirs: Bulunduğunuz konumdaki dizinleri tutuyor, liste türünde bir değişkendir.
files: Bulunduğunuz konumdaki dosyaları tutuyor, liste türünde bir değişkendir.

İşlevsel bir örnek olmakla beraber arkadaşın sorusuna yanıt olmuş değil maalesef. Örneği telefonumda denediğimde Python mobil sürümünün os.walk() fonksiyonunu desteklemediğini gördüm. Ancak diğer işletim sistemlerinde sorunsuz çalışıyor.

Mobil uygulamalarda arama yapmak için böyle bir fonksiyon var mı bilmiyorum. Sanırım bunun cevabını alabileceğiniz en iyi yer forum nokia.

Şimdilik bu kadar, kalın sağlıcakla…

Yazgaç hakkında

Yazgaç bizi halihazırda kullandığınız text editörden vazgeçirecek özelliklere sahip değil, o amaçla da yazmadım zaten. GUI olarak wxpython kullanan arkadaşlara faydalı olması ve genel python kullanımına örnek olması için yazdım. Programda bazı eksiklikler mevcut. Bir zaman sonra bunlarla uğraşamadığım, bir kısmını ise araştırdığım halde çözemediğim için bu şekliyle yolladım.

Belirlediğim eksikleri:

* Program ilk açıldığında düzen menü elemanlarından ve toolbar elemanlarından “kes, kopyala, yapıştır, sil” gibi öğelerin pasif olması gerekiyor. Pasif olması için gerekli kod basit ancak hangi durumda pasif olacağını ayarlamak güç oldu. Editörden herhangi bir metin seçildiği takdirde o elemanların aktfi olması gerekiyor, bunu kontrol etmekte kolay, editörden metin seçilip seçilmediği kontrol edilebilir, ancak o kodun her seçimde çalışması için bir EVENT’i vardır diye düşünüyorum, ben kurcaladım biraz bulamadım. Bilen arkadaşlar paylaşırsa güncelleriz o kısmını. Mesela “geri al” menü elemanını kontrol edebiliyorum onun durumu biraz farklı olduğu için düzenlemek sorun olmadı, onun kontrolü için özel bir EVENT’e gerek yok.

15 Kasım 16:21 de gelen düzeltme:

Yukarıda belirttiğim eksikliği bir timer tanımlayarak çözdüm. init() metodu içinde 100 milisaniyede bir çalışan bir timer tanımlıyoruz. Timer 100 milisaniyede bir timer’ı oluştururken belirlediğimiz metodu çalıştırıyor. O metodta GetSelection metodu ile ekranda seçili öğe olup olmadığını kontrol ediyoruz, seçili öğe varsa o elemanları aktif, seçim yoksa pasif yapıyoruz.

Eklediğim kod şu şekilde:

__init__ metodunda herhangi bir yere aşağıdaki kodu ekliyoruz.

self.timer=wx.Timer(self,-1)
self.timer.Start(100)
wx.EVT_TIMER(self,self.timer.GetId(),self.ontimer)

daha sonra ontimer() metodunu ekliyoruz.

def ontimer(self,evt):
        ilk,son=self.metinAlani.GetSelection()
        if ilk==son:
             self.menuBar.Enable(ID_SIL,False)
             self.menuBar.Enable(ID_KES,False)
             self.menuBar.Enable(ID_KOPYALA,False)

             
             self.toolbar.EnableTool(ID_SIL,False)
             self.toolbar.EnableTool(ID_KES,False)
             self.toolbar.EnableTool(ID_KOPYALA,False)
        else:
            self.menuBar.Enable(ID_YAPISTIR,True)
            self.menuBar.Enable(ID_SIL,True)
            self.menuBar.Enable(ID_KES,True)
            self.menuBar.Enable(ID_KOPYALA,True)

            self.toolbar.EnableTool(ID_YAPISTIR,True)
            self.toolbar.EnableTool(ID_SIL,True)
            self.toolbar.EnableTool(ID_KES,True)
            self.toolbar.EnableTool(ID_KOPYALA,True)
        
            
        if self.metinAlani.CanPaste():
            self.toolbar.EnableTool(ID_YAPISTIR,True)
            self.menuBar.Enable(ID_YAPISTIR,True)
        else:
            self.toolbar.EnableTool(ID_YAPISTIR,False)
            self.menuBar.Enable(ID_YAPISTIR,False)

Not: Sitedeki kod ve programın tamamının bulunduğu dosya güncellenmiştir.

* Bir diğer önemli sorun ise program ilk başladığında boş bir sayfayla başlaması. Bu benim yazdığım şekli, bunda bir sorun yok. Sorun şurda çıkıyor; mesela programı py2exe ile exe’sini oluşturdunuz ve txt uzantılı bir dosyayı Yazgaç’la açılması için ayarladınız, ama açılmadı. Çünkü açılışta böyle bir kontrol yapılmıyor. Bu işi yapmak için sys.argv kullanmak gerektiğini düşünüyorum. Ancak biraz kurcaladım bu işi görecek şekilde düzenleyemedim. Bu da düzeltilmesi gereken bir sorun.

* Programı yazdıktan sonra FontDialog konusunda da bir eksiklik olduğunu farkettim. Herşey iyi güzel çalışıyorda yazının rengi değişmiyor mesela. Onun için ayrıca birşeyler ayarlamak gerekli sanırım.

* Programa “bul” özelliği de eklenebilir.

Benim farkettiğim eksiklikler bu kadar, illa ki başka eksiklikleri de vardır. Ama dediğim gibi amacım çalışan, kullanılabilir bir program yazmak değil, sadece örnek teşkil etmesi, amacım öyle bir program yazmak olsaydı daha özen gösterirdim, ancak şu an böyle birşey için gerek de görmüyorum, vaktim de yok.

Programda sitede anlatacağımı söylediğim menuYap() metodundan bahsedeyim biraz. Programı yazarken menü elemanlarını oluşturmak için aynı kodu ufak tefek farklarla defalarca yazdığımı farkettim ve bunu bir metodla halletmeye karar verdim.

def menuYap(self,menuAdi,menuParam,fParam,idParam):

        menu=wx.Menu()
        sayac=0

        for i in menuParam:
            if i=="sep":
                menu.AppendSeparator()
                continue
            else:
                item=menu.Append(idParam[sayac],i,kind=wx.ITEM_NORMAL)
                self.Bind(wx.EVT_MENU,fParam[sayac],item)
                sayac=sayac+1
        self.menuBar.Append(menu,menuAdi)       

Metodu şu şekilde çağırıyoruz:

        
dosyaMenu=["Yeni\tCTRL+N","Aç\tCTRL+O","Kaydet\tCTRL+S","Farklı Kaydet","sep","Çık"]
dosyaFonksiyon=[self.yeni,self.ac,self.kaydet,self.farkliKaydet,self.cik]
dosyaID=[ID_YENI,ID_AC,ID_KAYDET,ID_FKAYDET,ID_CIK]
self.menuYap("&Dosya",dosyaMenu,dosyaFonksiyon,dosyaID)

Öncelikle metodun aldığı parametrelere bakalım.
menuAdi= Menünün adını içeren string bir değişken içeriyor. Mesela “Dosya”.
menuParam= Bu parametre menü elemanlarına vereceğimiz label (etiket) leri içeriyor.
fParam= Bu parametre menü elemanına tıkladığımızda çağrılacak metodları içeriyor. Değişken bir liste ve listenin elemanları metodlardan oluşuyor.
idParam= Menü elemanlarına vereceğimiz ID’leri içeriyor. Menü elemanlarını gerekli yerlerde aktif/pasif yapabilmek için ID tanımladık.
Metod ilk olarak bir “menu” adında bir menü nesnesi oluşturuyor. Daha sonra for döngüsüyle menuParam içerisindeki elemanları teker teker geziyoruz. menuParam içindeki değerlere “i” üzerinden ulaşıyoruz. Öncelikle menuParam içerisinde “sep” değeri varmı diye kontrol ediyoruz. Eğer i değişkenimiz “sep” değerine eşitse bir separator(ayırıcı) eklememiz gerektiğini anlıyoruz. Burada önemli nokta continue komutudur. Bu komut döngüyü orada keserek başa döndürür ve döngü bir sonraki değer için tekrar döner.

Eğer “sep” değeri gönderilmişse seperator eklememiz gerekiyor, ondan sonraki kod menüye menü elemanı eklemek için, separator için menü elemanı eklemeyeceğimiz için döngüyü bir sonraki değer ile dönmesi için başa gönderiyoruz. Eğer değerimiz “sep” değilse bu demektirki menü elemanı oluşturacağız. else bloğu içerisindeki kodlar bu işi yapıyor.

İlk olarak menüye elemanımızı ekliyoruz ve “item” değişkenine atıyoruz. Append metodundaki parametreler şöyle:
idParam[sayac]= idParam parametresi ile gelen değerlerden sayac indisinde olan değeri alıyor, sayac değeri 0′dan başlayıp fParam veya idParam indisine kadar gidiyor.
Metod yukarıdaki çağırımla ilk çalıştığında ilk değeri ID_YENI’dir.
i= menuParam parametresi ile gelen menü elemanının adını içeriyor.
Metod yukarıdaki çağırımla ilk çalıştığında ilk değeri “Yeni” dir.
kind=wx.ITEM_NORMAL ise menü elmanının normal özellikte olduğunu söylüyor. wx.ID_CHECK gibi değişik özellikleri mevcut.
Bir sonraki kodda ise menü elamanına olay atıyoruz.
Bind metodunun parametreleri:
wx.EVT_MENU= menü olayının adı, menüye tıklanma olayı.
fParam[sayac]= fParam parametresinin sayac indisinde içerdiği metodu verir.
Metod yukarıdaki çağırımla ilk çalıştığında ilk değeri self.yeni’dir
item değişkenini yukarıda belirtmiştik.
Menüye bir eleman eklediğimiz için sayac değerini 1 arttırıyoruz.
Son olarak init metodunda oluşturmuş olduğumuz menuBar’a menümüzü ekliyoruz.

Umarım açıklayıcı olmuştur.

Bu arada gui kütüphanesi olarak wxpython kullanmayacağım. QT kullanmayı düşünüyorum. Açıkçası wxpython kullanırken çeşitli sıkıntılar yaşadım, qt’nin bunları yaşatmayacağını umuyorum.

Kalın sağlıcakla.