Created
July 4, 2022 14:22
-
-
Save gottadiveintopython/f8a620a4ced20dd4c6d450d09f696fc5 to your computer and use it in GitHub Desktop.
getting familiar with size_hint_min #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
CPython 3.8.12 | |
pip install kivy[base]==2.1.0 | |
pip install "asynckivy>=0.5,<0.6" | |
pip install git+https://github.com/gottadiveintopython/kivyx.uix.magnet#egg=kivyx.uix.magnet | |
''' | |
from kivy.config import Config | |
Config.set('graphics', 'width', 1280) | |
Config.set('graphics', 'height', 720) | |
# Config.set('graphics', 'maxfps', 30) | |
# Config.set('graphics', 'fullscreen', 1) | |
from kivy.app import App | |
from kivy.lang import Builder | |
from kivyx.uix.magnet import KXMagnet | |
KV_CODE = r''' | |
#:import sm kivy.uix.screenmanager | |
#:import KivyLexer kivy.extras.highlight.KivyLexer | |
BoxLayout: | |
orientation: 'vertical' | |
spacing: '20dp' | |
padding: '20dp' | |
BoxLayout: | |
id: btn_container | |
spacing: '20dp' | |
pos_hint: {'x': 0, 'y': 0, } | |
ScreenManager: | |
id: scrmgr | |
transition: sm.NoTransition() | |
canvas.before: | |
Color: | |
rgb: .5, .5, .5 | |
Line: | |
points: (self.x, self.top, self.right, self.top, ) | |
width: 2. | |
Screen: | |
name: 'desc' | |
Label: | |
id: desc_label | |
padding: dp(10), dp(10) | |
font_size: '30sp' | |
text_size: self.width, None | |
halign: 'center' | |
Screen: | |
name: 'code' | |
KXMagnet: | |
do_anim: False | |
CodeInput: | |
id: code | |
font_size: '24sp' | |
lexer: KivyLexer() | |
''' | |
class SampleApp(App): | |
def build(self): | |
return Builder.load_string(KV_CODE) | |
def on_start(self): | |
import asynckivy | |
asynckivy.start(self.main()) | |
async def main(self): | |
from textwrap import dedent | |
from kivy.metrics import dp | |
from kivy.factory import Factory as F | |
import asynckivy as ak | |
ft = ak.fade_transition | |
ids = self.root.ids | |
btn_container = ids.btn_container | |
desc_label = ids.desc_label | |
await ak.n_frames(4) | |
async with ft(desc_label): | |
desc_label.text = "Let's say you want to put buttons in a row," | |
await ak.sleep(1) | |
async with ft(btn_container): | |
for text in 'ABC': | |
btn = F.Button(text=text, font_size='30sp') | |
magnet = F.KXMagnet(do_anim=False) | |
magnet.add_widget(btn) | |
btn_container.add_widget(magnet) | |
await ak.sleep(1) | |
async with ft(desc_label): | |
desc_label.text = " and the text length of the buttons vary." | |
await ak.sleep(2) | |
async with ft(btn_container): | |
magnets = btn_container.children[::-1] | |
texts = ('A', 'python-for-android & buildozer & plyer & kivy-ios', 'C') | |
for magnet, text in zip(magnets, texts): | |
magnet.do_anim = True | |
magnet.children[0].text = text | |
await ak.sleep(2) | |
async with ft(desc_label): | |
desc_label.text = "In this situation, lots of people seem to like disabling size_hint, like this." | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'code' | |
ids.code.text = dedent(''' | |
<MyButton@Button>: | |
size_hint: None, None | |
width: self.texture_size[0] + dp(10) | |
height: self.texture_size[1] + dp(10) | |
BoxLayout: | |
id: button_container | |
size_hint_y: None | |
height: self.minimum_height | |
''') | |
await ak.sleep(1) | |
ids.code.parent.do_anim = True | |
for magnet in magnets: | |
magnet.size_hint = (None, None, ) | |
ts = magnet.children[0].texture_size | |
magnet.width = ts[0] + dp(10) | |
magnet.height = ts[1] + dp(10) | |
btn_container.size_hint_y = None | |
bind_uid = btn_container.fbind('minimum_height', btn_container.setter("height")) | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'desc' | |
desc_label.text = 'This works, but ends up leaving weird space on the right hand side.' | |
await ak.sleep(2) | |
filler = F.Widget(opacity=0) | |
btn_container.add_widget(filler) | |
await ak.one_frame() | |
with filler.canvas: | |
F.Color(0, .5, 0, 1) | |
F.Rectangle(pos=filler.pos, size=filler.size) | |
for __ in range(4): | |
await ak.animate(filler, opacity=1, d=.2) | |
await ak.animate(filler, opacity=0, d=.2) | |
await ak.animate(filler, opacity=1, d=.2) | |
await ak.sleep(2) | |
async with ft(self.root): | |
btn_container.remove_widget(filler) | |
desc_label.text = '''And what if the texture height of the buttons also vary ?''' | |
await ak.sleep(3) | |
magnets[2].children[0].text = 'multi\nline' | |
await ak.sleep(-1) | |
ts = magnets[2].children[0].texture_size | |
magnets[2].size = (ts[0] + dp(10), ts[1] + dp(10)) | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
desc_label.text = '''If you want the all buttons to be the same height, your code would become like this.''' | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'code' | |
ids.code.text = dedent(''' | |
<MyButton@Button>: | |
size_hint_x: None | |
width: self.texture_size[0] + dp(10) | |
BoxLayout: | |
id: button_container | |
size_hint_y: None | |
height: max(c.texture_size[1] for c in self.children) + dp(10) | |
''') | |
await ak.sleep(2) | |
btn_container.unbind_uid('minimum_height', bind_uid) | |
def calc_height(boxlayout, children): | |
boxlayout.height = max(c.children[0].texture_size[1] for c in children) + dp(10) | |
bind_uid = btn_container.fbind('children', calc_height) | |
calc_height(btn_container, btn_container.children) | |
del calc_height | |
for magnet in magnets: | |
magnet.size_hint_y = 1 | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'desc' | |
desc_label.text = 'As you can see, you cannot rely on minimum_height in this method, which is annoying.' | |
await ak.sleep(4) | |
async with ft(ids.scrmgr): | |
desc_label.font_size = '60sp' | |
desc_label.text = 'size_hint_min solves all these problems.' | |
await ak.sleep(2) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'code' | |
ids.code.text = dedent(''' | |
<MyButton@Button>: | |
size_hin_min_x: self.texture_size[0] + dp(10) | |
size_hin_min_y: self.texture_size[1] + dp(10) | |
BoxLayout: | |
id: button_container | |
size_hint_y: None | |
height: self.minimum_height | |
''') | |
await ak.sleep(2) | |
btn_container.unbind_uid('children', bind_uid) | |
btn_container.bind(minimum_height=btn_container.setter("height")) | |
for magnet in magnets: | |
magnet.size_hint_x = 1 | |
ts = magnet.children[0].texture_size | |
magnet.size_hint_min = (ts[0] + dp(10), ts[1] + dp(10)) | |
await ak.sleep(3) | |
async with ft(ids.scrmgr): | |
ids.scrmgr.current = 'desc' | |
desc_label.text = 'size_hint_min makes your code clean.' | |
if __name__ == '__main__': | |
SampleApp().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment