George Kym
George Kym

Reputation: 55

[Python][Kivy] Content Being Hidden over Scrollable Area

I have put contents in

AnchorLayout():
    ScrollView():
       GridLayout():

In this Tree form.

When it is ran, it shows as below: enter image description here

ps. excuse me for the erasure. its personal data

but when drag my mouse with right button of my mouse vertically upwards and hold, the hidden contents show up only when i am holding the mouse pointer. and the picture shows as below: enter image description here

left side and the top side contents are now shown when i am not holding my mouse cursor after draging it.

How should i do to make this all presentable?

And I am a little bit worried if these widgets are not to be fit on the mobile device when I build it for an app.

Could you please also guide me on how to set the loc and the size of the widgets that expand or shrink on change of the size of the window.

My codes are found here: https://gist.github.com/georgekym/b6cc93a7b8224246bc937afd7e2f0ead

# -*- coding:utf-8 -*-
from kivy.app import App
from kivy.core.window import Window
from kivy.properties import ObjectProperty
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button

from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label

from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.scrollview import ScrollView


class OrdersPage(Screen):
    sm = ObjectProperty()

    def __init__(self, sm, name, **kwargs):
        super(OrdersPage, self).__init__(**kwargs)
        self.sm = sm
        self.name = name
        self.set_order_products()

    def set_order_products(self):
        prod_layout = GridLayout(cols=2,
                                 row_force_default=True,
                                 row_default_height=40,
                                 size_hint=(None, None),
                                 spacing=(10, 10))
        prod_layout.bind(minimum_height=prod_layout.setter('height'))

        product_table_header = {'Qty': 50, 'Product': 300}
        product_width_list = [50, 300]
        for column in product_table_header.keys():
            prod_layout.add_widget(Product(bold=True,
                                           text=column,
                                           width=product_table_header[column],
                                           size_hint=(None, None),
                                           color=(0.53, 0.808, 0.92, 1),
                                           valign='middle',
                                           halign='left'
                                           ))

        prod = [['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash']]

        for one in prod:
            for index in range(len(one)):
                prod_layout.add_widget(Button(text=str(one[index]), width=product_width_list[index]))

        self.v_scroller = ScrollView(size_hint=(1, 1))
        self.v_scroller.add_widget(prod_layout)
        self.prod_grand_layout = AnchorLayout(anchor_x='center',
                                              anchor_y='bottom',
                                              padding=(10, 10),
                                              size_hint=(1, 1),
                                              pos=(0, -200)
                                              # size=(380, 500)
                                              )

        self.prod_grand_layout.add_widget(self.v_scroller)

        self.add_widget(self.prod_grand_layout)


class Product(Label):
    def __init__(self, **kwargs):
        super(Product, self).__init__(**kwargs)
        self.size_hint = (None, None)
        self.color = (0.53, 0.808, 0.92, 1)
        self.valign = 'middle'
        self.halign = 'left'
        self.font_size = 13


class MainController(ScreenManager):
    def __init__(self, **kwargs):
        super(MainController, self).__init__(**kwargs)


class TestApp(App):
    sm = ObjectProperty()

    def build(self):
        Window.clearcolor = (1, 1, 1, 1)
        Window.size = (400, 600)
        self.sm = MainController()
        self.sm.add_widget(OrdersPage(self.sm, name='tester'))
        return self.sm


if __name__ == '__main__':
    TestApp().run()

And I would truly appreciate for your guidance.

Upvotes: 0

Views: 276

Answers (1)

John Anderson
John Anderson

Reputation: 39117

I believe the biggest problem is that your AnchorLayout is created with:

pos=(0, -200)

This means that the bottom 200 pixels of the AnchorLayout are below the bottom of the OrdersPage.

In order to adjust sizes when the window changes size, use size_hint instead of actual sizes. Her is a modified version of your posted code with the changes that I mentioned.

# -*- coding:utf-8 -*-
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen, ScreenManager


class OrdersPage(Screen):

    def set_order_products(self):
        prod_layout = self.ids.prod_layout

        # use size_hints for width instead of actual width values
        product_table_header = {'Qty': 0.15, 'Product': 0.85}
        product_width_list = [0.15, 0.85]
        for column in product_table_header.keys():
            prod_layout.add_widget(Product(bold=True,
                                           text=column,
                                           size_hint_x=product_table_header[column]
                                           ))

        prod = [['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash'],
                ['1', 'BodyWash']]

        for one in prod:
            for index in range(len(one)):
                prod_layout.add_widget(Button(text=str(one[index]), size_hint_x=product_width_list[index]))


class Product(Label):
    pass


class MainController(ScreenManager):
    pass


kv = '''
<Product>:
    size_hint_y: None
    height: self.texture_size[1]
    color: (0.53, 0.808, 0.92, 1)
    valign: 'middle'
    halign: 'left'
    font_size: 13
    
<OrdersPage>:
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'bottom'
        padding: (10, 10)
        ScrollView:
            GridLayout:
                id: prod_layout
                cols: 2
                row_force_default: True
                row_default_height: 40
                size_hint_y: None
                spacing: (10, 10)
                height: self.minimum_height
<MainController>:
    OrdersPage:
        name: 'tester'
'''


class TestApp(App):
    sm = ObjectProperty()

    def build(self):
        # load the kv rules
        Builder.load_string(kv)
        
        Window.clearcolor = (1, 1, 1, 1)
        Window.size = (400, 600)
        self.sm = MainController()

        # fill the OrdersPage
        self.sm.get_screen('tester').set_order_products()

        return self.sm


if __name__ == '__main__':
    TestApp().run()

I have used the kv language to set up the GUI. This simplifies the code and sets up bindings for you that you would otherwise have to code yourself.

Upvotes: 1

Related Questions