【问题标题】:Color changing issue with Kivy ScrollviewKivy Scrollview 的变色问题
【发布时间】:2019-07-15 19:45:46
【问题描述】:

我在scrollview 中的按钮之间创建了一些简单的线条,但是当您在各个位置上下拖动滚动条时,线条的亮度似乎会波动。

当您将 scrollview 对象的 HEIGHT 设置在 501 到 999 像素之间时,会出现此问题。但是,当您将 scrollview 对象的高度更改为 500 或 1000 像素时,问题停止并且颜色保持一致。无论scrollview 的高度是多少,我都需要红色线条在所有行中保持一致。

有谁知道是什么导致了这个问题以及如何解决它?

编辑:我在 2019 年 7 月 22 日用更新的代码和描述编辑了这篇文章,更好地展示了明显的错误。请参阅下面的代码和屏幕截图。

下面是线条开始变暗的图像:

这是拖动滚动条后线条变为更亮颜色的图像:

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()

【问题讨论】:

    标签: python kivy scrollview


    【解决方案1】:

    颜色没有改变,但是您正在绘制的LineButton 小部件覆盖。为什么它会在Buttons 列表中发生,我不知道。但您可以使用canvas.after 修复它。变化:

    with self.ids.container.canvas:
    

    到:

    with self.ids.container.canvas.after:
    

    【讨论】:

    • John - 我实施了您的更改,这似乎有所帮助。我绝对应该在视图中的按钮顶部画线。但是,颜色仍在变化。我更新了我的帖子,更好地描述了颜色变化和新代码。请自己测试一下,如果您也遇到这种情况,请告诉我。谢谢!
    • 我运行你更新的代码,但我没有看到颜色变化。如果您看到亮度的微小变化,可能是由于您的线条与显示像素不一致。这将导致某些线条(确实重合的线条)看起来比不重合的线条更亮。以 width=1 绘制的线条将使用典型的 opengl 线条绘制算法,该算法可能使用类似于 Bresenham 算法的东西来近似线条(并且可以有亮度变化)。尝试使用width=2 触发不同的算法。
    • 我在 2 台不同的计算机上遇到了同样的问题。一个使用 Windows 10,一个使用 Windows 7。我真的想保持线条细,因为我认为它们看起来更好。
    【解决方案2】:

    我找到了一个不太理想的解决方案来解决此问题,方法是绘制宽度为 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()
    

    【讨论】:

      猜你喜欢
      • 2021-10-06
      • 1970-01-01
      • 2017-09-18
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 2013-07-04
      相关资源
      最近更新 更多