问题
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