Kivy Scrollview 的颜色变化问题
Color changing issue with Kivy Scrollview
我在 scrollview
中的按钮之间创建了一些简单的线条,但是当您在不同位置上下拖动滚动条时,线条的亮度似乎会波动。
当您将 scrollview
对象的高度设置在 501 到 999 像素范围内时,会出现此问题。但是,当您将 scrollview
对象的高度更改为恰好 500 或 1000 像素时,问题停止并且颜色保持一致。我需要红色线条在所有行中保持一致,无论 scrollview
的高度是多少。
有谁知道导致此问题的原因以及解决方法?
编辑:我在 2019 年 7 月 22 日用更新的代码和描述编辑了这个 post,更好地展示了明显的错误。请参阅下面的代码和屏幕截图。
这是从黑色开始的线条图像:
下面是拖动滚动条后线条颜色变亮的图像:
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, 0
size: 900, 700 #If you change the height to 700 pixels, the line colors will darken and brighten as you drag the scroll bar up and down...
#Alternatively, if you change the height to 500 pixels, the line colors stay consistent as you drag the scroll bar..
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: 6
height: self.minimum_height
size_hint: None, None
do_scroll_x: False
""")
class ButtonsApp(App, FloatLayout):
def build(self):
y = 1 #we need to use this variable for dynamic ID creation
start_pixel = 0
for i in range(0, 200):
L1 = Button(text="row = " + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=60, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L2 = Button(text="", font_size=12, halign='left', valign='middle', size_hint=[None, None], width=63, height=40, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L3 = Button(text="22" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=330, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L4 = Button(text="33" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L5 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=122, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L6 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
with self.ids.container.canvas.after:
Color(1, 0, 0, 1)
Line(points=(L1.pos[0], L1.pos[1] + start_pixel, L1.pos[0] + 900, L1.pos[1] + start_pixel), width=1)
#bind text_size to size so that halign and valign work properly on button created above
L1.bind(size=L1.setter('text_size'))
L2.bind(size=L2.setter('text_size'))
L3.bind(size=L3.setter('text_size'))
L4.bind(size=L3.setter('text_size'))
L5.bind(size=L3.setter('text_size'))
L6.bind(size=L3.setter('text_size'))
#add the button to grid layout
self.ids.container.add_widget(L1)
self.ids.container.add_widget(L2)
self.ids.container.add_widget(L3)
self.ids.container.add_widget(L4)
self.ids.container.add_widget(L5)
self.ids.container.add_widget(L6)
y = y + 1
start_pixel = start_pixel + 40
return self
if __name__ == "__main__":
ButtonsApp().run()
颜色没有改变,但是您正在绘制的 Line
正在被 Button
小部件覆盖。为什么它发生在 Buttons
列表的中途,我不知道。但您可以使用 canvas.after
修复它。变化:
with self.ids.container.canvas:
至:
with self.ids.container.canvas.after:
我找到了一个不太理想的解决方案来解决这个问题,方法是在下方绘制宽度为 1.0001 的红线和宽度为 1 的黑线。出于某种原因,拖动滚动视图时颜色会发生变化红色线条的宽度设置为 1(或者线条非常细)。该解决方案会稍微影响性能,因为您必须绘制两倍的线条,但它确实解决了颜色变化问题。
代码如下:
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, 0
size: 900, 700 #If you change the height to 700 pixels, the line colors will darken and brighten as you drag the scroll bar up and down...
#Alternatively, if you change the height to 500 pixels, the line colors stay consistent as you drag the scroll bar..
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: 6
height: self.minimum_height
size_hint: None, None
do_scroll_x: False
""")
class ButtonsApp(App, FloatLayout):
def build(self):
y = 1 #we need to use this variable for dynamic ID creation
start_pixel = 0
for i in range(0, 200):
L1 = Button(text="row = " + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=60, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L2 = Button(text="", font_size=12, halign='left', valign='middle', size_hint=[None, None], width=63, height=40, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L3 = Button(text="22" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=330, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L4 = Button(text="33" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L5 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=122, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L6 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
with self.ids.container.canvas.after: #draw the red line with a width of 1.0001
Color(1, 0, 0, 1)
Line(points=(L1.pos[0], L1.pos[1] + start_pixel, L1.pos[0] + 900, L1.pos[1] + start_pixel), width=1.0001)
with self.ids.container.canvas.after: #draw a black line with a width of 1
Color(0, 0, 0, 1)
Line(points=(L1.pos[0], (L1.pos[1] + start_pixel) - 1, L1.pos[0] + 900, (L1.pos[1] + start_pixel) - 1), width=1)
#bind text_size to size so that halign and valign work properly on button created above
L1.bind(size=L1.setter('text_size'))
L2.bind(size=L2.setter('text_size'))
L3.bind(size=L3.setter('text_size'))
L4.bind(size=L3.setter('text_size'))
L5.bind(size=L3.setter('text_size'))
L6.bind(size=L3.setter('text_size'))
#add the button to grid layout
self.ids.container.add_widget(L1)
self.ids.container.add_widget(L2)
self.ids.container.add_widget(L3)
self.ids.container.add_widget(L4)
self.ids.container.add_widget(L5)
self.ids.container.add_widget(L6)
y = y + 1
start_pixel = start_pixel + 40
return self
if __name__ == "__main__":
ButtonsApp().run()
我在 scrollview
中的按钮之间创建了一些简单的线条,但是当您在不同位置上下拖动滚动条时,线条的亮度似乎会波动。
当您将 scrollview
对象的高度设置在 501 到 999 像素范围内时,会出现此问题。但是,当您将 scrollview
对象的高度更改为恰好 500 或 1000 像素时,问题停止并且颜色保持一致。我需要红色线条在所有行中保持一致,无论 scrollview
的高度是多少。
有谁知道导致此问题的原因以及解决方法?
编辑:我在 2019 年 7 月 22 日用更新的代码和描述编辑了这个 post,更好地展示了明显的错误。请参阅下面的代码和屏幕截图。
这是从黑色开始的线条图像:
下面是拖动滚动条后线条颜色变亮的图像:
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, 0
size: 900, 700 #If you change the height to 700 pixels, the line colors will darken and brighten as you drag the scroll bar up and down...
#Alternatively, if you change the height to 500 pixels, the line colors stay consistent as you drag the scroll bar..
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: 6
height: self.minimum_height
size_hint: None, None
do_scroll_x: False
""")
class ButtonsApp(App, FloatLayout):
def build(self):
y = 1 #we need to use this variable for dynamic ID creation
start_pixel = 0
for i in range(0, 200):
L1 = Button(text="row = " + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=60, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L2 = Button(text="", font_size=12, halign='left', valign='middle', size_hint=[None, None], width=63, height=40, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L3 = Button(text="22" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=330, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L4 = Button(text="33" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L5 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=122, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L6 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
with self.ids.container.canvas.after:
Color(1, 0, 0, 1)
Line(points=(L1.pos[0], L1.pos[1] + start_pixel, L1.pos[0] + 900, L1.pos[1] + start_pixel), width=1)
#bind text_size to size so that halign and valign work properly on button created above
L1.bind(size=L1.setter('text_size'))
L2.bind(size=L2.setter('text_size'))
L3.bind(size=L3.setter('text_size'))
L4.bind(size=L3.setter('text_size'))
L5.bind(size=L3.setter('text_size'))
L6.bind(size=L3.setter('text_size'))
#add the button to grid layout
self.ids.container.add_widget(L1)
self.ids.container.add_widget(L2)
self.ids.container.add_widget(L3)
self.ids.container.add_widget(L4)
self.ids.container.add_widget(L5)
self.ids.container.add_widget(L6)
y = y + 1
start_pixel = start_pixel + 40
return self
if __name__ == "__main__":
ButtonsApp().run()
颜色没有改变,但是您正在绘制的 Line
正在被 Button
小部件覆盖。为什么它发生在 Buttons
列表的中途,我不知道。但您可以使用 canvas.after
修复它。变化:
with self.ids.container.canvas:
至:
with self.ids.container.canvas.after:
我找到了一个不太理想的解决方案来解决这个问题,方法是在下方绘制宽度为 1.0001 的红线和宽度为 1 的黑线。出于某种原因,拖动滚动视图时颜色会发生变化红色线条的宽度设置为 1(或者线条非常细)。该解决方案会稍微影响性能,因为您必须绘制两倍的线条,但它确实解决了颜色变化问题。
代码如下:
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, 0
size: 900, 700 #If you change the height to 700 pixels, the line colors will darken and brighten as you drag the scroll bar up and down...
#Alternatively, if you change the height to 500 pixels, the line colors stay consistent as you drag the scroll bar..
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: 6
height: self.minimum_height
size_hint: None, None
do_scroll_x: False
""")
class ButtonsApp(App, FloatLayout):
def build(self):
y = 1 #we need to use this variable for dynamic ID creation
start_pixel = 0
for i in range(0, 200):
L1 = Button(text="row = " + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=60, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L2 = Button(text="", font_size=12, halign='left', valign='middle', size_hint=[None, None], width=63, height=40, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L3 = Button(text="22" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=330, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L4 = Button(text="33" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L5 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=122, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
L6 = Button(text="Test Description" + str(y), font_size=12, halign='left', valign='middle', size_hint_x=None, width=118, background_color=[0, 0, 0, 1],
id=str(y), color=[.92, .92, .92, 1])
with self.ids.container.canvas.after: #draw the red line with a width of 1.0001
Color(1, 0, 0, 1)
Line(points=(L1.pos[0], L1.pos[1] + start_pixel, L1.pos[0] + 900, L1.pos[1] + start_pixel), width=1.0001)
with self.ids.container.canvas.after: #draw a black line with a width of 1
Color(0, 0, 0, 1)
Line(points=(L1.pos[0], (L1.pos[1] + start_pixel) - 1, L1.pos[0] + 900, (L1.pos[1] + start_pixel) - 1), width=1)
#bind text_size to size so that halign and valign work properly on button created above
L1.bind(size=L1.setter('text_size'))
L2.bind(size=L2.setter('text_size'))
L3.bind(size=L3.setter('text_size'))
L4.bind(size=L3.setter('text_size'))
L5.bind(size=L3.setter('text_size'))
L6.bind(size=L3.setter('text_size'))
#add the button to grid layout
self.ids.container.add_widget(L1)
self.ids.container.add_widget(L2)
self.ids.container.add_widget(L3)
self.ids.container.add_widget(L4)
self.ids.container.add_widget(L5)
self.ids.container.add_widget(L6)
y = y + 1
start_pixel = start_pixel + 40
return self
if __name__ == "__main__":
ButtonsApp().run()