Изображение отображается пустым при обновлении - PullRequest
0 голосов
/ 31 января 2020

Я использую таймер для обновления изображения в интерфейсе через каждую секунду. После запуска интерфейса отображается первое изображение. После того, как поток таймера начинает отображать следующее изображение, виджет отображается пустым (я не вижу изображение). Я могу увидеть изображение, если я начну индекс с другого значения. У меня нет проблем с изображениями. Я не могу обновить изображение на экране интерфейса пользователя. Может кто-нибудь помочь мне разобраться в проблеме?

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.image import AsyncImage
from kivy.properties import StringProperty, ListProperty, ObjectProperty
import json, timer
import threading

data = json.load(open('demotest.json'))

Builder.load_file('dv_demo.kv')


class DVDemo(Widget):
    message = StringProperty()
    image = StringProperty('')
    sms = ListProperty()
    idx = 0

    def __init__(self, **kwargs):
        super(DVDemo, self).__init__(**kwargs)
        self.update_data_index(self.idx)

    def schedule_screens(self):
        self.idx = self.idx + 1
        if self.idx >= len(data):
            time.sleep(500)
        temp = threading.Thread(target=self.update_data_index, args=(self.idx,))
        threading.Timer(1, temp.start).start()

    def update_data_index(self, idx):
        # self.image = data[idx]['picture_url']
        self.message = data[idx]['message']
        self.sms = data[idx]['sms']

        message_layout = self.ids.message_panel
        message_btn = Button(text=self.message, background_color=[0, 1, 1, 1])
        message_layout.add_widget(message_btn)

        sms_layout = self.ids.sms_panel
        sms_layout.clear_widgets()
        for sms_msg in self.sms:
            sms_btn = Button(text=sms_msg['sms'], background_color=[0, 0, 2, 1])
            sms_layout.add_widget(sms_btn)

        self.ids.image_object.source = data[idx]['picture_url']

        self.schedule_screens()


class DVDemoApp(App):
    def build(self):
        self.title = 'DV Demo App'
        return DVDemo()


if __name__ == "__main__":
    DVDemoApp().run()
<ColoredLabel@Label>:
    text_size: self.size
    halign: 'left'
    valign: 'top'
    padding: 4, 4
    bold: True
    color: (.6, .6, .6, 1)
    canvas.before:
        Color:
            rgb: (.9, .9, .9)
        Rectangle:
            pos: self.pos
            size: self.width - sp(2), self.height - sp(2)

<DVDemo>:
    FloatLayout:
        id: demo_panels
        size: root.width - 50, root.height - 50
        pos: root.x + 25, root.y + 25

        BoxLayout:
            id: message_panel
            pos_hint: {"x":0, "top":1}
            size_hint: 0.5, 1
            orientation: 'vertical'
            canvas.before:
                Color:
                    rgb: (.9, .9, .9)
                Rectangle:
                    pos: self.pos
                    size: self.width - sp(2), self.height - sp(2)

        #ColoredLabel:
        #    id: message_panel
        #    text: root.message
        #    pos_hint: {"x":0, "top":1}
        #    size_hint: 0.5, 1

        BoxLayout:
            id: image_panel
            #text: "Image"
            pos_hint: {"x":0.5, "top":1}
            size_hint: 0.5, 0.5
            Image:
                id: image_object
                source: root.image
                center_x: self.parent.center_x
                center_y: self.parent.center_y
                size: self.parent.height,self.parent.width

        BoxLayout:
            id: sms_panel
            pos_hint: {"x":0.5, "top":0.5}
            size_hint: 0.5, 0.5
            orientation: 'vertical'
            canvas.before:
                Color:
                    rgb: (.9, .9, .9)
                Rectangle:
                    pos: self.pos
                    size: self.width - sp(2), self.height - sp(2)

1 Ответ

0 голосов
/ 31 января 2020

Установка свойств GUI должна выполняться в главном потоке. Удобно, что существует метод Clock.schedule_once(), который планирует вызов в главном потоке после задержки. Итак, я бы предложил изменить часть класса DVDemo следующим образом:

class DVDemo(Widget):
    message = StringProperty()
    image = StringProperty('')
    sms = ListProperty()
    idx = 0

    def __init__(self, **kwargs):
        super(DVDemo, self).__init__(**kwargs)
        self.update_data_index()

    def schedule_screens(self):
        self.idx = self.idx + 1
        Clock.schedule_once(self.update_data_index, 5)

    def update_data_index(self, *args):
        idx = self.idx
        .
        .
        .

В приведенном выше коде используется Clock.schedule_once() и исключено прохождение idx среди методов, поскольку он является атрибутом DVDemo экземпляр.

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