scrollview example without kv file

5,568 views
Skip to first unread message

Rodrigo Liberal

unread,
Jul 11, 2012, 7:02:26 PM7/11/12
to kivy-...@googlegroups.com
I was trying to implement the scrollview example without the kv file but I am finding it difficult.
Do you have a version like that?

qua-non

unread,
Jul 26, 2012, 9:33:11 AM7/26/12
to kivy-...@googlegroups.com

from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label

class SMApp(App):

    def build(self):
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        #Make sure the height is such that there is something to scroll.
        layout.bind(minimum_height=layout.setter('height'))
        for i in range(30):
            btn = Label(text=str(i), size_hint_y=None, height=40)
            layout.add_widget(btn)
        root = ScrollView(size_hint=(None, None), size=(400, 400),
            pos_hint={'center_x':.5, 'center_y':.5})
        root.add_widget(layout)
        return root

if __name__ == '__main__':
    SMApp().run()
This is actually taken from the documentation, http://kivy.org/docs/api-kivy.uix.scrollview.html#managing-the-content-size
I'm curious what part were you having difficulty with?

myprogra...@gmail.com

unread,
Feb 5, 2017, 7:43:09 AM2/5/17
to Kivy users support
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.app import runTouchApp

layout = GridLayout(cols=1, spacing=10, size_hint_y=None)

# Make sure the height is such that there is something to scroll.
layout.bind(minimum_height=layout.setter('height'))
for i in range(100):
btn = Button(text=str(i), size_hint_y=None, height=40)
layout.add_widget(btn)
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))
root.add_widget(layout)

runTouchApp(root)

sebastián lópez

unread,
Feb 5, 2017, 9:30:05 AM2/5/17
to Kivy users support
Hi

I have used this code adpated from kivymd

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

class Contenedor(GridLayout):
    _bind = True
    def __init__(self, *args, **kwargs):
        kwargs['size_hint_y'] = None
        kwargs['cols'] = 1
        super(Contenedor, self).__init__(*args, **kwargs)
    def add_widget(self, widget, index=0):
        if self._bind:
            self.bind(minimum_height=self.setter('height'))
            self._bind = False
        super(Contenedor, self).add_widget(widget, index)
        self.height += widget.height
    def del_widget(self, widget):
        super(Contenedor, self).del_widget(widget)
        self.height -= wigdet.height        
    
class Container(ScrollView):
    def __init__(self, *args, **kwargs):
        kwargs['do_scroll_x'] = False
        super(Container, self).__init__(*args, **kwargs)
        self._grid_widget = Contenedor()
        super(Container, self).add_widget(self._grid_widget)
    @property
    def childs(self):
        return self._grid_widget.children
    def add_widget(self, widget, index=0):
        self._grid_widget.add_widget(widget, index=0)
    def del_widget(self, widget):
        self._grid_widget.del_widget(widget)

You should use the Container class, also you can use it under the kv languaje

Charles longwe

unread,
Dec 30, 2022, 8:50:05 AM12/30/22
to Kivy users support
i underestimated it....But Big thank you....................it is very helpful

Charles longwe

unread,
Dec 30, 2022, 6:21:51 PM12/30/22
to Kivy users support
This works only with group of items what about a long single text...................i have tried but is looks bad...........imagine having a text that has 4000 words.... how can we customized this code to work

On Sunday, February 5, 2017 at 2:43:09 PM UTC+2 myprogra...@gmail.com wrote:

Elliot Garbus

unread,
Dec 30, 2022, 7:53:06 PM12/30/22
to kivy-...@googlegroups.com

What exactly are your trying todo?

Do you want one long Label that can scroll horizontally?

 

You mention 4000 words.  How are those arranged how do you want them displayed?

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/dbfd99e9-da97-4558-95ac-643d05e2a26bn%40googlegroups.com.

 

Charles longwe

unread,
Dec 30, 2022, 10:12:52 PM12/30/22
to kivy-...@googlegroups.com
Alright....I have notes.....in the database .....Yes i want to display it horizontally such that when scrolling .....it should work properly and fit perfectly..can you help please??🤗

Elliot Garbus

unread,
Dec 30, 2022, 11:27:33 PM12/30/22
to kivy-...@googlegroups.com
Please describe the problem in greater detail. Provide a sample of some data and how you want it laid out 


Sent from my iPhone

On Dec 30, 2022, at 8:12 PM, Charles longwe <longwec...@gmail.com> wrote:



Charles longwe

unread,
Dec 31, 2022, 3:15:06 AM12/31/22
to kivy-...@googlegroups.com
X equals  "Long text.......4000 words"
Then Label text equals to X
ScrollVIew  for Label
Then I must be able to scrollView the content without any problem horizontally

