Обновление background_color кнопки иногда не отражается на интерфейсе пользователя - PullRequest
0 голосов
/ 14 ноября 2018

Ну, я создаю приложение 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))

Еще более странно, что это происходит на Raspberry Pi 3 с Raspbian, но я не могу воспроизвести его на компьютере с Windows ... Я дважды проверил, что раздел [input] в конфигурации правильный, и кнопки нажимаются только один раз.

Версия

  • Python: 3.6.0
  • ОС: Raspbian GNU / Linux 9 (растяжение)
  • Киви: 1.10.1

1 Ответ

0 голосов
/ 26 ноября 2018

Наконец, проблема заключалась в том, что я обновлял пользовательский интерфейс в потоке, отличном от основного потока.

В моем приложении состояние кнопки можно изменить либо непосредственно из пользовательского интерфейса, либо из сообщения веб-сокета. Таким образом, когда кнопка background_color была изменена через веб-сокет, обновление пользовательского интерфейса было вызвано другим потоком, и по какой-то причине это вызывало проблему.

Я решил это с помощью декоратора @mainthread:

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

Теперь не имеет значения, какой поток вызывает этот метод, он будет выполняться в основном потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...