Movatterモバイル変換


[0]ホーム

URL:


泰 増田, profile picture
Uploaded by泰 増田
10,732 views

wxPython入門(大阪Pythonユーザの集まり2014/03)

大阪Pythonユーザの集まり 2014/03 で発表した、wxPython入門のスライドです。

Embed presentation

Downloaded 30 times
wxPython入門増田 (@whosaysni)
自己紹介•  増田 泰 (@whosaysni)•  Google+ つかってません•  GitHub<<<BitBucket•  某バイオベンチャー勤務•  ドキュメント翻訳とかDjango本とか•  一般社団法人PyConJP理事•  PyConJPきてください 9/13-15•  http://2014.pycon.jp/
wxPython•  GUIライブラリ•  wxWidgetsのPythonラッパー•  SWIG使ってる•  各OSのGUIコンポーネントを使う•  OSXならCocoa•  Windowsならwin32•  LinuxならGTK•  wxWidgetsライセンス•  条文はLGPL2だが、バイナリの配布時に独自の使用許諾ができる例外条項がある
まずは基本
GUIプログラム•  シェルで起動•  操作(イベント)に合わせてハンドラが呼ばれる•  ハンドラがUIコンポーネントを操作する•  次のイベント待ちGUIプログラミングって?スクリプト•  シェルで起動•  処理を逐次実行•  最後の処理を終えたら終了•  シェルに制御を戻すWebフレームワーク•  Webサーバが起動•  リクエストに合わせてハンドラが呼ばれる•  ハンドラがレスポンス返す•  次のリクエスト待ちディスパッチハンドラビュー操作イベントループ
ウィジェット Widget•  ボタンとかウィンドウとか、画面の構成要素•  UIを実際に描画する(自動的にね)•  ユーザ操作に応じてイベントを生成する•  wxPython/wxWidget•  ほとんどのウィジェットがクラスで階層化wxObject ... wxWindowwxControlwxBu4onwxSta7cTextwxMenu...wxPanelwxTopLevelWindowwxFramewxDialog
イベントループwhile len(event_q):ev = event_q.pop()handler = dispatch(ev)if handler:handler(ev)イベントキューイベントループロジックGUI操作その他  イベントイベントハンドライベントハンドライベントハンドラたいていのGUIフレームワークには、・イベントループを実行する関数・ハンドラを登録する関数があり、(1)ハンドラを定義して(2)ディスパッチャに登録し、(3)イベントループを呼ぶようになっている。
wxPythonのイベントループ>>> import wx>>> app = wx.App() # Appインスタンス>>> frame = wx.Frame(None) # ウィンドウつくる>>> app.SetTopWindow(frame)>>> frame.Show(True)True>>> app.MainLoop() # ここがメインループ(ループ中。ウィンドウ閉じるまで戻りませんw)
アプリは wxApp() をサブクラス化する# coding: utf-8import wxclass MyApp(wx.App):def OnInit(self): #Appインスタンス生成時に呼び出されるself.frame = wx.Frame(None) # 何でも属性にできる。Python最高ヤッホウself.frame.SetTitle(u'よろしくwxさん')self.SetTopWindow(self.frame)self.frame.Show(True)return True # お約束。重要if __name__=='__main__':app = MyApp()app.MainLoop()
GUIのレイアウト
GUIのレイアウト•  ウィジェットをウィンドウのどこに配置するか•  位置(x, y)と大きさ(w, h)•  配置(右寄せ、左寄せ)•  伸長(ウィンドウに合わせてサイズ変更)•  グループ化(OK/Cancelボタンとか)•  wxWidgetsでは、Sizerオブジェクトがレイアウトを制御する•  ウィンドウにSizerを登録する
BoxSizer()があれば無問題!だと思う硬派のSizer道(嘘)
BoxSizerwx.BoxSizer(wx.VERTICAL)wx.BoxSizer(wx.HORIZONTAL)v_box = wx.BoxSizer(wx.VERTICAL)v_box.Add(widget_A)v_box.Add(widget_B)h_box = wx.BoxSizer(wx.HORIZONTAL)h_box.Add(v_box)h_box.Add(widget_C)VERTICALHORIZONTALCAB
BoxSizerdef OnInit(self):...label = wx.StaticText(self.frame, -1, u'ボタン三兄弟', style=wx.ALIGN_CENTER)btn_1 = wx.Button(self.frame, -1, u'ボタン長男')btn_2 = wx.Button(self.frame, -1, u'ボタン次男 ')btn_3 = wx.Button(self.frame, -1, u'ボタン三男')sizer = wx.BoxSizer(wx.VERTICAL)btn_sizer = wx.BoxSizer(wx.HORIZONTAL)btn_sizer.Add(btn_1, 3, wx.ALL¦wx.EXPAND, 30)btn_sizer.Add(btn_2, 2, wx.ALL¦wx.EXPAND, 20)btn_sizer.Add(btn_3, 1, wx.ALL¦wx.EXPAND, 10)sizer.Add(label, 0, wx.ALL¦wx.EXPAND, 50)sizer.Add(btn_sizer, 0, wx.ALL¦wx.EXPAND, 0)self.frame.SetSizer(sizer)self.frame.Fit()505050 303030202010101020 20(上揃え)
イベント処理
おさらいイベントキューイベントループロジックGUI操作その他  イベントイベントハンドライベントハンドライベントハンドラGUIプログラム•  シェルで起動•  操作(イベント)に合わせてハンドラが呼ばれる•  ハンドラがUIコンポーネントを操作する•  次のイベント待ちディスパッチハンドラビュー操作イベントループ
イベントハンドラはどこにでも書けるdef event_handler(evt): #普通の関数...•  evt: イベントオブジェクト•  イベントの種類•  パラメタ(マウス座標など)•  その他、発生元のウィジェットなどの情報•  wx.Appのメソッドとして書くのがいい•  evtから他の変数引っ張るの大変•  詳しくはあとで
イベントをハンドラに結びつけるウィジェットの Bind() メソッドをつかう例: widget.Bind(wx.EVT_MOUSE, handler)•  この操作で、•  「widget」が•  「マウスイベント」を受け取ると•  handler を呼び出す•  アプリのインスタンスメソッドの場合•  def handler(self, evt): ...•  self.bind(wx.EVT_MOUSE, self.handler)
ハンドラの中でウィジェットを操作するdef OnInit(self):...self.btn = wx.Button(self.frame, -1, u'押さないで')self.btn.Bind(wx.EVT_BUTTON, self.OnOsunaPressed)def OnOsunaPressed(self, evt):self.btn.SetLabel(u'マジで'+self.btn.GetLabel())self.frame.Fit()
tips
アプリケーションの参照をとる•  Appクラスに変数置いてるんだけど。 →いいね!•  モジュール変数使って渡していい? ダメです•  ウィンドウにAppのインスタンス渡す?ダメ_人人人人人人人_> wx.GetApp() < ̄Y^Y^Y^Y^Y^Y ̄実例はあとで
大きなアプリを書くとき•  ウィンドウやダイアログがたくさんある•  ウィンドウごとにモジュールを作る•  wx.Dialogやwx.Frameをサブクラス化するほとんどのウィジェットをPurePythonでサブクラス化OK!Python完全勝利(S)!•  ウィンドウ固有の処理はモジュールに押し込める•  モジュールの if __module__==__main__ でwx.App を作ってアプリ化するこれで、画面構成モジュール単位で開発できます!
MVC的な住み分け•  Model基本、Appインスタンス経由で参照する•  ControllerビジネスロジックはAppインスタンスウィジェットの細かい操作が多ければ別モジュールに書くテストの住み分け的にも大事•  Viewウィジェットに複雑なデフォルト設定をしたいなら別モジュールに書くのがいい
ダメじゃないけどダメな例(app.py)def OnInit(self):self.main_window = wx.Frame(....)self.main_window_root_pane = wx.Panel(...)self.main_window_sizer = wx.BoxSizer(...)self.main_window_sizer.Add(self.main_window_root_pane)self.main_window.SetSizer(self.main_window_sizer)self.main_window_lr_sizer = wx.BoxSizer(...)self.main_window_left_pane = .......
いい感じな例(app.py)import wxfrom main_window import MainWindowclass MyApp(wx.App):def OnInit(self):self.main_window = MainWindow(...)self.SetTopWindow(self.main_window)...self.main_window.some_method(...)...return Truedef on_main_window_submit(self, evt):...(main_window.py)import wxclass MainWindow(wx.Frame):def __init__(self, *args, **kw):wx.Frame.__init__(self, *args, **kw)self.root_pane = wx.Panel(...)self.sizer = wx.BoxSizer(...)...self.Bind(SOMEEVENT,self.app.on_main_window_submit)@propertydef app(self):return wx.GetApp()def some_method(self, ...)... do something ...こっちは  プレゼンテーション寄りこっちはビジネスロジック寄り  
いい感じな例(app.py)import wxfrom main_window import MainWindowclass MyApp(wx.App):def OnInit(self):self.main_window = MainWindow(...)self.SetTopWindow(self.main_window)...self.main_window.some_method(...)...return Truedef on_main_window_submit(self, evt):...(main_window.py)import wxclass MainWindow(wx.Frame):def __init__(self, *args, **kw):wx.Frame.__init__(self, *args, **kw)self.root_pane = wx.Panel(...)self.sizer = wx.BoxSizer(...)...self.Bind(SOMEEVENT,self.app.on_main_window_submit)@propertydef app(self):return wx.GetApp()def some_method(self, ...)... do something ...こっちは  プレゼンテーション寄りこっちはビジネスロジック寄り  
モジュールのモック化(main_window.py)import wxclass MainWindow(wx.Frame):def __init__(self, *args, **kw):wx.Frame.__init__(self, *args, **kw)self.root_pane = wx.Panel(...)self.sizer = wx.BoxSizer(...)...self.Bind(SOMEEVENT,self.app.on_main_window_submit)@propertydef app(self):return wx.GetApp()...(続く)(続き)...# ここからモック駆動用コードif __name__== __main__ :class DemoApp(wx.App):def on_main_window_submit(self, evt):... do some nothing ......# モックアプリを作って走らせるapp = DemoApp()w = MainWindow(None)app.main_window = wapp.SetTopWindow(w)app.MainLoop()「ホホウ。もう出来てるじゃないか。じゃあ工数減らして見積り再提出してもらえんかね」とお客様に言われても当方は一切責任をもちません
おすすめツール•  wxPython Demohttp://www.wxpython.org/download.phpDemoを見れば大抵のウィジェットは使える•  Dashhttps://itunes.apple.com/jp/app/dash-docs-snippets/id458034879?mt=12wxWidets のドキュメントがあります
enjoy!