NB: The scroll should start exactly at the same position the text has begun and it should end at the end of  the content..
Is this clear enough?.........
=

Elliot Garbus

unread,
Dec 31, 2022, 9:43:25 AM12/31/22
to kivy-...@googlegroups.com

One Label of 4000 words will exceed the max texture size, and will not work.

 

You need a mechanism to break the 4000 words up into smaller pieces, and assign each to a label.  Depending on the number of words per Label, you may also want to use a RecycleView, rather than a ScrollView.

Charles longwe

unread,
Dec 31, 2022, 10:09:52 AM12/31/22
to kivy-...@googlegroups.com
Recycleview ???
sorry no offence...........i tried it this other day but how can it fit the screen/ widget.......it was not fitting perfectly
May you can share a simple example??...........cause whole night i been trying different skills

Elliot Garbus

unread,
Dec 31, 2022, 10:26:17 AM12/31/22
to kivy-...@googlegroups.com

Here is a ScrollView, If this is the kind of thing your looking for I’ll do the Recycleview version.

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock

kv =
"""
<ScrollLabel>:
    size_hint: None, None
    size: self.texture_size[0], dp(30)


BoxLayout:
    orientation: 'vertical'
    Label:
        text: 'Test long Scroll'
    AnchorLayout:
        ScrollView:
            BoxLayout:
                id: scroll_box
                size_hint: None, None
                size: self.minimum_width, dp(30)
"""

class ScrollLabel(Label):
   
pass


class
LongScrollApp(App):
   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):
        Clock.schedule_once(
self.add_text, .5)

   
def add_text(self, _):
        long_text =
'This is a very long piece of text. ' * 4000
       
scroll_box = self.root.ids.scroll_box
       
for substring in long_text.split('.'):
            scroll_box.add_widget(ScrollLabel(
text=substring + '.'))


LongScrollApp().run()

Elliot Garbus

unread,
Dec 31, 2022, 10:44:03 AM12/31/22
to kivy-...@googlegroups.com

Here is a version with RecycleView, the ‘trick’ here is to use key_size and calculate the size of the text.

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.properties import ListProperty
from kivy.clock import Clock

kv =
"""
<ScrollLabel>:
    size_hint: None, None


BoxLayout:
    orientation: 'vertical'
    Label:
        text: 'Test long Scroll'
    AnchorLayout:
        RecycleView:
            id: rv
            data: app.text
            viewclass: 'ScrollLabel'
            RecycleBoxLayout:
                id: scroll_box
                key_size: 'ks'
                default_size_hint: None, None

                size_hint: None, None
                size: self.minimum_width, dp(30)
"""

class ScrollLabel(Label):
   
pass


class
LongScrollApp(App):
    text = ListProperty()

   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):
        Clock.schedule_once(
self.add_text, .5)

   
def add_text(self, _):
        long_text =
'This is a very long piece of text. ' * 400
       
for ss in long_text.split('.'):
            t = ss +
'.'
           
sl = ScrollLabel(text=t)
            sl.texture_update()
           
self.text.append({'text': t, 'ks': sl.texture_size})



LongScrollApp().run()

Charles longwe

unread,
Dec 31, 2022, 12:03:02 PM12/31/22
to Kivy users support

yes is working.....But i wanted to scroll down..............for example imagine reading notes on your pc where u are able to scroll down according to the content you are having.

Elliot Garbus

unread,
Dec 31, 2022, 12:11:05 PM12/31/22
to kivy-...@googlegroups.com

Show me a picture of how you want it to look.  In your previous descriptions, you only mentioned horizontal scrolling of one line.

 

You can change the orientation of the RecycleBoxLayout to ‘vertical’, and make the other required adjustments…

Charles longwe

unread,
Dec 31, 2022, 12:13:21 PM12/31/22
to Kivy users support
Maybe i am not explaining my situation properly.
Supposed someone has  send u a long message on ur phone?
Then u are able to read it from top to bottom through scrolling.
that is the same scrolling i need....In my application i want students to be able to view written notes but scrolling throughput the content from top to bottom..............The same way when some read long message on Whatsaap by scrolling

Elliot Garbus

unread,
Dec 31, 2022, 12:20:11 PM12/31/22
to kivy-...@googlegroups.com

Any characteristics of the text?  Is it a collection of separate messages or just one long 4000 word message?

 

So you want to have the text fill the screen horizontally, wrap and then scroll vertically.  Correct?

Charles longwe

