Two or more ScrollViews with background in same BoxLabel with Kivy

0

I'm creating a simple GUI with Kivy in Python 3x and I've had trouble putting two ScrollViews on the same BoxLabel.

The way I put it, in the attached code, the items look like this: With ScrollViews

But it was expected that they would look like this: No ScrollViews

# -*- coding: utf-8 -*-

import kivy
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scrollview import ScrollView

from utils import Grade
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.utils import get_color_from_hex

kivy.require('1.9.1')

Builder.load_string("""
<BackgroundBoxLayout>:
  canvas.before:
    Rectangle:
      pos: self.pos
      size: self.size
      source: 'data/backgrounds/title.png'
<GridLayout>:
  canvas.before:
    Rectangle:
      pos: self.pos
      size: self.size
      source: 'data/backgrounds/label.png'
""")


class DropFile(Button):
    def __init__(self, **kwargs):
        super(DropFile, self).__init__(**kwargs)

        # aparência do botão
        self.size_hint = None, None
        self.background_normal = 'data/icons/pdf_icon_normal.png'
        self.background_down = 'data/icons/pdf_icon_down.png'

    # define o que ocorre quando arquivo é solto no local indicado
    def on_dropfile(self):
        if self.collide_point(*Window.mouse_pos) and not self.disabled:
            self.disabled = True


class BackgroundBoxLayout(BoxLayout):
    pass


class MultiLineLabel(Label):
    def __init__(self, **kwargs):
        super(MultiLineLabel, self).__init__(**kwargs)
        self.text_size = self.size
        self.halign = 'center'
        self.pos_hint = {'top': 0.5}
        self.bind(size=self.on_size)
        self.bind(text=self.on_text_changed)

    def on_size(self, widget, size):
        self.text_size = size[0], None
        self.texture_update()
        if self.size_hint_y is None and self.size_hint_x is not None:
            self.height = max(self.texture_size[1], self.line_height)
        elif self.size_hint_x is None and self.size_hint_y is not None:
            self.width = self.texture_size[0]

    def on_text_changed(self, widget, text):
        print(len(text))
        self.halign = 'left'
        if len(text) > 300:
            self.on_size(self, self.size)
            self.font_size = 12
            self.pos_hint = {'top': 1}
        elif len(text) > 280:
            self.pos_hint = {'top': 0.6}
        elif len(text) > 240:
            self.pos_hint = {'top': 0.6}
        elif len(text) > 100:
            self.halign = 'center'
            self.pos_hint = {'top': 0.7}
        else:
            self.halign = 'center'
            self.pos_hint = {'top': 0.5}


class SimulaReforma(App):
    def __init__(self, **kwargs):
        super(SimulaReforma, self).__init__(**kwargs)

    def build(self):
        Window.bind(on_dropfile=self.handledrops)

        # Layouts
        box = BoxLayout(orientation='vertical')
        disciplinas_label = BoxLayout(size_hint=(1, 1))
        status_label = BackgroundBoxLayout(size_hint=(1, None))
        tittle_label = BackgroundBoxLayout(size_hint=(1, 0.2))

        # Tittle Label
        tittle_label.add_widget(Image(source='data/icons/ufs_icon.png', size_hint=(0.1, 0.8), pos_hint={'top': 0.9}))
        tittle_label.add_widget(Label(text='[b]Simulador de mudança de grade para cursos do DCOMP[/b]',
                                      font_size=20, markup=True, color=get_color_from_hex("#000000")))

        # Status label
        drop_button = DropFile(pos_hint={'right': 1.5})
        status_label.add_widget(drop_button)
        self.status = MultiLineLabel(text='[b]ARRASTE O HISTÓRICO GERADO PELO SIGAA PARA O BOTÃO AO LADO[/b]',
                                     size_hint=(1, None), markup=True, color=get_color_from_hex("#000000"))
        status_label.add_widget(self.status)

        # Disciplinas label
        self.grid1 = GridLayout(cols=1, spacing=10, size_hint_y=None)
        self.grid1.bind(minimum_height=self.grid1.setter('height'))
        for i in range(50):
            btn = Button(text=str(i), size_hint_y=None, height=40)
            self.grid1.add_widget(btn)
        self.grid2 = GridLayout(cols=1, spacing=10, size_hint_y=None)
        self.grid2.bind(minimum_height=self.grid2.setter('height'))
        for i in range(50):
            btn = Button(text=str(i), size_hint_y=None, height=40)
            self.grid2.add_widget(btn)

        cursadas = ScrollView(size_hint=(1, None))
        cursadas.add_widget(self.grid1)
        nao_cursadas = ScrollView(size_hint=(1, None))
        nao_cursadas.add_widget(self.grid2)

        disciplinas_label.add_widget(cursadas)
        disciplinas_label.add_widget(nao_cursadas)

        # box add labels
        box.add_widget(tittle_label)
        box.add_widget(disciplinas_label)
        box.add_widget(status_label)

        return box

    def handledrops(self, *args):
        self.status.text = "[b]PROCESSANDO HISTÓRICO...[/b]"
        # instancia as grades
        self.nova_grade = Grade('novas_grades/Eng_Comp.csv')
        self.grade_atual = Grade(args[1].decode("utf-8"))

        self.status.text = "[b]REALIZANDO EQUIVALÊNCIAS...[/b]"
        # realiza as equivalências da nova grade com base na sua grade atual
        resultado_equivalencia = self.nova_grade.realizar_equivalencias(self.grade_atual.grade["GERAL"])
        self.status.text = resultado_equivalencia

        # printa as disciplinas já cursadas
        label = Label(text=("[b]DISCIPLINAS CURSADAS:[/b]\n\n" + self.nova_grade.disciplinas_cursadas()),
                      size_hint_y=None,
                      color=get_color_from_hex('#000000'), markup=True)
        before = label._label.render()
        label.text_size = (300, None)
        after = label._label.render()
        label.height = (after[1] / before[1]) * before[1]
        self.grid1.add_widget(label)

        label = Label(text=("[b]DISCIPLINAS NÃO CURSADAS:[/b]\n\n" + self.nova_grade.disciplinas_faltam()),
                      size_hint_y=None, markup=True)
        before = label._label.render()
        label.text_size = (300, None)
        after = label._label.render()
        label.height = (after[1] / before[1]) * before[1]
        self.grid2.add_widget(label)


if __name__ == "__main__":
    SimulaReforma().run()

If necessary, the complete project is available at: github.com/arielrodrigues/dcomp.ufs.reforma

    
asked by anonymous 24.11.2016 / 04:44

1 answer

0

After a debugging time I realized that when I remove the images from the rectangles of GridLayout and BoxLayout, I put colors in place, thus:

<BackgroundBoxLayout>:
  canvas.before:
    Color:
      rgba: 1, 1, 1, 1
    Rectangle:
      pos: self.pos
      size: self.size
<GridLayout>:
  canvas.before:
    Color:
      rgba: 1, 1, 1, 1
    Rectangle:
      pos: self.pos
      size: self.size

The result hits as expected (on the iamgem, I removed the buttons, they were there only because of the debug):

So the problem seems to be a bug in the API that was being caused by the background image.

    
24.11.2016 / 15:21