Bonjour, je suis relativement nouveau sur kivy. Jusqu'à présent, faire des trucs de base a été relativement simple, mais cela m'a déconcerté. Je crée une application qui doit ajouter dynamiquement des éléments de canevas rectangulaires à une grille dans une vue de défilement. Puisque je fais cela, j'ai besoin de créer le scrollview en python et non dans le fichier .kv. Comment puis-je faire cela pour que la taille des rectangles soit la même que la taille de la fenêtre lors du redimensionnement des fenêtres?

Fichier .py:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Line,Rectangle
from kivy.uix.carousel import Carousel
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window

class Scroll(ScrollView):
    def __init__(self,  **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = RelativeLayout(pos=(0,0), height=100, size_hint_y=None, size_hint_x=self.width)
            with SkillStat.canvas:
                Rectangle(pos=self.pos,size=(self.width, 90))
            layout.add_widget(SkillStat)

        self.add_widget(layout)
        pass
    pass
class Sheet(Carousel):
    pass

class SheetApp(App):
    def build(self):    
        return Sheet()

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

Fichier .kv:

# file name: Sheet.kv

<Sheet>:
    RelativeLayout:
        Scroll:
            size_hint:(1,1)
1
Austenite 13 mars 2019 à 04:50

2 réponses

Meilleure réponse

Les deux principaux problèmes de votre code sont:

  1. Vous effectuez tous les réglages de taille et de position de votre SkillStat et de son canevas dans une méthode __init__(). Dans une méthode __init__() d'un widget, la position du widget est toujours (0,0) et la taille est (100, 100). Ces propriétés ne sont pas définies sur des valeurs réelles jusqu'à ce que le widget soit réellement dessiné.
  2. Vous faites tout cela en python au lieu de kv. Dans kv, les liaisons sont créées pour de nombreuses propriétés que vous définissez et sont automatiquement mises à jour. Si vous effectuez votre configuration de widget en python, vous devez fournir ces liaisons vous-même.

Voici une version modifiée de votre classe Scroll et une nouvelle classe MyRelativeLayout qui gèrent ces liaisons:

class MyRelativeLayout(RelativeLayout):
    def adjust_size(self, *args):
        self.rect.size = self.size  # set the size of the Rectangle


class Scroll(ScrollView):
    def __init__(self,  **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = MyRelativeLayout(pos=(0,0), height=100, size_hint=(1.0, None))
            with SkillStat.canvas.before:
                SkillStat.rect = Rectangle()
            SkillStat.bind(size=SkillStat.adjust_size)
            layout.add_widget(SkillStat)
        self.add_widget(layout)

Notez l'appel SkillStat.bind() pour créer les liaisons nécessaires, et Rectangle est enregistré en tant que SkillStat.rect dans chaque instance MyRelativeLayout. Ces liaisons seront déclenchées dès que le SkillStat sera affiché, donc les pos et size initiaux du Rectangle ne sont pas nécessaires.

EDIT: La définition du pos du Rectangle dans une liaison causait probablement des problèmes. Le pos par défaut du Rectangle est (0,0), ce qui devrait toujours être le cas. Il nous suffit donc d'ajuster le size du Rectangle. J'ai supprimé la liaison pour pos.

0
John Anderson 16 mars 2019 à 23:41

Solution

  1. Créez une classe avec héritage de RelativeLayout.
  2. Mettez à jour ou supprimez les instructions que vous avez ajoutées à un canevas à l'aide de la fonction bind.

Extraits

class CustomLayout(RelativeLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)
        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=(self.width, 90))
        self.bind(pos=self.update_rect, size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size

Exemple

Main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Line, Rectangle
from kivy.uix.carousel import Carousel
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.lang import Builder


class CustomLayout(RelativeLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)
        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=(self.width, 90))
        self.bind(pos=self.update_rect, size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size


class Scroll(ScrollView):
    def __init__(self, **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = CustomLayout(pos=(0, 0), height=100, size_hint_y=None, size_hint_x=self.width)
            layout.add_widget(SkillStat)

        self.add_widget(layout)


class Sheet(Carousel):
    pass


Builder.load_file('main.kv')


class SheetApp(App):
    def build(self):
        return Sheet()


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

Main.kv

#:kivy 1.11.0

<Sheet>:
    RelativeLayout:
        Scroll:
            size_hint:(1,1)
            bar_width: 10
            effect_cls: "ScrollEffect"
            scroll_type: ['bars']
            bar_color: [1, 0, 0, 1]     # red color
            bar_inactive_color: [0, 0, 1, 1]    # blue color

Production

Scrollview - App Start Up Scrolling RelativeLaouts Window resized - smaller Window resized - bigger

0
ikolim 13 mars 2019 à 15:20