unread,
Dec 31, 2022, 12:59:36 PM12/31/22
to kivy-...@googlegroups.com
yes one long text..I am getting it from database... The scrolling must just be like the way you have explained..... filling up the screen and scroll down 

Charles longwe

unread,
Dec 31, 2022, 1:15:15 PM12/31/22
to Kivy users support
just the same plain text.............This text content has to be displayed on screen and user must be able to scroll down and wen the content is over the scroll must also stop

Elliot Garbus

unread,
Dec 31, 2022, 1:24:00 PM12/31/22
to kivy-...@googlegroups.com

If the text is just 4000 words, with no additional formatting, the trick will be to decide how to break up the text into smaller pieces. 

Another option you could try is just using the Rst widget.  https://kivy.org/doc/stable/api-kivy.uix.rst.html?highlight=rst#module-kivy.uix.rst

 

Let me know if the RST widget works for you.

If not I’ll see if I can come up with a flexible way to breaking the text up into “sections”.  Are their line breaks in the text?

Charles longwe

unread,
Dec 31, 2022, 1:45:12 PM12/31/22
to kivy-...@googlegroups.com
Maybe my explaination is not making sense.
All i need is just a perdon being able to scroll down.
I have tried to come up with something unfortanely it is scrolling yet it requires me to set height .....
This is not a good practice ...because someone can add notes to database that does not feet the height scrolling start behaving abnormally.

All examples in kivy book does not address the standard scrolling ..........................
let me try to test RST

Elliot Garbus

unread,
Dec 31, 2022, 3:14:54 PM12/31/22
to kivy-...@googlegroups.com

It looks like this example from the kivy garden does what you want.  Reading the issues – the code out of data and will need some updating but I’ expect there are some ideas here: https://github.com/kivy-garden/garden.scrolllabel

Elliot Garbus

unread,
Dec 31, 2022, 3:18:57 PM12/31/22
to kivy-...@googlegroups.com

…. the code is out of date and will need some updating…

Charles longwe

unread,
Jan 1, 2023, 3:13:20 AM1/1/23
to Kivy users support
there is problem my pc can not install garden scrolllabel............using pip or garden
................. i am using ubuntu

Charles longwe

unread,
Jan 1, 2023, 4:33:10 AM1/1/23
to kivy-...@googlegroups.com
Thank  you so much..........for now the RST module is working just perfectly.................. I can scroll up and down....... without setting heights and this is what i wanted . One favour please................................Do you have any clue on how we can bind scroll events with the keyboard? For example.. If I press the arrow button I have to scroll up and when I press the arrow down I have to scroll down. Thanks in advance.

Elliot Garbus

unread,
Jan 1, 2023, 7:54:02 AM1/1/23
to kivy-...@googlegroups.com

You do not need to do an install, you can just copy the code from GitHub.  As  I mentioned it will need to be edited/fixed – there are some issues with the code.

Elliot Garbus

unread,
Jan 1, 2023, 8:00:22 AM1/1/23
to kivy-...@googlegroups.com

RstDocument is derived from ScrollView.  You can bind the keyboard and modify scroll_y, to cause the text to scroll.  https://kivy.org/doc/stable/api-kivy.uix.scrollview.html#kivy.uix.scrollview.ScrollView.scroll_y

Charles longwe

unread,
Jan 1, 2023, 8:09:43 AM1/1/23
to Kivy users support
Let me try  it .....I will play it back to you after trying.

Charles longwe

unread,
Jan 1, 2023, 8:19:37 AM1/1/23
to Kivy users support
For us to ass garden scrollabel we need to install it........That's i said i have bad issues to install it on my ubuntu

Nowi am trying to do keyboard binding with RST but if u have example an implementation u can share

Elliot Garbus

unread,
Jan 1, 2023, 8:27:47 AM1/1/23
to kivy-...@googlegroups.com

You can go directly to the GitHub of ScrollLabel, and download the code as a zip file.

 

I’ll do an rst example.

Charles longwe

unread,
Jan 1, 2023, 8:31:26 AM1/1/23
to kivy-...@googlegroups.com

Elliot Garbus

unread,
Jan 1, 2023, 9:18:52 AM1/1/23
to kivy-...@googlegroups.com

Here you go… I left the print statements in there so you can see how the keyboard works.  The keyboard code is from the docs, see the link in the comment.

I selected 15 as the value in pixels to move on the up/down… you can change this if the font size is changed.

 

The document responds to the following keys: up, down, pageup, pagedown, home and end.

 

from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.rst import RstDocument
from kivy.metrics import sp

