GridView in ScrollLayout using an adaptor [WAS: vertical AND horizontal scrolling in ListView?]

175 views
Skip to first unread message

Oon-Ee Ng

unread,
Sep 30, 2015, 4:15:57 AM9/30/15
to kivy-...@googlegroups.com
I was just searching for information on my current issue when I saw
this topic, so I thought I'd add to it.

Rather than scroll events falling through, I'd rather the listview not
get any scroll events and leave all scrolling to the scrollview (which
can easily handle panning, AND gives a grab-bable scrollbar which is
important for my desktop app). As you mentioned, with 1.9.0 this
doesn't seem possible.

The alternative I can think of is to use a GridView in a ScrollLayout,
which is not too hard, but then we lose the benefits of the adaptor
(in particular, I don't really want to write my own buggy code for
enforcing selection rules).

Is there any way to adapt a GridView to use a ListAdaptor (for
instance)? Or a way to make ListView totally pass through all
scrolling (not all touches as that would make it unselectable)?

On Fri, Sep 18, 2015 at 12:05 PM, Bill Eaton <wpea...@gmail.com> wrote:
> I wonder if there is a way to make sure scroll events fall through some
> widgets and reach others? What if I could make sure my ListView gets y
> scroll events and it's container gets x scroll events? Would that work?
>
> On a different note, I managed to get some scrolling in both axes, but it's
> not really usable.
> If I set
> do_scroll_x: False
> do_scrolly_y: False
> For the ListView, and the true for a ScrollView container. Then I can get
> the Scrollview to scroll x and y. But the only way to make it work is to
> scroll x first so the ListVIew hangs off the screen and there is a small gap
> on the left. Then mouse/touch down on that gap and scroll in y.
>
> I can't really do anything useful with this.

Oon-Ee Ng

unread,
Sep 30, 2015, 4:57:19 AM9/30/15
to kivy-...@googlegroups.com, Bill Eaton
Oh that didn't turn out to be so hard in the end. I was thinking of
getting a new class to inherit from both GridLayout and AbstractView,
but needed an example, so I looked up the ListView sources themselves.
Turns out (probably since 1.9.0) ListView just uses GridView in
ScrollView internally anyway. I'm not familiar enough with the various
internals to comment much, but I can say that copying the kv and class
definitions for ListView to my own python file and modifying the kv
definitions to include do_scroll_x: True works, a pannable listview
results.

Of course, for my own issue I also added bar_width: 8 and scroll_type:
['bars', 'content']. Seems to work for now.

I believe the scroll bars in particular would be useful to expose as
an option for ListView. Not too helpful on phones, but almost expected
on desktop. I've raised a recommendation here -
https://github.com/kivy/kivy/issues/3658

Bill Eaton

unread,
Sep 30, 2015, 6:26:39 PM9/30/15
to Kivy users support, wpea...@gmail.com
Oon-Ee,

Could you provide some more details on how you got it to work?

Did you only have to edit the Builder.load_string() section of the listview.py file (line 779) in the uix directory?

I tried that on Windows and Linux and I cannot get x scrolling

Oon-Ee Ng

unread,
Sep 30, 2015, 8:00:24 PM9/30/15
to kivy-...@googlegroups.com
Unsure how familiar you are with python in general, but simply editing
that would work (but also affect every other Kivy project you have).
What I did was simply copy the kv definitions (in Builder.load_string)
for ListView as well as the entire class itself to my own
CustomListView.py source file, then do the edits there (adding as well
the necessary includes, and taking out the include which would bring
in the system Kivy listview).

Specifically, the only changes I made were:-

<ListView>:
container: container
ScrollView:
pos: root.pos
on_scroll_y: root._scroll(args[1])
do_scroll_x: False
bar_width: 20
scroll_type: ['bars', 'content']
effect_cls: 'ScrollEffect'
GridLayout:
cols: 1
id: container
size_hint_y: None


In your case, you would want do_scroll_x to be True, and probably to
modify GridLayout's size_hint_x and width (otherwise it would just
conform to the parent). The lines I added for bar_width, scroll_type,
and effect_cls aren't necessary for you I guess.
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.

Bill Eaton

unread,
Oct 2, 2015, 12:53:03 PM10/2/15
to Kivy users support
Thanks for the response, Oon-Eee. There's another way to change the behavior of a ListView: put it in the kv file for your app. I'm not sure if this is a good idea, but it works.

And you're right: the key to getting scrolling in the x direction was to change the width of the embedded GridLayout. Once I changed the width to be wider than the screen width, I got scrolling! Now I'm left with the issue of how to expose the GridLayout width to the rest of my program, so it can be set at run time.

Thanks for the help!


Bill Eaton

unread,
Oct 2, 2015, 2:59:55 PM10/2/15
to Kivy users support
I figure out the width problem. The trick is knowing that the parent is called "root" in kv language. To achieve scrolling in x and y, the kv becomes:
<ListView>:

  container: container
  ScrollView:
    pos: root.pos
    on_scroll_y: root._scroll(args[1])
    do_scroll_x: True

    GridLayout:
      cols: 1
      id: container
      size_hint_x: None
      size_hint_y: None
      width: 1.5*root.width
In this example I use 1.5 times the ScrollView width. This kv can either be put inside the Builder.load_string of a custom widget or it can be inside the .kv file for your app. For now, I'm putting it in the .kv file for my app.



Reply all
Reply to author
Forward
0 new messages