Successfully reported this slideshow.
Your SlideShare is downloading. ×

Python-GTK

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

Python-GTK

  1. 1. Python-GTK Yuren Ju <yurenju@gmail.com>
  2. 2. 請先安裝 ● sudo apt-get install python-pywapi glade
  3. 3. Yuren Ju ● Yuren's Info Area - http://yureinfore.blogspot.com/ ● Yuren Ju – Linkedin http://tw.linkedin.com/in/yurenju ● Hacking Thursday 成員 - http://hack.ingday.org/
  4. 4. 本份投影片…… ● 假設你學過任何一種程式語言 ● 特別有可能是 Java
  5. 5. + Python GTK+
  6. 6. TIOBE 程式語言社群指標 Source: TIOBE Software index
  7. 7. ? Source: "Why?", Mike Luckovich, Pulitzer-Winning Political Cartoonist (1 of 4), cc-by-deed
  8. 8. 別人怎麼說… ● 適合初學者,但也適合進階開發者 ● 高度彈性:從大型專案到小型專案都適合使用 ● you can get the job done Source: What is Python and Why Python
  9. 9. 成功案例
  10. 10. 成功案例 ● 四年前…… ● Python 初體驗 - 好吃不黏牙! ● 要找個簡單的語言寫作業 ● Perl? PHP? Java? ● Perl: 學過了,想換個口味 ● PHP: 在網頁上寫很麻煩,直接寫成 script 感覺又有點怪 ● Java: 程式碼超長 – Print: System.out.println – 每個程式都一定要宣告 Class
  11. 11. 對我來說的 Python 優點 ● 短小精簡 ● 程式碼簡潔 ● 快速驗證想法 ● 處理工作雜事 ● e.g. 產生報表、字串置換等
  12. 12. GTK+
  13. 13. GTK+ Qt wxWidgets Windows Form Android MFC Swing/AWT View/Widget/Layout
  14. 14. Cross Platform crossing the line, Jkönig, CC BY-NC-SA 2.0
  15. 15. GTK+ C/C++ Python Perl Ruby C# PHP ... Linux Windows Mac
  16. 16. 使用 GTK 的軟 / 硬體 Nokia n900
  17. 17. Python
  18. 18. Start! 將程式碼寫於檔案中 打開終端機直接鍵入程式
  19. 19. 打開你的終端機! $ python
  20. 20. python command-line
  21. 21. print " 你好世界! "
  22. 22. 數值指定 不需要宣告形態 ● String ● Boolean ● var = "this is String" ● var = True ● Integer ● Float ● var = 1 ● var = 0.1 String var = "this is String"; int var = 1; boolean var = true; float var = 0.1;
  23. 23. Python 鐵則 ● if/else 不用括號 ● 每行結尾不用分號 ● 縮排 ● 冒號
  24. 24. Example: agent smith if first == True: print "Mr. Anderson." else: print "Welcome back, we missed you." if (first == true) { System.out.println ("Mr. Anderson."); } else { System.out.println ("Welcome back, we missed you."); }
  25. 25. 開頭原本是用括號的地方改用冒號 4 個空白或是一個 tab if first == True: print "Mr. Anderson." else: print "Welcome back, we missed you." 結尾不需要括號
  26. 26. list & dict ● list => 陣列 ● dict => hash table
  27. 27. list ● actors = ["Neo", "Smith", "Trinity", "Oracle"] ● mixed = ["hi", "apple", 0, 0.1, False] ● print actors[1] ● actors.append ("Morpheus") ● del actors[1] ● actors.remove ("Oracle")
  28. 28. list (cont.) for a in actors: print a for a in actors[2:]: print a print sorted (actors) del actors[2:]
  29. 29. dict person = {"name": "Yuren Ju", "website": "http://yure...", "birthday": "yyyy/mm/dd"} print person["name"] print person["website"]
  30. 30. dict for k in person: print "%s: %s" % (k, person[k]) if person.has_key ("age"): print "no age attribute"
  31. 31. function def func (arg1, arg2): #Do something... return ret
  32. 32. 奇技淫巧 ● newlist = [n for n in oldlist if n > 50] ● function return 多個回傳值
  33. 33. Editor 將程式碼寫於檔案中
  34. 34. 建議 ● Geany ● Gedit ● eclipse ● Of cause~ vim!
  35. 35. Hello-world.py # -*- coding: utf-8 -*- print "你好世界!"
  36. 36. line 1 Python String Byte String Unicode String 預設 # -*- coding: utf-8 -*-
  37. 37. gedit
  38. 38. 實戰?
  39. 39. http://ajax.googleapis.com/ajax/services/language/translate? v=1.0&ie=utf8&q=test&langpair=en|zh-tw http://j.mp/dXYwLT
  40. 40. #!/usr/bin/env python # -*- coding: utf-8 -*- from urllib2 import urlopen from urllib import urlencode import simplejson import sys def translate(text): sl="zh-tw" tl="en" langpair='%s|%s'%(tl,sl) base_url = 'http://ajax.googleapis.com/ajax/services/language/translate?' data = urlencode({'v':1.0,'ie': 'UTF8', 'q': text, 'langpair':langpair}) url = base_url+data urlres = urlopen(url) json = simplejson.loads(urlres.read()) result = json['responseData']['translatedText'] return result if __name__ == "__main__": print translate (sys.argv[1]) https://gist.github.com/801339
  41. 41. tw-weather.py #!/usr/bin/env python # -*- coding: utf-8 -*- import pywapi cities = pywapi.get_cities_from_google('tw', 'zh-tw') for c in cities: print "%s: " % (cities.index(c)+1), print c['name'] num = int (raw_input ("type: ")) city = cities[num-1] weather = pywapi.get_weather_from_google(',,,%s,%s' % (city['latitude_e6'], city['longitude_e6']), 'zh-tw') print "天氣:%s" % weather['current_conditions']['condition'].encode ('utf-8') print "濕度:%s" % weather['current_conditions']['humidity'].encode ('utf-8') print "現在溫度:%s" % weather['current_conditions']['temp_c'].encode ('utf-8') https://gist.github.com/801493
  42. 42. Class/Object #!/usr/bin/env python class FirstClass { private String[] data; # -*- coding: utf-8 -*- public FirstClass() { class FirstClass: String[] data = {"a", "b", "c"}; this.data = data; def __init__(self): } self.data = ["a", "b", "c"] public void printData() { for (int i = 0; i < data.length; i++) { def print_data(self): System.out.println (data[i]); print self.data } } if __name__ == "__main__": public static void main (String[] args) { f = FirstClass() FirstClass f = new FirstClass(); f.print_data() f.printData(); } }
  43. 43. GTK+
  44. 44. #!/usr/bin/env python import pygtk pygtk.require ('2.0') import gtk if __name__ == "__main__": window = gtk.Window (); window.show () gtk.main ()
  45. 45. Event Handler
  46. 46. widget.connect("signal-name", callback)
  47. 47. #!/usr/bin/env python import pygtk pygtk.require ('2.0') import gtk def destroy (window): gtk.main_quit () def hello (button): print "Hello World" if __name__ == "__main__": window = gtk.Window () window.connect ("destroy", destroy) window.show () button = gtk.Button ("hello"); button.connect ("clicked", hello) button.show () window.add (button) gtk.main () gtk reference - gtk.Button
  48. 48. Keep state, using class/object #!/usr/bin/env python import pygtk pygtk.require ('2.0') import gtk class HelloWorld: def __init__ (self): window = gtk.Window () window.connect ("destroy", self.destroy) window.show () button = gtk.Button ("hello"); button.connect ("clicked", self.hello) button.show () window.add (button) self.position = 0 def destroy (self, window): gtk.main_quit () def hello (self, button): print "Hello World, position: %d" % self.position self.position += 1 if __name__ == "__main__": hello = HelloWorld () gtk.main () https://gist.github.com/801496
  49. 49. Layout. layouts, Kemeny_x, CC BY-NC 2.0
  50. 50. GTK+ Layout – box packing
  51. 51. HBox VBox
  52. 52. HBox VBox VBox
  53. 53. pack_start / pack_end hbox = gtk.HBox() vbox1 = gtk.VBox() vbox2 = gtk.VBox() hbox.pack_start(vbox1) hbox.pack_start(vbox2)
  54. 54. window = gtk.Window () hbox = gtk.HBox() vbox1 = gtk.VBox() vbox2 = gtk.VBox() hbox.pack_start(vbox1) hbox.pack_start(vbox2) label = gtk.Label ("Text: ") vbox1.pack_start (label) textview = gtk.TextView () vbox1.pack_start (textview) button_ok = gtk.Button ("OK") vbox2.pack_end (button_ok) button_cancel = gtk.Button ("Cancel") vbox2.pack_end (button_cancel) hbox.show_all() window.add(hbox) window.show()
  55. 55. layout expand=True expand=True expand=False fill=True fill=False fill=False
  56. 56. window = gtk.Window () hbox = gtk.HBox() vbox1 = gtk.VBox() vbox2 = gtk.VBox() hbox.pack_start(vbox1) hbox.pack_start(vbox2, expand=False) label = gtk.Label ("Text: ") label.set_property('xalign', 0.0) textview = gtk.TextView () vbox1.pack_start (label, expand=False) vbox1.pack_start (textview) button_ok = gtk.Button ("OK") button_cancel = gtk.Button ("Cancel") vbox2.pack_end (button_ok, expand=False) vbox2.pack_end (button_cancel, expand=False) hbox.show_all() window.add(hbox) window.show()
  57. 57. Gtk Builder
  58. 58. Gtk Builder builder = gtk.Builder () builder.add_from_file ("layout.glade") window = builder.get_object ("window1") window.show () builder.connect_signals (self)
  59. 59. 翻譯軟體 – GTK 版本 ● 拉 UI (glade) ● 事件分配 (glade) ● 事件分配 (python)
  60. 60. gtk.TextView 顯示文字內容 gtk.TextView 操作文字: gtk.TextBuffer - insert - delete
  61. 61. UI Freeze Frozen Moment, drinksmachine, by-nc-nd
  62. 62. English 中文 UI Freeze
  63. 63. 費時的操作 UI Freeze
  64. 64. Thread 嘿 Neo, 又是我
  65. 65. 費時的操作 Thread UI update
  66. 66. Thread def translate(text): ... ... class TransThread (Thread): def __init__(self, text, obj): self.text = text Thread.__init__(self) def run(self): try: self.result = translate(self.text) except: self.result = "error"
  67. 67. Communication? UI part ? Thread part
  68. 68. 概念 ● 繼承 gobject 或 gtk.Object ● 註冊一個信號 (signal) ● 連接此 signal ● 當 Thread 結束後射出 (emit) 此 signal
  69. 69. 步驟 ● gobject.type_register (Translation) ● gobject.signal_new("thread-complete", Translation, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()) ● self.connect ("thread-complete", self.thread_complete) ● self.obj.emit("thread-complete") gtk-gtr2.py
  70. 70. 範例
  71. 71. View Model TreeView ListStore TreeViewColumn TreeStore CellRendererText
  72. 72. Glade ListStore
  73. 73. Weather 產生城市列表 取得城市天氣 selected_city __init__ load-cities-completed load-weather-completed Create CitiesThread Create WeatherThread
  74. 74. __init__ def __init__(self): self.__gobject_init__() self.builder = gtk.Builder() self.builder.add_from_file ("weather.glade") self.builder.connect_signals(self) win = self.builder.get_object("window1") win.show_all() self.register_signals() self.cities_thread = CitiesThread(self) self.cities_thread.start() self.tree = self.builder.get_object("treeview_cities") col_name = gtk.TreeViewColumn("city name") self.tree.append_column(col_name) cell = gtk.CellRendererText() col_name.pack_start(cell, True) col_name.add_attribute(cell, 'text', 0) self.tree.connect("cursor-changed", self.selected_city)
  75. 75. CitiesThread class CitiesThread(Thread): def __init__(self, obj): self.obj = obj Thread.__init__(self) def run(self): self.cities = pywapi.get_cities_from_google('tw', 'zh-tw') gtk.gdk.threads_enter() self.obj.emit("load-cities-completed") gtk.gdk.threads_leave()
  76. 76. WeatherThread class WeatherThread(Thread): def __init__(self, obj, latitude, longitude): self.obj = obj self.latitude = latitude self.longitude = longitude Thread.__init__(self) def run(self): weather = pywapi.get_weather_from_google(',,,%s,%s' % (self.latitude, self.longitude), 'zh-tw') self.weather = {"condition": weather['current_conditions']['condition'], "humidity": weather['current_conditions']['humidity'], "temp_c": weather['current_conditions']['temp_c']} gtk.gdk.threads_enter() self.obj.emit("load-weather-completed") gtk.gdk.threads_leave()
  77. 77. load-cities-completed def load_cities_completed(self, obj): self.cities = self.cities_thread.cities self.liststore = self.builder.get_object("cities") for city in self.cities: self.liststore.append ([city['name'], long(city['latitude_e6']), long(city['longitude_e6'])])
  78. 78. load-weather-completed def load_weather_completed(self, obj): weather = self.weather_thread.weather self.builder.get_object("label_temperature") .set_markup ("<span size='xx-large'>溫度:%s</span>" % weather['temp_c']) self.builder.get_object("label_current") .set_label ("現在天氣:%s" % weather['condition']) self.builder.get_object("label_humidity") .set_label ("濕度:%s" % weather['humidity'])
  79. 79. selected_city def selected_city(self, tree): selection = self.tree.get_selection() (model, iter) = selection.get_selected() name = model.get_value(iter, 0) latitude = model.get_value(iter, 1) longitude = model.get_value(iter, 2) print "%s (%s, %s)" % (name, latitude, longitude) self.weather_thread = WeatherThread(self, latitude, longitude) self.weather_thread.start()
  80. 80. gtk-weather.py https://gist.github.com/800513
  81. 81. 釣竿 ● Dive Into Python 中文版 ● PyGTK 2.0 Tutorial ● PyGTK 2.0 Reference Manual ● google "python gtk < 問題關鍵字 >" ● 在 stackoverflow.com 上面找答案

×