On Aug 7, 2021, at 5:53 PM, Robert <planckp...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/21ef19d6-3b52-4958-949e-9404c261b57fn%40googlegroups.com.
<lay.py>
Robert,
I have laid this out the way I would make a custom widget for myself. The file can be imported into other files. The test code is at the bottom, so it runs as a standalone file.
I left in some code that changes the button text (portrait, landscape), you can remove those lines.
Let me know if this is what you are looking for.
-Elliot
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import DictProperty, NumericProperty, StringProperty
from kivy.uix.relativelayout import RelativeLayout
Builder.load_string("""
<AspectButton>:
Button:
id: button
size_hint: None, None
pos_hint: root.pos_hint
text: root.text
""")
class AspectButton(RelativeLayout):
aspect_ratio = NumericProperty(3/4)
scale = NumericProperty(.7) # size relative to parent
pos_hint = DictProperty({'center_x': 0.5, 'center_y': 0.5})
text = StringProperty()
def on_kv_post(self, base_widget):
self.bind(size=self._resize)
def _resize(self, _, size):
width, height = size
b = self.ids.button
if width < height:
self.text = 'portrait' # just for testing
b.height = height * self.scale
b.width = b.height * self.aspect_ratio
if b.width > self.scale * width: # max width, now constrain by width
b.width = width * self.scale
b.height = b.width / self.aspect_ratio
else:
self.text = 'landscape' # just for testing
b.width = width * self.scale
b.height = b.width * self.aspect_ratio
if b.height > height * self.scale: # max height, constrain by height
b.height = height * self.scale
b.width = b.height / self.aspect_ratio
if __name__ == '__main__':
from textwrap import dedent
kv_test = dedent("""
BoxLayout:
AspectButton:
scale: .9
BoxLayout:
orientation: 'vertical'
Label:
text: 'Top'
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Left'
AspectButton:
scale: .7
Label:
text: 'Right'
Label:
text: 'Bottom'
AspectButton:
scale: .5
""")
class AspectApp(App):
def build(self):
return Builder.load_string(kv_test)
AspectApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/8b985331-fae0-41aa-adab-6889ad570f39n%40googlegroups.com.
Scale sets the size relative to the parent, I had not really considered a scale > 1 use case.
My first implementation I based on Window.size but thought that was too limiting. There are other shortcomings when combining this implementation into other layouts. That is why I moved to the relativelayout.
Here is my first implementation for your reference and amusement. This might work fine for limited use cases.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.properties import NumericProperty
from kivy.core.window import Window
kv = """
<AspectButton>:
size_hint: None, None
FloatLayout:
AspectButton:
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
scale: .9
"""
class AspectButton(Button):
aspect_ratio = NumericProperty(3/4)
scale = NumericProperty(.7) # size relative to window
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(on_resize=self.window_resize)
def on_kv_post(self, base_widget):
self.window_resize(Window, Window.width, Window.height)
def window_resize(self, window, width, height):
if width < height:
self.text = 'portrait' # just for testing
self.height = height * self.scale
self.width = self.height * self.aspect_ratio
if self.width > self.scale * width: # max width, now constrain by width
self.width = width * self.scale
self.height = self.width / self.aspect_ratio
else:
self.text = 'landscape' # just for testing
self.width = width * self.scale
self.height = self.width * self.aspect_ratio
if self.height > height * self.scale: # max height, constrain by height
self.height = height * self.scale
self.width = self.height / self.aspect_ratio
class AspectApp(App):
def build(self):
return Builder.load_string(kv)
AspectApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/a9763295-ba05-4ec7-84a5-f64c30f5917cn%40googlegroups.com.
Anything for a co-worker 😊
Enjoy!
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/1cda12bc-180c-4c38-a4a6-7a83be48d91fn%40googlegroups.com.