`class MyWidget(Widget):`
ルート ウィジェットは、レイアウトMyWidget
の 1 つからではなく から継承するためWidget
、その子のサイズを制御しません。
ルート ウィジェットは、ウィンドウのスペース全体を占有します。MyWidget
次のようなキャンバスに Rectangle を追加することで、これをテストできます::
with self.canvas.before:
Color(1,0,0,1)
Rectangle(pos=self.pos, size=self.size)
canvas、canvas.before、および canvas.afterに慣れる必要があります。これらは基本的に命令のグループであり、before グループはウィジェットのキャンバス命令の前に描画され、after グループは after に描画されます。
ただし、Kivy で異なる重要な点の 1 つは、ウィジェットのサイズ変更/レイアウトが次のフレームまで遅延されることです。そのため、上記のスニペットを次のようにコードに追加すると::
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import *
class MyWidget(Widget):
def __init__(self, **kwargs):
# I'd make sure to pass of kwargs through to the super
# as there are widgets's that process their initial
# arguments through.
super(MyWidget, self).__init__(**kwargs)
grid_layout = GridLayout(cols=3)
grid_layout.add_widget(Button(text='A'))
grid_layout.add_widget(Button(text='B'))
grid_layout.add_widget(Label(text='text'))
grid_layout.add_widget(Label(text='other'))
grid_layout.add_widget(Button(text='text'))
self.add_widget(grid_layout)
with self.canvas.before:
Color(1,0,0,1)
Rectangle(pos=self.pos, size=self.size)
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
これは、ウィジェットの初期位置とサイズでのみ赤い四角形を表示します。その時点では、デフォルトの位置とサイズはそれぞれ (0, 0) と (100, 100) です。
赤い四角形をウィジェットのサイズに合わせるには、次のようにサイズをウィジェットのサイズにバインドする必要があります::
...
grid_layout.add_widget(Button(text='text'))
self.add_widget(grid_layout)
with self.canvas.before:
Color(1,0,0,1)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.bind(size=self.update_rect)
def update_rect(self, instance, value):
self.rect.pos = self.pos
self.rect.size = self.size
class MyApp(App):
def build(self):
...
上記のコードの出力が示すように、ウィジェットはウィンドウ全体のサイズを占めています。ただし、これで問題は解決せず、子レイアウトは元の位置と元のサイズのままです。これは、上記のように、ウィジェットが子のサイズを制御しないためです。
rect を更新するようにウィジェットの子/子のサイズと位置を更新するか (複数の子があるとすぐに複雑になります)、レイアウトの 1 つをルート ウィジェットとして使用します。
これは、次のように kv で行うこともできます::
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
Builder.load_string('''
# this is the rule for MyWidget that defines
# what MyWidget looks like i.e.drawing
# instructions and widgets etc
<MyWidget>:
canvas.before:
Color:
rgba: 1, 0, 0, 1
Rectangle:
# this implicitly binds the size of the
# rect to the size of the widget
size: self.size
# self here still refers to the widget as Rectangle is only a
# graphics instruction and not a widget
pos: self.pos
GridLayout:
cols: 3
# root here refers to the `MyWidget`, bind the size of the
# GridLayout to the size of your root widget
size: root.size
Button:
text: 'A'
Button:
text: 'B'
Label:
text: 'text'
Label:
text: 'other'
Button:
text: 'text'
''')
class MyWidget(Widget):
pass
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
上記の例では、子のサイズをその親ウィジェットのサイズにバインドします。レイアウトをルート ウィジェットとして使用することを引き続きお勧めします。レイアウトをネストすることをためらわないでください。