0
2

More than 3 years have passed since last update.

Pythonista3のui.View.flexを使い倒す

Last updated at Posted at 2019-11-25

pythonista3のいまいち挙動を理解しきれなかった、ui.Viewのflex属性を色々試して理解を深めてみた。

最初に動きを試す

画面の四隅をドラッグすると大きさが変わるので、それぞれの動きの変化を視覚的に確認できる。

ui_flex01.py
import ui

class ResizableView(ui.View):

    STA_IDLE = 1  # 待機
    STA_MOVE_LT = 2  # 左上移動
    STA_MOVE_LB = 3  # 左下移動
    STA_MOVE_RT = 4  # 右上移動
    STA_MOVE_RB = 5
    STA_MOVE = 6


    def __init__(self):
        self.m_state = self.STA_IDLE

    def touch_began(self, touch):
        l = self.width * 0.1
        r = self.width * 0.9
        t = self.height * 0.1
        b = self.height * 0.9

        self.m_state = self.STA_IDLE

        if touch.location.x < l:
            if touch.location.y < t:
                self.m_state = self.STA_MOVE_LT
            if touch.location.y >= b:
                self.m_state = self.STA_MOVE_LB
        if touch.location.x >= r:
            if touch.location.y < t:
                self.m_state = self.STA_MOVE_RT
            if touch.location.y >= b:
                self.m_state = self.STA_MOVE_RB

        if self.m_state == self.STA_IDLE:
            self.m_state = self.STA_MOVE


    def touch_moved(self, touch):
        s = self.m_state
        vx = touch.location.x - touch.prev_location.x
        vy = touch.location.y - touch.prev_location.y

        if s == self.STA_IDLE:
            pass
        elif s == self.STA_MOVE_LT:
            self.x += vx
            self.y += vy
            self.width -= vx
            self.height -= vy
        elif s == self.STA_MOVE_RT:
            self.width += vx
            self.y += vy
            self.height -= vy
        elif s == self.STA_MOVE_LB:
            self.x += vx
            self.width -= vx
            self.height += vy
        elif s == self.STA_MOVE_RB:
            self.width += vx
            self.height += vy
        elif s == self.STA_MOVE:
            self.x += vx
            self.y += vy

    def touch_ended(self, touch):
        self.m_state = self.STA_IDLE

datas = (
    ('RB',0,0,30,30),
    ('LB',270,0,30,30),
    ('RT',0,370,30,30),
    ('LT',270,370,30,30),
    ('W',50,40,200,50),
    ('H',50,100,50,250),
    ('R',100,100,100,50),
    ('L',100,100,100,50),
    ('LR',100,100,100,50),
    ('RW',100,160,100,50),
    ('LW',100,220,100,50),
    ('RTW',110,300,50,50),
    ('LTH',200,300,50,50),
    ('',150,220,100,50),
    ('RW',100,280,30,50),
    ('RW',150,280,30,50),
    ('RW',200,280,30,50),
    ('RLW',100,340,30,50),
    ('RLW',150,340,30,50),
    ('RLW',200,340,30,50),

)

p = ui.View()
v = ResizableView()
v.width = 300
v.height = 400
v.background_color = '#808080'
p.add_subview(v)

for d in datas:
    l = ui.Label()
    l.border_width = 2
    l.alignment = ui.ALIGN_CENTER
    l.text = l.flex = d[0]
    l.frame = (d[1],d[2],d[3],d[4])
    v.add_subview(l)


p.present('fullscreen')
v.width = p.width
v.height = p.height

8874C09C-4259-42BE-8D37-BF99880219CE.png

flex の機能

flex を設定すると、親 View のサイズ変更に合わせて、自分の位置 (x,y) や大きさ (width,height) が自動的に変わるようにする事が可能です。

指定可能なのは R, B, L, T, W, H の文字で、複数組み合わせて指定する事も可能です。

デフォルト ‘’、’R’、’RB’

flex に空文字を指定すると、x,y,width,height は親 View のサイズ変更の影響を受けません。
これは ‘R’ や ‘RB’ を指定した時と同じ挙動です。

右端に吸着 ‘L’

flex に ‘L’ を指定すると flexible left margine。直訳すると左の余白が柔軟に変化する。意訳すると親 View の右端に吸着します。

これは、親 View の大きさが変わった時にこの View が右寄りを維持する事になります。

それぞれの端に吸着 ‘R’、’B’、’T’

‘L’ 同様に

‘R’ は親 View の左端に吸着
‘B’ は親 View の上端に吸着。(デフォルトの挙動)
‘T’ は親 View の下端に吸着

となります。

個人的には LRBT の意味が真逆のイメージなのですが、そう思うのは私だけでしょうか?

大きさを追従 ‘W’、’H’

‘W’ を指定すると親の大きさ変更に合わせて幅が変わります。
‘H’ を指定すると親の大きさ変更に合わせて高さが変わります。

親View上の相対位置を維持 ‘RL’、’BT’

親の大きさが変わっても、複数のボタンを等間隔に配置したい。という時に使用します。
たいていは大きさも合わせて変化させる必要があるので、W H も加えて、’RLW’、’BTH’ を使う事が多いと思います。

0
2
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
2