kv =
"""
BoxLayout:
    Label:
        text: 'Scroll Rst with up/down keys'
    KeyRstDocument:
        text: ' '.join([f'Line {i} This is a long repeating text, it repeats over and over.' for i in range(150)])

"""
# see: https://kivy.org/doc/stable/api-kivy.core.window.html?highlight=window#kivy.core.window.Keyboard
class KeyRstDocument(RstDocument):
   
def __init__(self, **kwargs):
       
super().__init__(**kwargs)
       
self._keyboard = Window.request_keyboard(
           
self._keyboard_closed, self, 'text')
       
self._keyboard.bind(on_key_down=self._on_keyboard_down)

    
def _keyboard_closed(self):
       
print('My keyboard have been closed!')
       
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
       
self._keyboard = None

    def
_on_keyboard_down(self, keyboard, keycode, text, modifiers):
       
print('The key', keycode, 'have been pressed')
       
print(' - text is %r' % text)
       
print(' - modifiers are %r' % modifiers)

       
# Keycode is composed of an integer + a string
       
if keycode[1] in ['up', 'down', 'pageup', 'pagedown', 'home', 'end']:
           
self.process_key(keycode[1]) # your code to process the keyboard

        # If we hit escape, release the keyboard
       
elif keycode[1] == 'escape':
            keyboard.release()
       
# Return True to accept the key. Otherwise, it will be used by
        # the system.
       
return True

    def
process_key(self, key):
       
if key == 'home':
           
self.scroll_y = 1
       
elif key == 'end':
           
self.scroll_y = 0
       
elif key == 'pageup':
            scroll_distance =
self.convert_distance_to_scroll(0, self.height)[1]
           
self.scroll_y = min(1, self.scroll_y + scroll_distance)
       
elif key == 'pagedown':
            scroll_distance =
self.convert_distance_to_scroll(0, self.height)[1]
           
self.scroll_y = max(0, self.scroll_y - scroll_distance )
       
elif key == 'up':
           
# selected 15 as about right for a line based on font size
           
scroll_distance = self.convert_distance_to_scroll(0, sp(15))[1]
           
self.scroll_y = min(1, self.scroll_y + scroll_distance)
       
elif key == 'down':
            scroll_distance =
self.convert_distance_to_scroll(0, sp(15))[1]
           
self.scroll_y = max(0, self.scroll_y - scroll_distance)

class ScrollRstApp(App):
   
def build(self):
       
return Builder.load_string(kv)


ScrollRstApp().run()

Charles longwe

unread,
Jan 1, 2023, 1:34:23 PM1/1/23
to Kivy users support
Thank you so much........You have enlightened me so much
I thought it was impossible but You have done .....Thanks alot

ElliotG

unread,
Jan 2, 2023, 11:32:48 AM1/2/23
to Kivy users support
Here is an implementation that use a recycleview to create the "console-like" display of text.  I have assumed that the text will have a '\n' character, and have used this to split the text into separate labels.   If this is not the case, the text could be split with different strategies.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.recycleview import RecycleView

kv = """
<ScrollLabel>:
    size_hint: 1, None
    text_size: self.width, None  # height must be calculated based on texture_size

<ConsoleRV>:

    viewclass: 'ScrollLabel'
    RecycleBoxLayout:
        id: scroll_box
        orientation: 'vertical'
        key_size: 'ks'
        default_size_hint: 1, None
        size_hint: 1, None
        height: self.minimum_height
        on_width: root.update_text() # when width changes, update sizes in rv data list



BoxLayout:
    orientation: 'vertical'
    Label:
        text: 'Test long Scroll'
        size_hint_y: None
        height: 30
    ConsoleRV:
        id: console_rv
"""

class ScrollLabel(Label):
    pass

class ConsoleRV(RecycleView):
    def add_text(self, text):
        st = [x + '\n' for x in text.split('\n')]  # assuming there are some \n in the text, split into separate labels
        for t in st:
            sl = ScrollLabel(text=t, width=self.width) # create a label
            sl.texture_update()
            self.data.append({'text': t, 'ks': sl.texture_size})

    def update_text(self):
        sl = ScrollLabel()
        for i, entry in enumerate(self.data):
            sl.text = entry['text']
            sl.width = self.width
            sl.texture_update()
            self.data[i]['ks'] = sl.texture_size
            self.refresh_from_data()


