計算機アプリを作る
この例では、eSEATのGUI作成機能を用いて、簡単な計算機をSEATMLで作成したいと思います。最終的に、下図のようなGUIをもつ単純な計算機の実現を目指します。
ひな形の作成
まずは、SEATMLのひな形を作成します。このひな形は、SimpleIOの時と同じものです。
下記のような内容をもつファイルです。
<?xml version="1.0" encoding="UTF-8"?> <seatml> <general name="calc"> </general> <state name="main_state"> </state> </seatml>
このSEATMLファイルでeSEATは起動可能ですが、全く何のポートも持っていないし、コアロジックも持たないRTCになります。
GUIのパーツを追加する
次にGUIのボタンと計算結果を表示するための一行入力を追加します。eSEATでは、GUIのパーツはGRID形式のパッキングマージャーを使っていますので、目標とするGUIは、4行7列の表の中にGUIアイテムを配置すると考えればよいと思います。
HTMLのTABLEで書くと
<table> <tr><td bgcolor="red" colspan="4" align="center"><font color="#ffffff">SimpleCalc</font></td></tr> <tr><td colspan="4"><input ></td></tr> <tr><td>C</td><td></td><td></td><td>+</td></tr> <tr><td>1</td><td>2</td><td>3</td><td>-</td></tr> <tr><td>4</td><td>5</td><td>6</td><td>*</td></tr> <tr><td>7</td><td>8</td><td>9</td><td>/</td></tr> <tr><td></td><td>0</td><td>.</td><td>=</td></tr> </table>
SimpleCalc | |||
C | + | ||
1 | 2 | 3 | - |
4 | 5 | 6 | * |
7 | 8 | 9 | / |
0 | . | = |
という感じになると思います。
このGUIをSEATMLで実装していきましょう。ここで注意していただきたいのは、SEATMLのGUIアイテムは基本的に左から右へ一列に配置されていくということです。そのため表形式のようなGUIを作成する場合には、brk要素やspace要素を組み合わせて書くことになります。
以上を念頭においてSEATMLを書くと下のようになります。
<label text="SimpeCalc" bg_color="#ff0000" color="#ffffff" colspan="4"> <brk /> <input id="in1" width="50" colspan="4"></input> <brk /> <button label="C" ></button> <button label="" ></button> <button label="" ></button> <button label="+" ></button> <brk /> <button label="1" ></button> <button label="2" ></button> <button label="3" ></button> <button label="-" ></button> <brk /> <button label="4" ></button> <button label="5" ></button> <button label="6" ></button> <button label="*" ></button> <brk /> <button label="7" ></button> <button label="8" ></button> <button label="9" ></button> <button label="/" ></button> <brk /> <button label="" ></button> <button label="0" ></button> <button label="." ></button> <button label="=" ></button>
このSEATMLでラベルなしのボタンは何も割り当てたくありませんので、label要素やspace要素に置き換えても良いと思います。
コアロジックを実装する
GUIができたところで、各GUIアイテムに対してイベントハンドラを実装していきます。アルゴリズムを簡単にするために、次のように考えてみましょう。
- 数字および演算子、小数点を押下した場合には、一行入力アイテムにその表記の文字を追加し、式を作っていく。
- "="ボタンが押下された場合には、現在表示されている式をeval関数で評価し、その結果に置き返る。
- "C"ボタンが押下された場合には、現在表示されている式を消す。
以上の機能を実装すれば、非常に簡単な計算機ができると思います。
これらの機能は、script要素を使ってコアロジックをPythonプログラムとして記述してくとよいと思います。ここで中止していただきたいのは、ユーザ関数は、general要素の中であらかじめ定義しておいた方がよいということです。なぜなら、general要素内のscript要素に記載されているコードは、起動時のみ評価されるからです。
下に上記のアルゴリズムを追加したSEATMLスクリプトを書いておきます。
2014/07/24 のアップデートで、seatml内のlabel, button, input, textの要素の指定は、「stateの識別子+":"+要素の識別子」に仕様変更しました
<?xml version="1.0" encoding="UTF-8"?> <seatml> <general name="calc"> <script> def pushKey(n, id): tmp=seat.getEntry("main_mode:"+id) if tmp == "0": seat.setEntry("main_mode:"+id, n) else: seat.setEntry("main_mode:"+id, tmp+n) </script> </general> <state name="main_mode"> <label text="SimpleCalc" bg_color="#ff0000" color="#ffffff" colspan="4" /> <brk /> <input id="in1" width="50" colspan="4">0</input><brk /> <button label="C" ><script>seat.setEntry("main_mode:in1","0")</script></button> <space length="2" /> <button label="+" ><script>pushKey("+", "in1")</script></button> <brk /> <button label="1" ><script>pushKey("1", "in1")</script></button> <button label="2" ><script>pushKey("2", "in1")</script></button> <button label="3" ><script>pushKey("3", "in1")</script></button> <button label="-" ><script>pushKey("-", "in1")</script></button> <brk /> <button label="4" ><script>pushKey("4", "in1")</script></button> <button label="5" ><script>pushKey("5", "in1")</script></button> <button label="6" ><script>pushKey("6", "in1")</script></button> <button label="*" ><script>pushKey("*", "in1")</script></button> <brk /> <button label="7" ><script>pushKey("7", "in1")</script></button> <button label="8" ><script>pushKey("8", "in1")</script></button> <button label="9" ><script>pushKey("9", "in1")</script></button> <button label="/" ><script>pushKey("/", "in1")</script></button> <brk /> <button label="" ></button> <button label="0" ><script>pushKey("0", "in1")</script></button> <button label="." ><script>pushKey(".", "in1")</script></button> <button label="=" > <script> try: expr=seat.getEntry(""main_mode:in1") ans=eval(expr) seat.setEntry(""main_mode:in1", ans) except: seat.setEntry(""main_mode:in1", "ERROR") </script> </button> </state> </seatml>
上記ができた後は、通常の電卓と同じように動くように改変してみてください。
計算機に関して、電卓のような動きをするものを2つのRTCを使って実装した例を作成しました。こちらを参照してください。
資料