このシリーズももう7回目になるんですね.空き時間を見つけてぼちぼち書いているのですが,ブログに書くのはなかなか進まないです.はい,言い訳.
回りくどい説明,正確でない日本語など,つたない文章力なのは承知の上なのですが,それでも見てくださっている方がいらっしゃるのは本当にありがたい限りです.ゆっくりとボチボチ進める形にはなりますが,どうかよろしくお願いします.
前置きはこれぐらいにして,「これから kivy の話をしよう」.今までの内容では,文字を表示するだけのLabel(ポストイットみたいなものでしたね),ただの Button ぐらいしかやっていませんですね.これぐらいの機能だとパソコンで開発する意味がよくわからなくなってきます...ということで,今回はパソコンやスマートフォンならではの機能を一つ扱います.
例えば,パソコンやスマートフォンのゲーム開発などを考えると,キーボード上だけで操作するゲームももちろん考えられますが,より高度で豊富な遊び方を追求するためには,マウスを移動しクリックする,もしくはスマートフォンのタップなどの操作を加えることが欠かせないのではないでしょうか.今回の投稿では kivy で,マウスのクリック,またはスマートフォンのタップした位置など,デバイスからの位置情報をゲットする方法を紹介します.デバイスとはいっても,この投稿を見ている方はほとんどデスクトップやラップトップで開発していらしてると思われるので,今回の投稿の範囲ではマウスクリックに限って書かせていただきます.
前回までのしばらくの投稿ではkvファイルのいじることで様々な機能を使ったりその機能の特徴を変化をさせていましたが,今回はkvファイルは用いません.
今回習う内容はこちらの動画になります.
マウスのクリックの位置:on_touch_down
とりあえず座標を取得する
では,さっそく...Kivy でマウスの位置を検出する際に用いる機能は,ボタンを作成する際に使った Widget クラスを用います.その時の投稿は次になります.
Kivy 超入門(4):ボタンを作成する,ウィジェットの作成
もうそんなの知っているよという方,忘れてたけど大体内容を思い出した方は,早速次のコードを書いてみましょう.
from kivy.app import App from kivy.uix.widget import Widget class KurikkuInput(Widget): def on_touch_down(self, touch): print(touch) class IntroKivy(App): def build(self): return KurikkuInput() if __name__ == "__main__": IntroKivy().run()
これの実行結果は次のようになります.筆者は統合開発環境としてPyCharmを用いています.左側がPyCharmで開発している画面で,右側が実行結果として出てきたウィンドウになります.新しいタブで開くなどをして拡大して確認していただきたいです.
実行結果として出てきた画面は真っ黒ですが,ここでその黒い画面上のどこでもいいのでクリックしてみましょう.そうすると,コンソール(筆者の場合,PyCharm の下に配置しているやつ.コマンドプロンプトでpythonを実行している人は,そのコマンドラインがコンソール)に次のようなメッセージが出てきます.
<MouseMotionEvent spos=(0.38125, 0.5233333333333333) pos=(305.0, 314.0)>
Python のコードについて新しく説明する部分は,ハイライトされている5行目の「on_touch_down」という機能ですね.上の例で,KurikkuInput という関数を新しく作成し,そのクラスはWidgetクラスを継承しています.そして,その中身にある「on_touch_down」はWidgetクラスの機能ですが,上のコードではこの「on_touch_down」をオーバーライドしています.オーバーライドがピンとこない方は,「もともと継承する前のクラスにある機能を,一部自分で書き換えてしまう」と解釈してもいいでしょう.オーバーライドについてもう少し知りたい方は,次の記事がわかりやすいかと思います.
メソッドのオーバーライド – Pythonで学ぶ 基礎からのプログラミング入門
さて,その「on_touch_down」の機能ですが,ボタンをクリックした,もしくはスマートフォンの画面をタップしたという操作に対応しています.アメフトとかラグビーでタッチダウンというのがありますが,ニュアンスはその通りです.画面上にマウスをクリックしてonするイメージです.引数にあるtouchには,クリックしたときの相対位置(spos)と絶対位置(pos)が格納されます.
値についてですが,相対位置はグラフの第一象限のイメージの通りで,一番左下が(0,0),一番右上が(1,1)となります.絶対位置は,一番左下を(0,0)としてそこから今いる位置の座標をピクセルの単位で返します.上のプログラムを実際動かしてみて,確かに自分がクリックした位置と対応しているかチェックしてみましょう.
相対座標だけを値としてゲットする
touch には相対位置と絶対位置の情報の二つを持っていましたが,実際扱う上で大事になってくるのは,それらを文字でprintすることでなく,きちんと数字として持ってくることです.例えば,相対座標の値だけを持ってきたいときは,次のようにすればよろしいです.
from kivy.app import App from kivy.uix.widget import Widget class KurikkuInput(Widget): def on_touch_down(self, touch): print(touch.spos) class IntroKivy(App): def build(self): return KurikkuInput() if __name__ == "__main__": IntroKivy().run()
これを実行して現れた画面の一部をクリックすると,コンソールには相対座標の値だけが表示されます.「touch.spos」にはtouchの相対座標がタプル型で格納されています.
お察しの通り,絶対座標を得たい際には「touch.spos」の部分を「touch.pos」に変更するだけでオッケーです.
より進んで on_touch_down を理解したい方は,公式ドキュメントにある Widget クラスの on_touch_down の項を参考にされればよろしいかと思います.
on_touch_down – Widget class – Kivy公式ドキュメント
ここまでを理解していただければ,他の場合についてもマウスの座標をゲットする方法についてはもうわかったも同然です.続けて「マウスを話した座標」と「マウスをドラックした軌跡」について簡単に説明させていただきます.
マウスを離した位置:touch_down_up
マウスを画面に下ろすのがonだったら,離すことはupになります(offじゃないです).基本的な使い方は同じなのですが,上の動画に従い,print文の中身を少し変形させてあります.
from kivy.app import App from kivy.uix.widget import Widget class KurikkuInput(Widget): def on_touch_up(self, touch): print("Released!",touch) class IntroKivy(App): def build(self): return KurikkuInput() if __name__ == "__main__": IntroKivy().run()
実行して現れた画面の上をゆっくりクリックしてみると「touch_down_up」の機能は明らかに理解していただけるかと思います.先ほどとの違いは,print文に変更を加えたため,クリックを離すと離した点の座標の前に”Released!”文字が表示されることです
ドラッグしている軌跡をトラック:touch_down_move
マウスのクリックを押したままドラッグしている間は,マウスカーソルを画面上に落として「動かしている」ので,move ということになります.
from kivy.app import App from kivy.uix.widget import Widget class KurikkuInput(Widget): def on_touch_move(self, touch): print(touch) class IntroKivy(App): def build(self): return KurikkuInput() if __name__ == "__main__": IntroKivy().run()
実行して現れた画面の上をクリックを押してドラッグしてみると,動くたびに膨大な量の座標がコンソールに図れることがわかります.move はあくまでもクリックを押しドラッグているところを示すので,ただ単に画面上でマウスを動かしても座標はゲットできないのに注意しましょう.
合わせ技:マウスを押している間の軌跡
先ほどの機能を順番通りに丸ごと合わせれば,左クリックを押している間のマウスの軌跡をたどることができそうですね.本当に単純な合わせ技です.
from kivy.app import App from kivy.uix.widget import Widget class KurikkuInput(Widget): def on_touch_down(self, touch): print(touch) def on_touch_move(self, touch): print(touch) def on_touch_up(self, touch): print("Released!",touch) class IntroKivy(App): def build(self): return KurikkuInput() if __name__ == "__main__": IntroKivy().run()
実行結果は上までの内容を読んでいただいたのであれば,「あぁー,マウスを押している間の軌跡がコンソールにprintされるだけかー」と納得していただけるのではないのでしょうか.
次回予告:お絵かきツール
不安を煽るわけではないですが,今回の投稿は「touch_down_on」さえ使い方が分かってしまえば,どうってことない内容でしたね.さて,次の学習内容は「今までの機能に少しだけ毛をはやすことで,いとも簡単にお絵かきツールが作れちゃうぞ」という内容です(全然少しの毛じゃない気もするんですけどね...).「お絵かきツールなんて必要になったらやればいいだけじゃん」とは思うのですが,動画を作っている方の Kivt チュートリアルシリーズでは今後よく出てくるので,今後に余計な混乱を招かないため次の投稿でフォローしておこうと思っています.次の動画の内容です.
この方,お絵かきツールがなぜかお気に入りのようですね.