Kivy Label Невозможно обновить при проверке IP-адреса - PullRequest
1 голос
/ 12 апреля 2019

Я создаю интерфейс Kivy с модулем raspberry pi. В пользовательском интерфейсе у меня есть экран состояния, на котором отображается IP-адрес. Если я отсоединяю кабель Ethernet, на экране должно появиться сообщение об ошибке ( ярлык kivy screenone : IpAddress ) и при повторном подключении кабеля Ethernet метка должна быть обновлена ​​до IP-адреса. К сожалению, когда я отключаю кабель Ethernet, приложение показывает «Ошибка», но при повторном подключении Ethernet оно не отображает мой IP-адрес. Ipaddress метка остается как "Ошибка" ..

##this is the root widget
class Menu(BoxLayout):
    manager = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Menu, self).__init__(**kwargs)
        Window.bind(on_keyboard=self._key_handler)
        #btn1 = ActionButton(text='',icon='./assest/usb.jpg')

    def _key_handler(self, instance, key, *args):
        if key is 27:
            self.set_previous_screen()
            return True

    def set_previous_screen(self):
        if self.manager.current != 'home':
            #self.manager.transition.direction = 'left'
            self.manager.transition = SwapTransition()


class ScreenOne(Screen,BoxLayout):

    stringIP=subprocess.check_output(["hostname", "-I"]).split()[0]
    print_ip = StringProperty(str(stringIP).strip("b'"))

    def __init__(self, **kwargs):
        super(ScreenEnergy, self).__init__(**kwargs)
        #Clock.schedule_interval(self.update_ip, 1)
        scheduler1 = BackgroundScheduler()
        scheduler1.add_job(self.update_ip, 'interval', seconds=1)
        scheduler1.start()
        # #self.update_ip()
        print("status window")


    def update_ip(self,*args):     
        try:
            # connect to the host -- tells us if the host is actually
            # reachable
            socket.create_connection(("www.google.com", 80))
            self.print_ip
            print("ip")
            #print("connected")
            return True
        except OSError:
            self.ids.ipAddress.text="[b][color=ff0000]Error[/color][/b]"
            print("not Ip ")
        return False

        # try:
        #     #socket.inet_aton(self.print_ip)
        #     #socket.inet_pton(socket.AF_INET6, self.print_ip)
        #     self.print_ip='\b(([1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
        #     self.ids.ipLabel.text="faffxga"
        #         # legal
        # except socket.error:
        #     self.ids.ipLabel.text="adadadsadsa"
        # return False

        #         # Not legal

       class MenuApp(FlatApp):


    def build(self):
        my_callback=Menu()
        #ip_call =ScreenEnergy()
        scheduler = BackgroundScheduler()
        scheduler.add_job(my_callback.is_connected, 'interval', seconds=1)
        #scheduler.add_job(ip_call.update_ip, 'interval', seconds=1)
        scheduler.start()
        return my_callback



if __name__ == '__main__':

    MenuApp().run()
#:kivy 1.10.0
#:import hex kivy.utils.get_color_from_hex
#:import Factory kivy.factory.Factory

<Menu>:
    canvas.before:
        Rectangle:
            pos: self.pos
            size: self.size

    manager: screen_manager
    orientation: "vertical"
    ActionBar:

        size_hint_y: 0.15
        background_image: ''
        background_color: 0.349, 0.584, 0.917, 1
        ActionView:
            ActionPrevious:

            ActionButton:
                id:motorBtn
                text:''
                icon:'./assest/Ethernet.jpg'

    Manager:
        id: screen_manager

<ScreenOne>:
    BoxLayout:
        orientation: 'vertical'
        WrappedLabel:
            id:welcomeStatus
            text: "[b]Status[/b]"
            font_size:min(root.width,root.height)/15
        GridLayout:
            cols:2
            row: 3
            padding:root.width*.02,root.height*.03
            spacing:min(root.width,root.height)*.02
            Label:   
                id:ipLabel
                size_hint_x: .15
                color: 0, 0, 0, 1
                text: '[b]IP Address :[/b]'
                markup:True 
            Label:
                id:ipAddress
                size_hint_x: .15
                color: 0, 0, 0, 1
                text: root.print_ip
                color: 1, 0, 0, 1
                bold:True
                markup:True  

<Screen 2>:

<Manager>:

    id: screen_manager

ОБНОВЛЕНИЕ ВТОРОЕ: После требуемой модификации кода больше нет ошибок на терминале .. по крайней мере, это хороший знак!

class ScreenOne(Screen,BoxLayout):
    print_ip = StringProperty('')
       
    def __init__(self, **kwargs):
        super(ScreenEnergy, self).__init__(**kwargs)
        Clock.schedule_interval(self.update_ip, 1)
        print("status window")
        
    
    def update_ip(self,*args):     
        try:
            # connect to the host -- tells us if the host is actually
            # reachable
            socket.create_connection(("www.google.com", 80))
            stringIP = subprocess.check_output(["hostname", "-I"]).split()[0]
            self.print_ip = str(stringIP).strip("b'")
            print("ip={self.print_ip}")
            return True
        except OSError:
            self.ids.ipAddress.text="[b][color=ff0000]Error[/color][/b]"
            print("not Ip ")
        return False

перед отсоединением кабеля Ethernet (выглядит хорошо) enter image description here

после отсоединения кабеля (выглядит хорошо) enter image description here

после повторного подключения кабеля Ethernet (не хорошо) enter image description here

выглядит как код, застрявший в , за исключением OSError: , потому что он не возвращается обратно к адресу Ethernet.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

В файле kivy вы устанавливаете id:ipAddress, что означает, что метка будет искать свойство ipAddress объекта ScreenOne.

Из-за особенностей работы свойств Kivy любые изменениячтобы это свойство было автоматически отражено в метке.Таким образом, в коде Python вы не должны устанавливать текст метки напрямую;вместо этого используйте self.ipAddress.set("The New Value")

Вы также не сбрасываете значение метки после ошибки, поэтому даже после установления соединения в инструкции try метка останется со значением ошибки.

Я рекомендую изменить функцию update_ip следующим образом:

def update_ip(self,*args):     
    try:
        # connect to the host -- tells us if the host is actually
        # reachable
        socket.create_connection(("www.google.com", 80))
        self.print_ip.set(str(stringIP).strip("b'"))
        print("ip")
        #print("connected")
        return True
    except OSError:
        self.print_ip.set("[b][color=ff0000]Error[/color][/b]")
        print("not Ip ")
    return False
1 голос
/ 12 апреля 2019

Проблема

Не сбрасывает атрибут, print_ip внутри блока try после вызова socket.create_connection().

Решение

При class ScreenOne выполнитеследующее:

  • Переместить stringIP=subprocess.check_output(["hostname", "-I"]).split()[0] после socket.create_connection() вызов
  • Заменить атрибут класса, print_ip = StringProperty(str(stringIP).strip("b'")) на print_ip = StringProperty('')
  • Добавить self.print_ip = str(stringIP).strip("b'") после stringIP = subprocess.check() вызов
  • Заменить self.ids.ipAddress.text на self.print_ip

Фрагменты

class ScreenOne(Screen):

    print_ip = StringProperty('')
    ...

    def update_ip(self,*args):     
        try:
            # connect to the host -- tells us if the host is actually
            # reachable
            socket.create_connection(("www.google.com", 80))
            stringIP = subprocess.check_output(["hostname", "-I"]).split()[0]
            self.print_ip = str(stringIP).strip("b'")
            print(f"ip={self.print_ip}")
        except OSError:
            self.print_ip = "[b][color=ff0000]Error[/color][/b]"
            print("not Ip ")
...