更新Button的background_color有时不会反映在用户界面上

时间:2018-11-13 21:16:29

标签: kivy

好吧,我正在创建一个Kivy应用程序,在其中您只能选择许多状态之一。每个状态都有自己的Button,所选状态的background_color与其他状态不同。

问题是,有时(显然是随机的)单击按钮后,其中两个停留在同一时间改变了背景。奇怪的是,我正在检查这些元素的background_color,它与我在屏幕上看到的结果不匹配。

因此,background_color属性具有一种颜色,而另一种正在呈现在屏幕上。

相关的kv文件部分:

<StatusButtonsContainer>:
    cols: 2
    spacing: 8
    padding: 0,16,0,0

<StatusButton>:
    selected: False
    text: self.status_name
    on_release: app.on_change_status_click(self.status_name)
    font_size: '16'
    background_color: self.back_color if self.selected else (0.259, 0.259, 0.259,1)
    background_normal: ''
    background_down: ''
    background_disabled_normal: ''

这就是我如何动态创建Button小部件的方式:

class StatusButtonsContainer(GridLayout):

    def __init__(self, **kwargs):
        super(StatusButtonsContainer, self).__init__(**kwargs)
        for name, color in config.statuses.items():
            button = StatusButton(status_name=name, back_color=color)
            self.add_widget(button)


class StatusButton(Button):
    status_name = StringProperty()
    back_color = ListProperty()

这是按下按钮时执行的功能:

class ControlsScreen(Screen):

    def change_selected_status(self, status):
        for button in self.ids.buttons_container.children:
            if button.status_name == status:
                button.selected = True
                button.disabled = True
                print('Status ' + button.status_name + ' was selected.')
                print('background_color:' + str(button.background_color))
            else:
                button.selected = False
                button.disabled = status in ['printing', 'preparing', 'paused']
                print('Status ' + button.status_name + ' was NOT selected.')
                print('background_color:' + str(button.background_color))

更奇怪的是,这是在带有Raspbian的Raspberry Pi 3上发生的,但是我无法在Windows机器上重现它...我再次检查了配置中的[input]部分是否正确,并且这些按钮仅被按下一次。

版本

  • Python:3.6.0
  • 操作系统:Raspbian GNU / Linux 9(拉伸)
  • 基维:1.10.1

1 个答案:

答案 0 :(得分:0)

最后,问题是我在与主线程不同的线程中更新UI。

在我的应用程序中,可以直接从UI或从Web套接字消息更改按钮状态。因此,当通过Web套接字更改按钮的background_color时,UI更新被另一个线程调用,由于某种原因,这导致了问题。

我已经用@mainthread装饰器解决了这个问题:

@mainthread
def change_status_ui(self, status):
    self.get_screen('Controls').change_selected_status(status)
    self.get_screen('Status').change_status(status)

现在,哪个线程调用此方法都没有关系,它将在主线程上执行。