0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ひとりアドベント(グラフ電卓,関数電卓,Python)Advent Calendar 2024

Day 19

QPython で GUI プログラミング1(サンプルスクリプトを動かす)

Posted at

QPython には QSL4A が搭載されている

QPython には GUI で動く環境がいくつか用意されており、 SL4A をQPython用に改造した QSL4A (プロジェクト化したものが QSL4AApp)なるものがその一つ。
以下の記事だと QuietScripts と表記されているものがそれに該当すると思われるが、初期生成されるサンプルスクリプトは異なる。

この QSL4A や QSL4AApp、検索してもほとんど情報が出てこない。
SL4A などのページも参考に、 QPython での GUI プログラミングを試してみたい。

サンプルスクリプト

Editor で新規作成ボタン(+)を押すと、 File(コンソール用)の他に、 ConsoleApp、WebApp、QSL4AApp、PygameApp を選ぶことができる。
QSL4AApp_test_1.png
QSL4AApp を選びプロジェクト名を付けると、 project3 フォルダの中にプロジェクト名のフォルダが生成され、サンプルスクリプトとなる main.py が開く。
QSL4Aapp_test_2.png
QSL4Aapp_test_3.png
QSL4Aapp_test_4.png

このサンプルスクリプトを実行すると、 Hello, QPython のメッセージと、下部に LOADEXIT の2つのボタンが出てくる。
QSL4Aapp_test_5.png

LOAD ボタンを押すと、上部にロゴ画像が読み込まれる。
QSL4Aapp_test_6.png

EXIT ボタンを押すと終了してエディタ画面に戻る。

サンプルスクリプトを各部に分けて見てみる

1. 前処理部

#qpy:quiet
#-*-coding:utf8;-*-
"""
This is a sample project which use SL4A UI Framework,
There is another Sample project: https://github.com/qpython-android/qpy-calcount
"""
import qpy
import androidhelper
try:
    import urllib.request as ur
except:
    import urllib as ur
from qsl4ahelper.fullscreenwrapper2 import *

droid = androidhelper.Android()

冒頭でコンソールを出さない設定 #qpy:quiet 、モジュールのインポート等が行われている。

2. XML で画面レイアウト

class MainScreen(Layout):
    def __init__(self):
        super(MainScreen,self).__init__(str("""<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:background="#ff0E4200"
	android:orientation="vertical"
	xmlns:android="http://schemas.android.com/apk/res/android">
	<ImageView
		android:id="@+id/logo"
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:layout_weight="10"
	/>
	<LinearLayout
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:orientation="horizontal"
		android:layout_weight="20">

		<TextView
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:textSize="8dp"
			android:text="Hello, QPython"
			android:textColor="#ffffffff"
			android:layout_weight="1"
			android:gravity="center"
		/>
    </LinearLayout>

	<ListView
		android:id="@+id/data_list"
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:layout_weight="55"/>

	<LinearLayout
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:orientation="horizontal"
		android:layout_weight="8">
		<Button
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:text="Load"
			android:id="@+id/but_load"
			android:textSize="8dp"
			android:background="#ffEFC802"
			android:textColor="#ffffffff"
			android:layout_weight="1"
			android:gravity="center"/>
		<Button
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:text="Exit"
			android:id="@+id/but_exit"
			android:textSize="8dp"
			android:background="#ff06AF00"
			android:textColor="#ffffffff"
			android:layout_weight="1"
			android:gravity="center"/>
	</LinearLayout>
</LinearLayout>
"""),"SL4AApp")

どうやら @+id/ のついた部分は下記の関数等で差し替えたり機能を持たせたりできるようだ。

3. 関数定義

    def on_show(self):
        self.views.but_exit.add_event(click_EventHandler(self.views.but_exit, self.exit))
        self.views.but_load.add_event(click_EventHandler(self.views.but_load, self.load))

        pass

    def on_close(self):
        pass

    def load(self, view, dummy):
        droid = FullScreenWrapper2App.get_android_instance()
        droid.makeToast("Load")

        saved_logo = qpy.tmp+"/qpy.logo"
        ur.urlretrieve("https://www.qpython.org/static/img_logo.png", saved_logo)
        self.views.logo.src = "file://"+saved_logo

    def exit(self, view, dummy):
        droid = FullScreenWrapper2App.get_android_instance()
        droid.makeToast("Exit")
        FullScreenWrapper2App.close_layout()

イベントの定義と、イベント発生時に行う機能の定義。

4. メイン

if __name__ == '__main__':
    FullScreenWrapper2App.initialize(droid)
    FullScreenWrapper2App.show_layout(MainScreen())
    FullScreenWrapper2App.eventloop()

初期化して、XML をもとにレイアウトして、イベント発生を待つ…ということのようだ。

Load ボタンを押すと真ん中の文字が表示されるようにしよう

このサンプルスクリプトでトースト通知と画像の表示の方法はわかったが、文字の差し替え・表示についてはわからない。
サンプルスクリプトが紹介している qpy-calcount のソースを見てみると、どうやら

self.views.((ID名)).text = "((表示させたい文字))"

とすればよいようだ。

XML 部分、 Load 部分を以下のように修正してみる(一部抜粋、このほか datetime モジュールの呼び出しや文字サイズの適宜修正をした)。

	<LinearLayout
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:orientation="horizontal"
		android:layout_weight="10">

		<TextView
			android:id="@+id/time"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:textSize="20dp"
			android:text=""
			android:textColor="#ffffffff"
			android:layout_weight="1"
			android:gravity="right"
		/>
	</LinearLayout>
	<LinearLayout
		android:layout_width="fill_parent"
		android:layout_height="0px"
		android:orientation="horizontal"
		android:layout_weight="20">

		<TextView
			android:id="@+id/title"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"
			android:textSize="30dp"
			android:text=""
			android:textColor="#ffffffff"
			android:layout_weight="1"
			android:gravity="center"
		/>
	</LinearLayout>
    def load(self, view, dummy):
        curdatetime = datetime.datetime.now()
        self.views.time.text = curdatetime.time().isoformat()[0:8]
        self.views.title.text = "Load button pressed!"

最初は text が空なので表示されず、
QSL4Aapp_test_7.png

Load ボタンを押すと時刻とメッセージが表示される。
QSL4Aapp_test_8.png

うまくいった。今回はここまで。

次回はこのスクリプトを発展させ YouTube チャンネル登録者数カウンターにする予定。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?