我注意到当将新行添加到现有的滚动视图时,scroll_y值将重置为0.0。这是一个问题,因为在将行添加到现有的滚动视图时,我需要知道新的scroll_y值。
在将新行添加到scrollview之后,我可以手动向下滚动鼠标滚轮(通过滚动停止)来获取新的scroll_y值。但是,我需要在代码向视图中添加新行并将滚动条向上移动之后立即知道新的scroll_y值,如下例所示。
在将新行添加到滚动视图并且使用代码移动了条形之后,如何获取新的scroll_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()
答案 0 :(得分:0)
我认为这个问题有两个方面。
首先-我怀疑on_scroll_stop
事件的行为不符合您的期望(这不是我所期望的)。每次鼠标滚轮滚动都会导致多个on_scroll_stop
事件,而不仅仅是滚动结束时的一个事件。这会使您的scroll_on_stop()
方法在每次鼠标滚轮滚动时都会被调用多次。
第二个-scroll_to()
方法将延迟自身(使用Clock.schedule.once()
),如果还有其他未决操作(例如将行添加到其子级时)。
因此,当scroll_on_stop()
被多次调用时,scroll_to()
被延迟(scroll_y
未更新),导致报告了旧值scroll_y
。 / p>
我认为您可以通过不使用scroll_to()
来解决此问题,而只需设置scroll_y
。我建议替换您的行:
self.root.ids.sv.scroll_to(self.root.ids.container.children[100])
类似:
self.root.ids.sv.scroll_y = 100.0/end_row
这可以防止scroll_on_stop()
一次滚动多次添加行,并且应滚动到所需的行。