【问题标题】:Clock.schedule_once not updating the label, but update method is being calledClock.schedule_once 不更新标签,但正在调用更新方法
【发布时间】:2019-06-15 03:15:51
【问题描述】:

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

我的代码:

#!/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 应用程序上,我看到的只是 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 天开始尝试,似乎没有什么可以解决这个问题。同时,VBoxWidget_Details__init__ 内部的self.label_name = str(l_server_text) 似乎在初始化时正确设置了文本。

【问题讨论】:

  • 抱歉,这个问题可能很愚蠢,但您要更新的Label 在哪里?我在你的代码中没有看到。
  • @JohnAnderson,我没有发布 kv 代码,但是 VBoxWidget_Details 中的 label_name = StringProperty() 是正在谈论的标签。
  • 更新了代码。

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


【解决方案1】:

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

    a = VBoxWidget_Details()
    a.updateText(self)

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

【讨论】:

  • 一共有三个instance,一个在start中,第二个在try中,第三个在except中。即使我删除了 try 和 except 中的那些,我也会遇到同样的错误。我只是在函数开始时初始化它,然后调用a.updateText(self)
  • 我错过了其中一个,所以实际上有四个实例。您提到的三个和显示中的一个(由您的KV 中的VBoxWidget_Details: 行创建)。 KV 中的那个是正在显示的那个,所以这是您应该引用的唯一实例。
  • KV 中,我只是将文本引用到root.label_name,而在python 中,在init 中,它正在更改文本。之后,我只是创建一个新实例(如您所述)。我不认为KV 会创建任何实例。
  • KV 文件中,您的&lt;ContainerBox&gt;: 提供了创建ContainerBox 的规则。当WipApp 中的build() 方法调用ContainerBox() 时,将遵循该规则并在WipApp 启动时创建并显示VBoxWidget_Details 的实例。对VBoxWidget_Details() 的任何其他调用都会创建一个新的不同的VBoxWidget_Details 实例,但不会显示。
猜你喜欢
  • 1970-01-01
  • 2016-12-23
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多