Kivy Quiz (宣伝)

私がこれまでKivyを使ってきて時間を取られてしまった、思わぬKivyの振るまいをQuizの形式にしてみた。Quizは全て

- Kivy 1.10.1
- Python 3.7.1

で実行した場合を想定している。

# 第一問

次のcodeの実行結果はどれ？

```python3
from kivy.lang import Builder
from kivy.app import runTouchApp

root = Builder.load_string('''
Widget:
    canvas:
        PushMatrix:
        Translate:
            x: 100
        Rotate:
            angle: 45
        Rectangle:
            pos: -32, -32
            size: 64, 64
        PopMatrix:
''')

runTouchApp(root)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/fe2d3735-3f52-35c0-2eee-4dc008c24796.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/f27c992d-722d-1053-fd14-f6619696e343.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/3a7e7a90-99a2-e347-5ff4-cbad83b2e75c.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/25d77ddd-17c5-585a-9146-4a1e1ccdfe62.png"/>

<details><summary>答え</summary>上から二番目
回転(Rotate),移動(Translate),拡大縮小(Scale)などの命令をcanvasに書いた時、書いた順とは逆に適用される。問題では`Translate`の後に`Rotate`を書いているので、45度回転した後に右に100移動する。
</details>

# 第二問

次のcodeの実行結果はどれ？

```python3
from kivy.lang import Builder
from kivy.app import runTouchApp

root = Builder.load_string('''
BoxLayout:
    Widget:
    RelativeLayout:
        canvas.before:
            Color:
                rgb: 1, 0, 0
            Rectangle:
                pos: 0, self.height / 3 * 2
                size: self.width, self.height / 3
        canvas:
            Color:
                rgb: 0, 1, 0
            Rectangle:
                pos: 0, self.height / 3
                size: self.width, self.height / 3
        canvas.after:
            Color:
                rgb: 0, 0, 1
            Rectangle:
                pos: 0, 0
                size: self.width, self.height / 3
''')

runTouchApp(root)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/1f5fbbdd-e547-2470-c893-55be2d5dee77.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/e33540ea-264a-18b1-dc8f-7ab8a8203116.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/0d7fa49c-9982-a9d5-f372-0c2c802db1aa.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/01f06c1e-db74-feef-9d03-422c4186c153.png"/>

<details><summary>答え</summary>一番上
`canvas.after`は自身が属する`RelativeLayout`の座標変換の影響を受けない。
</details>

# 第三問

次のcodeを実行した時の標準出力は？

```python3
from kivy.lang import Builder
from kivy.app import runTouchApp

root = Builder.load_string('''
ScreenManager:
    Screen:
        name: 'A'
        on_pre_enter: print('A')
    Screen:
        name: 'B'
        on_pre_enter: print('B')
    Screen:
        name: 'C'
        on_pre_enter: print('C')
''')

runTouchApp(root)
```

<details><summary>答え</summary>ABCのどれも表示されない</details>

# 第四問

次のcodeの実行結果はどれ？

```python3
from kivy.factory import Factory
from kivy.lang import Builder
from kivy.app import runTouchApp

Builder.load_string('''
<MyBoxLayout>:
    Label:
        text: 'Label'
''')

class MyBoxLayout(Factory.BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.add_widget(Factory.Button(text='Button'))

root = Factory.BoxLayout(orientation='vertical')
root.add_widget(MyBoxLayout())
root.add_widget(Builder.load_string('''
RelativeLayout:
    MyBoxLayout:
'''))

runTouchApp(root)
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/26c79e53-50fa-71e2-8b66-f204deeedb1a.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/92c3f93c-c044-4006-4245-56d1e5b298db.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/73e2b2ff-148e-a9bc-eae0-4fe42c2a698d.png"/>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/2225fbb8-9148-9237-eae2-4e924f906834.png"/> 

<details><summary>答え</summary>上からニ番目</details>

# 第五問

次のcodeの実行結果はどれ？

```python3
from functools import partial
from kivy.uix.button import Button

class Hoge:
    def __init__(self, value):
        self.value = value
    def callback(self, *args):
        print(self.value, end='')

hoge = Hoge('A')
button = Button()
button.bind(on_press=hoge.callback)
button.bind(on_press=Hoge('B').callback)
button.bind(on_press=partial(Hoge('C').callback))
button.bind(on_press=partial(Hoge.callback, Hoge('D')))
button.bind(on_press=lambda *args: print('E', end=''))
button.dispatch('on_press')
```

```
EDCBA
```

```
A
```

```
EDCA
```

```
ECA
```

<details><summary>答え</summary>上から三番目。理由は[この記事](https://qiita.com/gotta_dive_into_python/items/67059f0451ddb163d92d)を。</details>

# 宣伝

第三問と第四問は拙著「[KivyにKivyったけ#1](https://www.amazon.co.jp/dp/B07KMN9NBR)」にて何故そうなるのか書いています。良かったら買ってやってください。