【问题标题】:Kivy - Updating label in kv code from python sideKivy - 从 python 端更新 kv 代码中的标签
【发布时间】:2016-11-15 02:55:23
【问题描述】:

我正在尝试制作一个带有几个屏幕和一个按钮的 GUI,该按钮将从 SQLite 数据库中获取一些数据并将其分配给要在 GUI 屏幕上显示的标签。总的来说,我对 kivy、python 和面向对象编程还是很陌生。我尝试运行它,它似乎可以正常获取 SQL 数据,但我无法将它分配给我想要显示的标签。我得到的错误是“属性错误:'float'对象没有属性'psarjvalue'”,所以我知道它正在查看我的浮动布局并试图找到psarjvalue但没有成功,为什么不呢?我也尝试为浮动布局分配一个 id,但我显然遗漏了一些东西。

import kivy
import sqlite3
import sched, time
import smbus
import time
from Naked.toolshed.shell import execute_js, muterun_js
import os
import signal
import multiprocessing, signal
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.uix.button import Button
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.base import runTouchApp
from kivy.clock import Clock
from kivy.properties import ListProperty
from kivy.vector import Vector
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.stacklayout import StackLayout
from kivy.core.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, WipeTransition, SwapTransition

bus = smbus.SMBus(1)
address = 0x04 

psarj = 0.00

p = multiprocessing.Process(target = muterun_js,args=('iss_telemetry.js',))

conn = sqlite3.connect('iss_telemetry.db')
c = conn.cursor()

class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

class CalibrateScreen(Screen):
    pass

class ManualControlScreen(Screen):
    def __init__(self, **kwargs):
        super(ManualControlScreen, self).__init__(**kwargs)

class MimicScreen(Screen):
    def __init__(self, **kwargs):
        super(MimicScreen, self).__init__(**kwargs)

    def updatePSARJ(self, *args, **kwargs):
        c.execute('SELECT two FROM telemetry where one="psarj"') 
        psarj = c.fetchone()
        label = self.psarjvalue
        label.text = psarj

       # self.psarjvalue.text = psarj

class MainScreenManager(ScreenManager):
    pass

#def updatePSARJ(*args):
#    c.execute('SELECT two FROM telemetry where one="psarj"') 
#    psarj = c.fetchone()
#    MimicScreen.psarjlabel.text = psarj

class MainApp(App):
    def build(self):
        root = ScreenManager(transition=WipeTransition())
        root.add_widget(MainScreen(name = 'main'))
        root.add_widget(CalibrateScreen(name = 'calibrate'))
        root.add_widget(MimicScreen(name = 'mimic'))
        root.add_widget(ManualControlScreen(name = 'manualcontrol'))
        root.current= 'main'
        return root

    def startTelemetry(*kwargs):
        p.start()

    def stopTelemetry(*kwargs):
        os.kill(p.pid,signal.SIGKILL)

#def update_values(*args):
#    c.execute('SELECT two FROM telemetry where one="psarj"') 
#    psarj = c.fetchone()
#    MimicScreen.updatePSARJ()

Clock.schedule_interval(MimicScreen.updatePSARJ, 1)

Builder.load_string('''
#:kivy 1.8
#:import kivy kivy
#:import win kivy.core.window

<MimicScreen>:
    name: 'mimic'
    FloatLayout:
        id: mimicscreenlayout
        Image:
            source: 'iss1.png'
            allow_stretch: True
            keep_ratio: False
        Label:
            id: psarjvalue
            pos_hint: {"center_x": 0.7, "center_y": 0.5}
            text: '0.003'
            markup: True
            color: 1,1,1
            font_size: 60
        Label:
            id: telemetrystatus
            pos_hint: {"center_x": 0.6, "center_y": 0.8}
            text: 'Telemetry'
            markup: True
            color: 1,0,1
            font_size: 60
        Button:
            id: mimicstartbutton
            size_hint: 0.3,0.1
            pos_hint: {"x": 0.1, "y": 0.6}
            text: 'MIMIC'
            disabled: False
            font_size: 30
            on_release: telemetrystatus.text = 'Fetching Telemetry...'
            on_release: app.startTelemetry()
            on_release: mimicstopbutton.disabled = False
            on_release: mimicstartbutton.disabled = True
        Button:
            id: mimicstopbutton
            size_hint: 0.3,0.1
            pos_hint: {"x": 0.1, "y": 0.4}
            text: 'Stop'
            disabled: True
            font_size: 30
            on_release: telemetrystatus.text = 'Program Stopped'
            on_release: app.stopTelemetry()
            on_release: mimicstopbutton.disabled = True
            on_release: mimicstartbutton.disabled = False
        Button:
            size_hint: 0.3,0.1
            pos_hint: {"Left": 1, "Bottom": 1}
            text: 'Return'
            font_size: 30
            on_release: root.manager.current = 'main'

''')

