Python Scrollview问题-将行添加到Scrollview后,scroll_y未更新

Python Scrollview问题-将行添加到Scrollview后,scroll_y未更新,python,kivy,Python,Kivy,我注意到,当向现有scrollview添加新行时,scroll_y值被重置为0.0。这是一个问题,因为在将行添加到现有scrollview时,我需要知道新的scroll_y值 在向scrollview添加新行后,我可以在手动向下滚动鼠标滚轮(通过on scroll stop)后获得新的scroll_y值。但是,在代码向视图添加新行并向上移动滚动条之后,我需要知道新的scroll_y值,如下面的示例所示 在向scrollview添加新行并使用代码移动滚动条后,如何获取新的滚动y值 from kiv

我注意到,当向现有scrollview添加新行时,scroll_y值被重置为0.0。这是一个问题,因为在将行添加到现有scrollview时,我需要知道新的scroll_y值

在向scrollview添加新行后,我可以在手动向下滚动鼠标滚轮(通过on scroll stop)后获得新的scroll_y值。但是,在代码向视图添加新行并向上移动滚动条之后,我需要知道新的scroll_y值,如下面的示例所示

在向scrollview添加新行并使用代码移动滚动条后,如何获取新的滚动y值

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.graphics import Line, InstructionGroup, Canvas, CanvasBase, Color, Rectangle

Builder.load_string("""
<ButtonsApp>:
    ScrollView:
        id: sv
        size_hint: None, None
        pos: 205, 200
        size: 200, 600 
        on_scroll_stop: app.scroll_on_stop()
        scroll_type: ['bars']
        scroll_wheel_distance: 20
        bar_width: 8
        bar_inactive_color: .55, .55, .55, 1 
        bar_color: .663, .663, .663, 1 
        canvas.before:
            Color:
                rgba: 0, .5, 1, 1
                group: 'b'
            Rectangle:
                size: 0, 0
                group: 'b'
        GridLayout:
            id: container
            cols: 1
            height: self.minimum_height
            size_hint: None, None
            do_scroll_x: False


""")

class ButtonsApp(App, FloatLayout):

    def build(self):
        global rolling_row_cnt
        global my_number_list
        global start_row 
        global end_row
        rolling_row_cnt = 0 #we will use this variable to keep track of the total number of rows in the scrollview as we add rows to it..
        my_number_list = []
        #create a list of numbers from 1 to 600 - this represents the max number of rows that can be displayed
        for i in range(0, 600):
            my_number_list.append(i)
        #we will start the scrollview only showing 100 rows to start.. 
        #as the user scrolls down the view we will add more rows (100 at a time) and adjust the scrollview upwards      
        start_row = 0
        end_row = 100
        self.modify_scrollview()
        return self

    def modify_scrollview(self):
        global rolling_row_cnt
        global my_number_list
        global start_row 
        global end_row
        for i in my_number_list[start_row:end_row]: #add 100 rows to the scrollview...
            L1 = Button(text="row = " + str(rolling_row_cnt), font_size=12, halign='left', valign='middle', size_hint=[None, None], height=37, width=60, background_color=[0, 0, 0, 1], color=[.92, .92, .92, 1])
            L1.bind(size=L1.setter('text_size'))  
            self.ids.container.add_widget(L1)
            rolling_row_cnt = rolling_row_cnt + 1
        if rolling_row_cnt > 99:
            print ("WRONG SCROLL_Y = " + str(self.ids.sv.scroll_y)) #THIS IS WHERE THE PROBLEM OCCURS - after you add rows to the existing scrollview through scroll_on_stop below,
        #the scroll_y value that gets calculated here is 0.0 which is WRONG. How do I get this value to update properly when new rows are added to the scrollview? If I add new rows and move the bar up using code,
        #it should give me the scroll_y at the current bar's position, not 0.0.. 

    def scroll_on_stop(self):
        global start_row 
        global end_row
        if self.ids.sv.scroll_y < .05: #if the user scrolls the view close to the bottom, we will add another 100 rows to the existing scrollview 
            start_row = start_row + 100
            end_row = end_row + 100
            self.modify_scrollview() #trigger the addition of 100 more rows to the existing scrollview
            self.root.ids.sv.scroll_to(self.root.ids.container.children[100]) #adjust the scrollview UPWARD to keep the last most row from last time in view for the user..
        print ("SCROLL_Y = " + str(self.ids.sv.scroll_y)) #this scroll_y is correct when you manually move the mouse wheel 

if __name__ == "__main__":
    ButtonsApp().run()
