Макет изображений Kivy Bing - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь сделать что-то вроде макета "Bing images".

То есть:

  • Изображения разделены на несколько столбцов одинаковой ширины.
  • Все изображения имеют одинаковую ширину.
  • Изображения добавляются таким образом, чтобы изображения, добавленные первыми, находились в верхней части макета.
  • Макет можно добавить в ScrollView дляпрокрутка с помощью колесика мыши

Я не нашел способа сделать это с помощью Stack Layout, поэтому я решил создать свой собственный макет.

Я остановился здесь:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.properties import NumericProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView

KV = '''
#:import Window kivy.core.window.Window

ScrollView

    size_hint: (1, None)
    size: Window.size

    MyLayout
        id:my_l
        Button
            text:'1'
        Button
            size_hint_y: None
            height: 900
            text:'2'
        Button
            text:'3'
        Button
            text:'4'
        Button
            text:'5'
            size_hint_y: None
            height: 900

<MyLayout>:
    #height: self.minimum_height

    cols: 3
    spacing: 10
    size_hint_y:None
    row_width: 300
'''

class MyLayout(FloatLayout):
    def __init__(self, **kwargs):

        super(MyLayout, self).__init__(**kwargs)

    cols = NumericProperty(3)
    row_width = NumericProperty(300)
    spacing = NumericProperty(0)

    def do_layout(self, *args):

        self.i = 0
        self.last_x = [self.height]*self.cols
        for child in self.children[::-1]:

            child.width = self.row_width

            if isinstance(child, Image):
                child.height = child.width / child.image_ratio

            child.size_hint_y= None
            child.size_hint_x= None

            self.i+=1
            if self.i == self.cols+1: self.i = 1


            child.x = self.x+(self.i-1)*(self.row_width+self.spacing)

            child.y = self.last_x[self.i-1]-child.height
            self.last_x[self.i-1]-=child.height+self.spacing



        def on_pos(self, *args):
            self.do_layout()

        def on_size(self, *args):
            self.do_layout()

        def add_widget(self, widget):
            super(SuperGrid, self).add_widget(widget)
            self.do_layout()

        def remove_widget(self, widget):
            super(SuperGrid, self).remove_widget(widget)
            self.do_layout()



class MyApp(App):
    def build(self):
        self.root = Builder.load_string(KV)
        Window.bind(on_dropfile=self.add)

    def add(self, *args):

        name= list(args)[1]
        self.root.ids.my_l.add_widget(Image(source=name))

MyApp().run()

Он уже частично работает (вы можете запустить его и перетащить некоторые изображения из ваших папок, чтобы увидеть, о чем я), но проблема в том, что я не понимаю, как подключить к нему ScrollView.

Похоже, мне нужно добавить строку с чем-то вроде height: self.minimum_height в строку KV.но не ясно, где в классе макета мне нужно вычислить minimum_height.

Как заставить код работать с ScrollView?

1 Ответ

0 голосов
/ 28 ноября 2018

Вам просто нужно вычислить height вашего MyLayout экземпляра.В вашем kv файле добавьте:

size_hint: (1, None)

в вашем MyLayout разделе

Затем, в методе do_layout, вычислите height вашего MyLayout.Сделайте self.height = только один раз в конце do_layout (чтобы избежать бесконечного цикла из-за метода on_size).Например, вот модифицированная версия вашего do_layout:

def do_layout(self, *args):

    self.i = 0
    col_heights = [0] * self.cols    # keeps track of the height of each column
    self.last_x = [self.height]*self.cols
    for child in self.children[::-1]:

        child.width = self.row_width

        if isinstance(child, Image):
            child.height = child.width / child.image_ratio

        child.size_hint_y= None
        child.size_hint_x= None

        self.i+=1
        if self.i == self.cols+1:
            self.i = 1

        col_heights[self.i-1] += child.height + self.spacing
        child.x = self.x+(self.i-1)*(self.row_width+self.spacing)

        child.y = self.last_x[self.i-1]-child.height
        self.last_x[self.i-1]-=child.height+self.spacing

    if len(self.children) > 0:
        self.height = max(col_heights)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...