Unsolved Custom component in ScrollView
-
This is a counterpart to another question I have asked, about how to get a non-attached
ScrollBar
to respond to wheel events. There I have assumed that I cannot useScrollView
to implement scrolling of my component. Maybe I am wrong so let me ask a different question...What does a component need to provide so that it will work in a
ScrollView
? I understand that it should provide acontentHeight
andcontentWidth
and that will tell theScrollView
the actual bounds of the item to be scrolled over. But what about tying the scroll bar positions to the item?In my case I am subclassing
QQuickPaintedItem
to draw a large area of text. Mypaint
method draws in the rectangle defined by theheight
andwidth
properties of the item and I have exposed specific properties that define an offset within the full area of text so that I know which part of the text to draw. I then bind these properties to the scroll bars' positions.If I wanted to make my component work inside a
ScrollView
how would theScrollView
normally expect to communicate to the content item what the scroll bar positions are so that the content item is painted correctly? -
Do you want to paint the part only displayed in the viewport of the ScrollView in your contentItem?
-
@GrecKo yes, that's right. The question is how my component knows where the
ScrollView
viewport currently is. I know what the height and width are but I presume that there is a standard way thatScrollView
communicates the offset of the viewport. -
@GrecKo Another way to put it: for a normal component that functions correctly in a
ScrollView
how does it know which part to paint? This will have some relationship to theScrollView
's scrollbar position but obviously the component does not know aboutScrollView
. -
A normal component in a ScrollView paints everything, even what's not displayed, it just get moved by the ScrollView.
I guess you don't want that as a kind of optimization.
You could add a rect property in your component to make it aware of the viewport needed to be rendered.
You can access it via thecontentItem
of the ScrollView, which is aFlickable
.
Your item will be parent to the contentItem of the Flickable ( so the contentItem of the contentItem of the ScrollView :P)
I would do something like that:ScrollView { id: scrollView CustomItem { viewport: Qt.rect(scrollView.contentItem.contentX, scrollView.contentItem.contentY, scrollView.width, scrollView.height) } }
and in your paint method, only paint what's inside the viewport.
-
@GrecKo Thank you! I have not tried this yet but the
contentItem.contentX|Y
seems like the piece I was missing.Also, thank you for clarifying how
ScrollView
works, in that in fact it paints the whole area. My custom component is a simplified replacement for a read-onlyTextArea
which needs to handle 1000s of lines of text but is obviously only displaying a few at a time. The whole point of what I am doing is to limit the paints to the area needed becauseTextArea
itself performs so poorly (particularly in handling incremental updates once the text is beyond a certain length). -
@GrecKo I tried the suggested approach but it seems that it is quite well baked into
ScrollView
that it expects the whole thing to be painted. There might be a way to get it to work but it's beyond my current level of expertise. I guess I am back to rolling my ownScrollView
-like behaviour which, to be fair, I have working reasonably well; it's just the lack of wheel response on the vertical scrollbar that is the issue. I guess I could implement my ownScrollBar
from scratch...