从kivy.app导入应用
从kivy.uix.floatlayout导入floatlayout
从kivy.lang导入生成器
从kivy.uix.button导入按钮
从kivy.graphics导入行、指令组、画布、画布库、颜色、矩形
生成器。加载\u字符串(“”)
:
滚动视图:
id:sv
大小提示:无,无
位置:205200
尺寸:200600
on_scroll_stop:app.scroll_on_stop()
滚动条类型:[“条”]
滚轮距离:20
钢筋宽度:8
条形图非活动颜色:.55、.55、.55、1
条形图颜色:.663、.663、.663、1
在以下情况之前:
颜色:
rgba:0,5,1,1
b组
矩形:
大小:0,0
b组
网格布局:
id:集装箱
科尔斯:1
高度:自身最小高度
大小提示:无,无
是否滚动\u x:False
""")
类按钮应用程序(应用程序、浮动布局):
def生成(自):
全球滚动
全局我的号码列表
全局起始行
全局结束行
rolling_row_cnt=0 35;我们将使用此变量在向scrollview添加行时跟踪scrollview中的行总数。。
我的号码列表=[]
#创建一个从1到600的数字列表-这表示可以显示的最大行数
对于范围(0600)内的i:
我的号码列表。附加(i)
#我们将启动仅显示100行的滚动视图。。
#当用户向下滚动视图时,我们将添加更多行(一次100行),并向上调整滚动视图
起始行=0
结束_行=100
self.modify_scrollview()
回归自我
def修改_滚动视图(自):
全球滚动
全局我的号码列表
全局起始行
全局结束行
对于我的编号列表中的i[开始行:结束行]:#将100行添加到scrollview。。。
L1=按钮(text=“row=”+str(滚动行),font\u size=12,halign='left',valign='middle',size\u hint=[None,None],高度=37,宽度=60,背景色=[0,0,0,1],颜色=[0.92,92,92,1])
L1.bind(size=L1.setter('text\u size'))
self.ids.container.add_小部件(L1)
滚动排碳管=滚动排碳管+1
如果滚动行>99:
打印(“Error SCROLL_Y=“+str(self.ids.sv.SCROLL_Y))#这就是问题发生的地方-通过下面的SCROLL_on_stop将行添加到现有的scrollview之后,
#此处计算的滚动y值为0.0,这是错误的。当向scrollview添加新行时,如何使该值正确更新?如果我添加新行并使用代码向上移动条,
#它应该给出当前条位置的滚动条,而不是0.0。。
def滚动打开停止(自):
全局起始行
全局结束行
如果self.ids.sv.scroll_y<.05:#如果用户将视图滚动到接近底部,我们将在现有的scrollview中再添加100行
起始行=起始行+100
end_行=end_行+100
self.modify_scrollview()#触发在现有scrollview中再添加100行
self.root.ids.sv.scroll_to(self.root.ids.container.children[100])#向上调整scrollview,以便为用户保留上次查看的最后一行。。
打印(“SCROLL_Y=“+str(self.ids.sv.SCROLL_Y))#手动移动鼠标滚轮时,此滚动是正确的
如果名称=“\uuuuu main\uuuuuuuu”:
ButtonsApp().run()

我认为问题是双重的。 首先-我怀疑
on\u scroll\u stop
事件的行为与您期望的不一样(这不是我期望的)。每个鼠标滚轮滚动都会导致几个
on\u scroll\u stop
事件,而不仅仅是滚动结束时的一个事件。这会导致每次鼠标滚轮滚动都会多次调用
scroll\u on\u stop()
方法

第二个-如果有其他操作挂起(如将行添加到子行),则
滚动到()
方法将延迟自身(使用
Clock.schedule.once()

因此,当多次调用
scroll\u on\u stop()
时,
scroll\u to()
会延迟(
scroll\u y
不会更新),导致报告
scroll\u y
的旧值

我认为您可以通过不使用
scroll\u to()
来解决此问题,而只需设置
scroll\u y
。我建议更换您的线路:

self.root.ids.sv.scroll_to(self.root.ids.container.children[100])
比如:

self.root.ids.sv.scroll_y = 100.0/end_row

这可以防止
滚动到\u stop()
在一个滚动上多次添加行,并且应该滚动到所需的行。

最好仍然使用“滚动到”方法并确定适当的滚动y值。我还注意到“convert_scroll_to_distance”方法在这种情况下似乎也不起作用。我猜这些问题是源代码问题。John的回答是一个很好的变通解决方案,在这种情况下仍然可以提供滚动值。非常感谢你的帮助!