Fold All / Expand All

2008年1月26日 星期六

PythonCard初嘗試

PythonCard
把wxPython再包一層,並提供Resource Editor…等工具。

剛才試了一下,拿來寫pyLyricRetriever的GUI,code量銳減!

不過之前wxPython是把layout直接用code寫,PythonCard則是透過resource的方式,因此理所當然code量不同。

兩者的GUI畫起來,還蠻不同的感覺,之前的wxPython是利用wxGlade,layout都是用sizer去排,所以multiline textfield可以跟著視窗改變大小。而PythonCard目前似乎還沒支援sizer,所以是position, size固定值,是否可以resize那邊就disable掉啦~~。

Binding也是不同,在PythonCard直接寫成on_componentName_eventName即可,原本需要下binding
self.Bind(wx.EVT_BUTTON, self.OnClick, self.button_query)
就直接把OnClick()取名為
def on_queryButton_mouseClick(self, event):
即可

原本透過getter, setter也變成直接存取該value,例如
self.components.lyricTextArea.text = ''

不過PythonCard的document還不是很詳盡,為了簡化wxPython,很多功能就找了老半天才發現。例如一開要將focus設在輸入網址的textfield,在wxPython的時候,就在__init__()裡面放一個SetFocus(),而PythonCard沒有寫__init__()的習慣,要達到這個效果的方法是讓該textfield為resource的第一個(即components順位會影響focus)。

要控制statusbar的話,請用self.statusBar.text,在官方document也沒看到,後來在別的地方才咕到。
#!/usr/bin/python
# coding: utf-8
from PythonCard import model, dialog
import lyric_engine

class Main(model.Background):
def on_queryButton_mouseClick(self, event):
# get lyric page url
url = self.components.urlTextField.text

# clear lyric textarea
self.components.lyricTextArea.text = ''

# verify url, if invalid, popu a warning dialog
self.statusBar.text = 'verifying url...'
url = self.verify_url(url)
if url == False:
self.show_invalid()
return False

# processing url
self.statusBar.text = 'processing url...'
lyric = self.process_url(url)
if lyric == None:
self.show_invalid()
return False

# show lyric
self.statusBar.text = 'showing lyric'
self.show_lyric(url, lyric)

self.statusBar.text = 'lyric retrieved!'

def show_lyric(self, url, lyric):
# set the first line as the url of lyric
# then the following is the lyric
string = unicode('lyric from '+url) + u'\n\n' + lyric
self.components.lyricTextArea.text = string

def process_url(self, url):
""" choose different processing function to handle """
engine = lyric_engine.Lyric(url)
lyric = engine.get_lyric()

return lyric

def verify_url(self, url):
""" check if 'http://' is in the input string """
if url.find('http://') == -1:
return False
else:
return url

def show_invalid(self):
self.statusBar.text = 'invalid url'
result = dialog.alertDialog(self, 'Invalid URL', 'Error')

if __name__ == '__main__':
app = model.Application(Main)
app.MainLoop()


{'application':{'type':'Application',
'name':'Template',
'backgrounds': [
{'type':'Background',
'name':'bgTemplate',
'title':u'Standard Template with File->Exit menu',
'size':(626, 630),
'statusBar':1,
'icon':'lyric_ico.ico',

'menubar': {'type':'MenuBar',
'menus': [
{'type':'Menu',
'name':'menuFile',
'label':'&File',
'items': [
{'type':'MenuItem',
'name':'menuFileExit',
'label':'E&xit',
'command':'exit',
},
]
},
]
},
'components': [

{'type':'TextField',
'name':'urlTextField',
'position':(50, 10),
'size':(305, 25),
'font':{'faceName': u'Tahoma', 'family': 'sansSerif', 'size': 12},
'text':u'please input the url of lyric',
},

{'type':'Button',
'name':'queryButton',
'position':(370, 10),
'size':(80, 25),
'default':True,
'font':{'faceName': u'Tahoma', 'family': 'sansSerif', 'size': 12},
'label':u'Download',
},

{'type':'TextArea',
'name':'lyricTextArea',
'position':(10, 40),
'size':(600, 500),
'editable':False,
'font':{'faceName': u'Meiryo', 'family': 'sansSerif', 'size': 12},
},

{'type':'StaticText',
'name':'urlText',
'position':(10, 10),
'font':{'faceName': u'Tahoma', 'family': 'sansSerif', 'size': 12},
'text':u'URL:',
},

] # end components
} # end background
] # end backgrounds
} }

沒有留言: