Clock.schedule_once不更新标签,但正在调用更新方法

时间:2019-01-21 17:20:47

标签: user-interface raspberry-pi kivy kivy-language

我有一个标签,一旦我从服务器收到文本,就需要在其中更新文本。方法正在工作,正在获取输出,并且函数也正在被调用,但标签文本未更新。

我的代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jan 21 00:34:58 2019

@author: driftking9987
"""
from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
import requests
from kivy.properties import StringProperty
from kivy.clock import Clock
import time

url = 'http://119.........'
l_server_text = "abc..."
l_server_text_waiting = "def..."
l_server_text_error = "ghi..."
self_global = ""

class HBoxWidget(BoxLayout):

    def __init__(self, **kwargs):
        super(HBoxWidget, self).__init__(**kwargs)

class VBoxWidget_Details(BoxLayout):
    label_name = StringProperty()

    def __init__(self, **kwargs):
        super(VBoxWidget_Details, self).__init__(**kwargs)
        self.label_name = l_server_text


    def updateText(self, *args):
        print("string to be updated is : ")
        print(l_server_text)
        print("updated")
        self.label_name = l_server_text


class ContainerBox(BoxLayout):
    def __init__(self, **kwargs):
        super(ContainerBox, self).__init__(**kwargs)

class WipApp(App):
    def build(self):
        global self_global
        self_global = self
        Clock.schedule_once(lambda dt: retrieveDataFromServer(self_global,12), 2)
        return ContainerBox() 


def retrieveDataFromServer(self,id):
    global l_server_text
    l_server_text = l_server_text_waiting
    print(l_server_text)
    a = VBoxWidget_Details()
    a.updateText(self)
    try:
        r_headers = {
        'Content-type': 'application/json',
        }
        data_post_req =  '{"id":'+str(id)+'}'
        print(data_post_req)
        response = requests.post('http://119....', headers=r_headers, data=data_post_req)
        res = response.json()
        output_text = res['Message']
        output_text = output_text.replace(':', '\n')
        print(output_text)
        l_server_text = output_text
        a = VBoxWidget_Details()
        a.updateText(self)
        print("done")
    except Exception as e:
        print("exception")
        l_server_text = l_server_text_error
        a = VBoxWidget_Details()
        a.updateText(self)


if __name__ == '__main__':
    wapp = WipApp()
    wapp.run()

KV文件:

<HBoxWidget>:

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'center'
        Image:
            source: '/Users/driftking9987/Desktop/fp.gif'
<VBoxWidget_Details>:
    BoxLayout:
        orientation: "horizontal"
        size: [1,.25]
        pos: root.pos
        Label:
            id: label_name
            text: root.label_name
            color: [0,84,80,19]
        Widget:

<ContainerBox>:
    orientation: 'vertical'
    Label:
        text: 'Label'
        size_hint_y: 0.1
    BoxLayout:
        id: four_horizontals
        orientation: 'horizontal'
        HBoxWidget:
        BoxLayout:
            orientation:'vertical'
            BoxLayout:
            BoxLayout:
                orientation:'vertical'
                VBoxWidget_Details:
            BoxLayout:

以下在端子中输出:

driftking9987$ python pp.py 
[INFO   ] [Logger      ] Record log in /Users/driftking9987/.kivy/logs/kivy_19-01-21_47.txt
[INFO   ] [Kivy        ] v1.10.1
[INFO   ] [Python      ] v3.6.8 |Anaconda custom (64-bit)| (default, Dec 29 2018, 19:04:46) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [Image       ] Providers: img_tex, img_imageio, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [Window      ] Provider: sdl2
[INFO   ] [GL          ] Using the "OpenGL ES 2" graphics system
[INFO   ] [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version <b'2.1 INTEL-12.4.7'>
[INFO   ] [GL          ] OpenGL vendor <b'Intel Inc.'>
[INFO   ] [GL          ] OpenGL renderer <b'Intel(R) Iris(TM) Graphics 650'>
[INFO   ] [GL          ] OpenGL parsed version: 2, 1
[INFO   ] [GL          ] Shading version <b'1.20'>
[INFO   ] [GL          ] Texture max size <16384>
[INFO   ] [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [GL          ] NPOT texture support is available
[INFO   ] [Base        ] Start application main loop
def...
string to be updated is : 
def...
updated
{"id":12}
KAM TRY
 logout
 Contac
string to be updated is : 
KAM TRY
 logout
 Contac
updated
done

在Kivy App上,我只看到abc是标签文本。

我计划在满足某些条件后递归调用retrieveDataFromServer,这应该会更改文本,但不会发生。

有什么主意吗?

*************************更新********************* *******

假设我只想引用带有ID的标签,那我该怎么做?

<HBoxWidget>:

    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'center'
        Image:
            source: '/Users/driftking9987/Desktop/fp.gif'
<VBoxWidget_Details>:
    BoxLayout:
        orientation: "horizontal"
        size: [1,.25]
        pos: root.pos
        the_label_g_info: label_name
        Label:
            id: label_name
            text: root.label_name
            color: [0,84,80,19]
        Widget:

<ContainerBox>:
    orientation: 'vertical'
    title_name: title
    Label:
        id: title
        text: 'Label'
        size_hint_y: 0.1
    BoxLayout:
        box_name: box_id
        id: four_horizontals
        orientation: 'horizontal'
        HBoxWidget:
        BoxLayout:
            orientation:'vertical'
            BoxLayout:
            BoxLayout:
                id: box_id
                the_label_g_info: label_name
                orientation:'vertical'
                VBoxWidget_Details:
            BoxLayout:

updateText方法内部,如果我尝试编写self.the_label_g_info.text="drift",则显示为AttributeError: 'wapp' object has no attribute 'the_label_g_info'

我的意思是,如何引用标签?我从2天开始尝试,似乎没有任何解决办法。同时,self.label_name = str(l_server_text)的{​​{1}}内的__init__似乎在初始化时正确设置了文本。

1 个答案:

答案 0 :(得分:-1)

在您的retrieveDataFromServer()方法中,我看到:

    a = VBoxWidget_Details()
    a.updateText(self)

在两个地方。这段代码正在创建一个新的VBoxWidget_Details实例,并在该新实例上而不是您所显示的实例上调用updateText()。您可能需要在某个地方保存对现有VBoxWidget_Details的引用,并在retrieveDataFromServer()方法中引用该实例。