Clock.schedule_once not updating the label, but update method is being called

橙三吉。 提交于 2019-12-13 04:17:20

问题


I have a label in which I need to update the text once I receive the text from server. Method is working, am getting the output and the function is also getting called, but the label text is not updating.

My code :

#!/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 file :

<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:

Below is output in terminal :

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

And on the Kivy App, all I see is abc is the label text.

I plan to call the retrieveDataFromServer recursively after some condition is satisfied and that should change the text but it's not happening.

Any idea?

*************************UPDATE****************************

Let's say I just want to reference the label with the id, then how do I do that?

<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:

Inside the updateText method, if I try to write self.the_label_g_info.text="drift" , it says AttributeError: 'wapp' object has no attribute 'the_label_g_info'

I mean, how do I reference the label? I am trying from 2 days, nothing seems to fix this. At the same time, the self.label_name = str(l_server_text) inside __init__ of VBoxWidget_Details seems to set the text correctly while initialising.


回答1:


In your retrieveDataFromServer() method, I see:

    a = VBoxWidget_Details()
    a.updateText(self)

in two places. This code is creating a new VBoxWidget_Details instance and calling updateText() on that new instance rather than on the one you have displayed. You probably need to save a reference to the existing VBoxWidget_Details somewhere, and reference that instance in your retrieveDataFromServer() method.



来源:https://stackoverflow.com/questions/54294930/clock-schedule-once-not-updating-the-label-but-update-method-is-being-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!