0

Trying code like this I get the Scrollview to work nicely but the scroll_to() function doesn't do anything. The view still starts at the top position.

pixperhour = 60
tagHL = []

dayview = ScrollView(size_hint=(1,1))
test = BoxLayout(size_hint=(1,None), height=24*pixperhour, orientation='vertical')
dayview.add_widget(test)

for i in range(24):
    tagHL.append(Label())
    test.add_widget(tagHL[i])
    tagHL[i].text = "Label "+str(i)
    tagHL[i].color = (1, 1, 1)
    tagHL[i].font_size = 30

dayview.scroll_to(tagHL[12])

I would expect the viewport of the scrollview to change so that the label tagHL[12] becomes visible. Am I doing it wrong or is the function bugged?

Skandalos
  • 123
  • 2
  • 6
  • 1
    Try to schedule that or bind that to an action triggered by some widget like `Button` etc. – ApuCoder Jan 04 '22 at 10:36
  • I triggered it using a Button and this worked. Of course Id like it to be automatic. What kind of event could I bind this to? – Skandalos Jan 04 '22 at 16:56

1 Answers1

2

In order to make it happen as soon as the widget creation is done you can schedule it after (or, before) some (or, no) time as, Clock.schedule_once(lambda *args : dayview.scroll_to(tagHL[12]),dt) where dt can be -1, 0 or any positive value.

As a side note, if you are using tagHL just as a widget container then it will better to use the children attribute of the BoxLayout, test. So, that will be like,

    for i in range(24):
        self.lbl = Label(
            text=f"Label {i}",
            color = [1, 1, 1],
            font_size = 30,
        )
        test.add_widget(self.lbl)
    Clock.schedule_once(lambda *x : dayview.scroll_to(test.children[::-1][12]))
ApuCoder
  • 2,795
  • 2
  • 3
  • 19
  • This seems to work consistently. What does the [::-1] bit do? – Skandalos Jan 04 '22 at 20:24
  • Also Ive now encoutered another obstacle when I try to use the scroll_to() function on an array of scrollviews using a for loop. Using the exact syntax from your example above doesnt work. When I use separate time values, like Clock.schedule_once(lambda *x: dayview.scroll_to(test.children[::-1][12]), i*0.1) , with i being the loop variable, it only updates the view of the last scrollview. – Skandalos Jan 04 '22 at 21:01
  • Just copyed and pasted the same line i times and everthing works. – Skandalos Jan 04 '22 at 21:23
  • 1
    Every `Widget` has an attribute called `children`, a `list` containing its child widgets (if there is/are any). They are inserted one after another, so the first added widget (index=-1) will be at the bottom of the stack and last added widget (index=0) will be on top. Now if you want to address them in the order you added (i.e. first added : 0, secondly : 1, etc.), one way is as described above, i.e. reversing the list that we generally do by the slicing [::-1]. – ApuCoder Jan 05 '22 at 06:25
  • For your second query : that depends on how you set the time duration. – ApuCoder Jan 05 '22 at 06:28
  • It seems to be different from the previous, either add the related codes or post it as another question. – ApuCoder Jan 05 '22 at 07:05
  • I tried a variety of different timings, always got the same result. What could be the reason why it all works when I just place a number of Clock.schecule_once commands in a row but not when I put the same commands in a for loop? – Skandalos Jan 05 '22 at 07:06
  • Sorry you just replied to a comment I already deleted. I cant get the formatting to work in the comments. – Skandalos Jan 05 '22 at 07:08