if __name__ == '__main__':
    MainApp().run()

这是 kv 代码中带有我要更新的标签的部分:

<MimicScreen>:
    name: 'mimic'
    FloatLayout:
        id: mimicscreenlayout
        Image:
            source: 'iss1.png'
            allow_stretch: True
            keep_ratio: False
        Label:
            id: psarjvalue
            pos_hint: {"center_x": 0.7, "center_y": 0.5}
            text: '0.003'
            markup: True
            color: 1,1,1
            font_size: 60

这是python端的相关部分

conn = sqlite3.connect('iss_telemetry.db')
c = conn.cursor()

class MimicScreen(Screen):
    def __init__(self, **kwargs):
        super(MimicScreen, self).__init__(**kwargs)

    def updatePSARJ(self, *args, **kwargs):
        c.execute('SELECT two FROM telemetry where one="psarj"') 
        psarj = c.fetchone()
        label = self.psarjvalue
        label.text = psarj

label = self.psarjvalue 是问题出现的地方

如何将此链接到我的 kv 标签? 我试过 label = self.ids['psarjvalue'] 和同样的错误

...某物某物的属性?

感谢您的帮助

【问题讨论】:

    标签: python sqlite user-interface kivy


    【解决方案1】:

    已编辑:查看完整代码后,问题似乎在于更新标签的方法的调度。

    Clock.schedule_interval(MimicScreen.updatePSARJ, 1)

    由于缺少 python 库,我无法完全测试您的代码,但也许创建一个将传递给 Clock.schedule_intervalMainApp 方法将达到相同的目的。 (评论或删除原Clock.schedule_interval(MimicScreen.updatePSARJ, 1)

    MainApp(App):
        def build(self):
            # Create attribute that will be used to reference labels
            self.m_screen = MimicScreen(name = 'mimic')
            root = ScreenManager(transition=WipeTransition())
            root.add_widget(MainScreen(name = 'main'))
            root.add_widget(CalibrateScreen(name = 'calibrate'))
            # Provide the above created attribute instead of creating a new instance
            root.add_widget(self.m_screen)
            root.add_widget(ManualControlScreen(name = 'manualcontrol'))
            root.current= 'main'
    
            # Put the schedule function here, and reference the new function defined below
            Clock.schedule_interval(self.update_labels, 1)
            return root
    
        # This method will periodically update the label text
        def update_labels(self, dt):
            c.execute('SELECT two FROM telemetry where one="psarj"')
            psarj = c.fetchone()
            self.m_screen.ids.psarjvalue.text = psarj
    
        def startTelemetry(*kwargs):
            p.start()
    
        def stopTelemetry(*kwargs):
            os.kill(p.pid,signal.SIGKILL)
    

    【讨论】:

    • AttributeError: 'float' 对象没有属性 'ids'
    • 查看完整代码,问题似乎出在Clock.schedule_interval(MimicScreen.updatePSARJ, 1)。这样self属性就变成了float 1而不是Screen对象。据我所知,您想安排一个定期更新标签文本的功能,是吗?
    • 正确,我想在屏幕上有一个标签(实际上是几个标签),每个标签都代表我的 SQL 数据库中的一个值(将不断更新),所以我希望每个标签都更新等于该值大约每秒一次
    • 是的!完美运行!!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2022-09-28
    • 1970-01-01
    • 2015-06-09
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多