sample_text = \
"""In general, the worst-case time complexity of QuickSort is O(n^2), which occurs when the array is already sorted or almost sorted in the reverse order. The best-case time complexity is O(n log n), which occurs when the pivot element is always chosen as the middle element or when the array is already sorted. The average-case time complexity of QuickSort is O(n log n), which makes it a good sorting algorithm for most practical purposes.
However, the actual compute efficiency of QuickSort can be affected by a variety of factors, including the choice of pivot element, the size of the input array, and the presence of duplicate elements. For example, if the pivot element is always chosen as the first or last element in the array, the time complexity can degrade to O(n^2) in the worst case. Similarly, if the input array contains a large number of duplicate elements, the time complexity can also degrade to O(n^2) in the worst case.
In general, QuickSort is a fast and efficient sorting algorithm that is well-suited for many practical applications. Its average-case time complexity of O(n log n) makes it a good choice for sorting large arrays, and it can be implemented in a variety of programming languages.
The time complexity of a bubble sort algorithm is typically O(n^2), which means that the algorithm's performance is proportional to the square of the size of the input array. This is because a bubble sort algorithm compares adjacent elements and swaps them if they are out of order, which means that it has to perform a number of comparisons and swaps that is proportional to the size of the input array.
For example, if the input array contains n elements, the bubble sort algorithm will need to perform n-1 comparisons on the first pass, n-2 comparisons on the second pass, and so on, until it reaches the final pass, which will only require one comparison. This gives us a total of (n-1) + (n-2) + ... + 2 + 1 = (n^2 - n)/2 comparisons, which is O(n^2).
In addition to the time complexity, the compute efficiency of a bubble sort algorithm can also be affected by factors such as the choice of data structures and the presence of optimized code. However, in general, bubble sort is not considered to be a very efficient sorting algorithm, especially for large input arrays. There are many other sorting algorithms that have a better time complexity and are more efficient in practice, such as QuickSort and MergeSort.
There are many different sorting algorithms that have been developed over the years, and the most efficient algorithm for a given situation can depend on a variety of factors. Some of the factors that can affect the efficiency of a sorting algorithm include the size of the input array, the type of data being sorted, the presence of certain patterns or distributions in the data, and the hardware and software environment in which the algorithm is being implemented.
In general, the most efficient sorting algorithms have a time complexity of O(n log n), which means that their performance is proportional to the size of the input array multiplied by the logarithm of the array size. Some examples of sorting algorithms that have a time complexity of O(n log n) include Quicksort, MergeSort, and HeapSort. These algorithms are generally considered to be the most efficient for sorting large arrays.
However, there are also other sorting algorithms that can be more efficient in certain situations. For example, if the input array is already partially sorted or has a limited number of possible values, certain algorithms, such as Insertion Sort and Selection Sort, can be more efficient. In addition, some algorithms, such as Radix Sort and Counting Sort, can be more efficient for sorting data with a limited range of values.
In general, it is important to consider the specific requirements and constraints of a sorting problem when selecting an algorithm, as the most efficient algorithm can vary depending on the situation.

"""

class LongScrollApp(App):

    def build(self):
        return Builder.load_string(kv)

    def on_start(self):
        self.root.ids.console_rv.add_text(sample_text * 10)


LongScrollApp().run()

Elliot Garbus

unread,
Jan 2, 2023, 11:57:33 AM1/2/23
to kivy-...@googlegroups.com

Added a small optimization, removing unnecessary creation of Labels in the add_text loop:

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.recycleview import RecycleView

kv =
"""

<ScrollLabel>:
    size_hint: 1, None
    text_size: self.width, None  # height must be calculated based on texture_size
    font_size: 30


<ConsoleRV>:
    viewclass: 'ScrollLabel'
    RecycleBoxLayout:
        id: scroll_box
        orientation: 'vertical'
        key_size: 'ks'
        default_size_hint: 1, None
        size_hint: 1, None
        height: self.minimum_height
        on_width: root.update_text() # when width changes, update sizes in rv data list


BoxLayout:
    orientation: 'vertical'
    Label:
        text: 'Test long Scroll'
        size_hint_y: None
        height: 30
    ConsoleRV:
        id: console_rv
"""

class ScrollLabel(Label):
   
pass

class
ConsoleRV(RecycleView):
   
def add_text(self, text):
        st = [x +
'\n' for x in text.split('\n')] 
# assuming there are some \n in the text, split into separate labels
       
sl = ScrollLabel() # create a label to use for calculating texture size
       
for t in st:
            sl.text = t
            sl.width =
self.width
            sl.texture_update()
           
self.data.append({'text': t, 'ks': sl.texture_size})

   
def update_text(self):
        sl = ScrollLabel()
       
for i, entry in enumerate(self.data):
            sl.text = entry[
'text']
            sl.width =
self.width
            sl.texture_update()
           
self.data[i]['ks'] = sl.texture_size
           
self.refresh_from_data()


sample_text = \
Reply all
Reply to author
Forward
0 new messages