Recommended

PDF
Dexcs2021 of install2
PDF
Oci file storage service deep dive 20181001 ss
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
オープンソースからの高位合成によるORB-SLAM FPGA実装
PDF
今もう一度知ろう。 Solarisのコンテナ型仮想化技術
PDF
日本一詳しい人が教えるUE4
PDF
Docker Swarm入門
PPTX
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
PDF
[아이펀팩토리] 2018 데브데이 서버위더스 _04 리눅스 게임 서버 성능 분석
PDF
[UE4]自動テストでもっと楽したい!
 
PPTX
Wiresharkの解析プラグインを作る ssmjp 201409
PPTX
PostgreSQLのgitレポジトリから見える2021年の開発状況(第30回PostgreSQLアンカンファレンス@オンライン 発表資料)
PPTX
java.lang.OutOfMemoryError #渋谷java
PDF
CI/CDツール比較してみた
PDF
MHA for MySQLとDeNAのオープンソースの話
PDF
Akkaで分散システム入門
PPTX
Ganglia のUIにGrafanaを追加する話
PPTX
やってはいけない空振りDelete
PPTX
Effective Modern C++ 勉強会 Item 22
KEY
やはりお前らのMVCは間違っている
PDF
2025年現在のNewSQL (最強DB講義 #36 発表資料)
PDF
UniRx完全に理解した
PDF
世界最強のソフトウェアアーキテクト
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
PDF
企業システムにアジャイルは必要か
PPTX
オレ流のOpenJDKの開発環境(JJUG CCC 2019 Fall講演資料)
PDF
PlaySQLAlchemyORM2017.key
PDF
PlaySQLAlchemy: SQLAlchemy入門

More Related Content

PDF
Dexcs2021 of install2
PDF
Oci file storage service deep dive 20181001 ss
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
オープンソースからの高位合成によるORB-SLAM FPGA実装
PDF
今もう一度知ろう。 Solarisのコンテナ型仮想化技術
PDF
日本一詳しい人が教えるUE4
PDF
Docker Swarm入門
Dexcs2021 of install2
Oci file storage service deep dive 20181001 ss
コンテナの作り方「Dockerは裏方で何をしているのか?」
Spring Bootをはじめる時にやるべき10のこと
オープンソースからの高位合成によるORB-SLAM FPGA実装
今もう一度知ろう。 Solarisのコンテナ型仮想化技術
日本一詳しい人が教えるUE4
Docker Swarm入門

What's hot

PPTX
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
PDF
[아이펀팩토리] 2018 데브데이 서버위더스 _04 리눅스 게임 서버 성능 분석
PDF
[UE4]自動テストでもっと楽したい!
 
PPTX
Wiresharkの解析プラグインを作る ssmjp 201409
PPTX
PostgreSQLのgitレポジトリから見える2021年の開発状況(第30回PostgreSQLアンカンファレンス@オンライン 発表資料)
PPTX
java.lang.OutOfMemoryError #渋谷java
PDF
CI/CDツール比較してみた
PDF
MHA for MySQLとDeNAのオープンソースの話
PDF
Akkaで分散システム入門
PPTX
Ganglia のUIにGrafanaを追加する話
PPTX
やってはいけない空振りDelete
PPTX
Effective Modern C++ 勉強会 Item 22
KEY
やはりお前らのMVCは間違っている
PDF
2025年現在のNewSQL (最強DB講義 #36 発表資料)
PDF
UniRx完全に理解した
PDF
世界最強のソフトウェアアーキテクト
PDF
ネットワーク ゲームにおけるTCPとUDPの使い分け
PDF
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
PDF
企業システムにアジャイルは必要か
PPTX
オレ流のOpenJDKの開発環境(JJUG CCC 2019 Fall講演資料)
9/14にリリースされたばかりの新LTS版Java 17、ここ3年間のJavaの変化を知ろう!(Open Source Conference 2021 O...
[아이펀팩토리] 2018 데브데이 서버위더스 _04 리눅스 게임 서버 성능 분석
[UE4]自動テストでもっと楽したい!
 
Wiresharkの解析プラグインを作る ssmjp 201409
PostgreSQLのgitレポジトリから見える2021年の開発状況(第30回PostgreSQLアンカンファレンス@オンライン 発表資料)
java.lang.OutOfMemoryError #渋谷java
CI/CDツール比較してみた
MHA for MySQLとDeNAのオープンソースの話
Akkaで分散システム入門
Ganglia のUIにGrafanaを追加する話
やってはいけない空振りDelete
Effective Modern C++ 勉強会 Item 22
やはりお前らのMVCは間違っている
2025年現在のNewSQL (最強DB講義 #36 発表資料)
UniRx完全に理解した
世界最強のソフトウェアアーキテクト
ネットワーク ゲームにおけるTCPとUDPの使い分け
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
企業システムにアジャイルは必要か
オレ流のOpenJDKの開発環境(JJUG CCC 2019 Fall講演資料)

More from 泰 増田

PDF
PlaySQLAlchemyORM2017.key
PDF
PlaySQLAlchemy: SQLAlchemy入門
PDF
SQLAlchemy Primer
PPTX
Taming robotframework
PPT
Open bio2004 biopython
PPT
Python languageupdate (2004)
PPTX
Robot Framework (のSelenium2Libraryのお話)
PDF
Django boodoo
PlaySQLAlchemyORM2017.key
PlaySQLAlchemy: SQLAlchemy入門
SQLAlchemy Primer
Taming robotframework
Open bio2004 biopython
Python languageupdate (2004)
Robot Framework (のSelenium2Libraryのお話)
Django boodoo

wxPython入門(大阪Pythonユーザの集まり2014/03)


[8]ページ先頭

©2009-2025 Movatter.jp