【问题标题】:Trying to convert app from Tkinter to Kivy: can't get labels to update尝试将应用程序从 Tkinter 转换为 Kivy:无法更新标签
【发布时间】:2015-03-30 19:35:53
【问题描述】:

我在 Tkinter 中有一个功能齐全的应用程序,我正试图了解 Kivy 的工作原理,并且已经碰壁了几天。我把所有的东西都布置好了(最后)并完全放弃了使用 .kv 文件。我认为,如果我可以通过 Python 代码完成一些工作,那么我将开始了解 Python 和 Kivy 之间的关系。无论如何,现在的问题是当我调用函数时我无法更新标签。我只想(现在)在按下按钮时获得一个标签来更改它的文本。在 tkinter 中非常容易,但在这里并非如此。我已经尝试了许多不同的组合来让它工作,但我失败了。你会注意到这个按钮调用了 tick() 函数,它最初是切换屏幕的,但是我改变了它,所以我可以让它改变标签。最终我希望时钟在屏幕顶部运行,但会满足于让它更新为一些任意文本。带有完整代码的回复将是超级的!
(ps。我知道你们中的大多数人可能会在 30 分钟内完成整个应用程序,这是非常基本的)

谢谢

这是我的代码:

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager 
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
from kivy.uix.image import Image
from kivy.event import EventDispatcher

import time
import datetime

class ScreenOne(Screen):

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

        main_box = BoxLayout(orientation='vertical')
        header_box = BoxLayout(size_hint_y=None, height=35)
        top_box = BoxLayout(size_hint_y=None, height=60)
        middle_box = BoxLayout(size_hint_y=None, height=300)
        bottom_box = BoxLayout()
        middle1_box =BoxLayout(size_hint_x=None, width=50)
        middle2_box = BoxLayout(orientation='vertical')
        list_box1 = BoxLayout()
        list_box2 = BoxLayout()
        list_box3 = BoxLayout()
        list_box4 = BoxLayout()
        list_box5 = BoxLayout()
        list_box6 = BoxLayout()

        checkmark = 'Check_Mark.jpg'
        redX = Image(source='red_X')

        my_label1 = Label(text="BlaBlaBla on screen 1", font_size='24dp')
        my_button1 = Button(text="Go to screen 2",size_hint_y=None, size_y=100)
        my_button1.bind(on_press=self.tick)
        self.date_label = Label(text="not working")
        top_label = Label(text="The top text")
        mid_label = Label(text="The mid text")
        bot_label = Label(text="The bottom text")
        header_label = Label(text=" ")
        my_image = Image(source='colours.png', allow_stretch=True, keep_ratio=False)
        my_image2 = Image(source='colours2.png', allow_stretch=True, keep_ratio=False)

        my_image3 = Image(source='red_X.gif')

        fish_icon = Image(source=checkmark)
        coral_icon = Image(source=checkmark)
        topoff_icon = Image(source=checkmark)
        water_icon = Image(source=checkmark)
        filter_icon = Image(source=checkmark)
        bulb_icon = Image(source=checkmark)

        fish_label = Label(text="Last Fish Feeding", font_size=30)
        coral_label = Label(text="Last Coral Feeding", font_size=30)
        topoff_label = Label(text="Last water Top-Off", font_size=30)
        water_label = Label(text="Last Water Change", font_size=30)
        filter_label = Label(text="Last Filter Replacement", font_size=30)
        bulb_label = Label(text="Last Bulb Replacement", font_size=30)

        last_fish_date = Label(text="This is a date", font_size=30)
        last_coral_date = Label(text="This is a date", font_size=30)
        last_topoff_date = Label(text="This is a date", font_size=30)
        last_water_date = Label(text="This is a date", font_size=30)
        last_filter_date = Label(text="This is a date", font_size=30)
        last_bulb_date = Label(text="This is a date", font_size=30)

      #  main_box.add_widget(bot_label)
        main_box.add_widget(header_box)
        main_box.add_widget(top_box)
        main_box.add_widget(middle_box)
        main_box.add_widget(bottom_box)
        header_box.add_widget(header_label)
        header_box.add_widget(self.date_label)

        top_box.add_widget(my_image)
        middle_box.add_widget(middle1_box)
        middle1_box.add_widget(my_image3)
        middle_box.add_widget(middle2_box)
        middle2_box.add_widget(list_box1)
        middle2_box.add_widget(list_box2)
        middle2_box.add_widget(list_box3)
        middle2_box.add_widget(list_box4)
        middle2_box.add_widget(list_box5)
        middle2_box.add_widget(list_box6)

        list_box1.add_widget(fish_icon)
        list_box1.add_widget(fish_label)
        list_box1.add_widget(last_fish_date)
        list_box2.add_widget(coral_icon)
        list_box2.add_widget(coral_label)
        list_box2.add_widget(last_coral_date)
        list_box3.add_widget(topoff_icon)
        list_box3.add_widget(topoff_label)
        list_box3.add_widget(last_topoff_date)
        list_box4.add_widget(water_icon)
        list_box4.add_widget(water_label)
        list_box4.add_widget(last_water_date)
        list_box5.add_widget(filter_icon)
        list_box5.add_widget(filter_label)
        list_box5.add_widget(last_filter_date)
        list_box6.add_widget(bulb_icon)
        list_box6.add_widget(bulb_label)
        list_box6.add_widget(last_bulb_date)

        bottom_box.add_widget(my_button1)
        self.add_widget(main_box)
    def tick(self, *args):
        print ("test output")
        time1 = " "
        # get the current local time from the PC
        time2 = time.strftime('%H:%M:%S')
        time3 = time.strftime('%M:%S')

        date = datetime.datetime.strftime(date, "%m-%d-%Y   ")
        if time2 != time1:
            time1 = time2
            self.time1 = time1
            self.date_label(text=date + time2)




    def changer(self,*args):
        self.manager.current = 'screen2'

class ScreenTwo(Screen):

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

        my_box1 = BoxLayout(orientation='vertical')
        my_label1 = Label(text="BlaBlaBla on screen 2",font_size='24dp')
        my_button1 = Button(text="Go to screen 1",size_hint_y=None, size_y=100)
        my_button1.bind(on_press=self.changer)
        my_box1.add_widget(my_label1)
        my_box1.add_widget(my_button1)
        self.add_widget(my_box1)

    def changer(self,*args):
        self.manager.current = 'screen1'

class TestApp(App):

        def build(self):
            my_screenmanager = ScreenManager()
            screen1 = ScreenOne(name='screen1')
            screen2 = ScreenTwo(name='screen2')
            my_screenmanager.add_widget(screen1)
            my_screenmanager.add_widget(screen2)
            return my_screenmanager

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

【问题讨论】:

    标签: python function label kivy


    【解决方案1】:
    date = datetime.datetime.strftime(date, "%m-%d-%Y   ")
    

    此行会导致崩溃,因为日期尚未定义,但您在其自己的定义中使用它。

    self.date_label(text=date + time2)
    

    self.date_label 是一个 Label 实例,但它是不可调用的。设置 kivy 属性的正确方法是将其作为属性访问:

    self.date_label.text = time2
    

    (由于上面定义中的问题,我删除了日期部分)。

    【讨论】:

    • 我已经删除了这篇文章的一些代码,定义一定是其中的一部分。谢谢!我一更改 self.date_label.text 就可以设置文本。既然我知道了更改 Kivy 属性的语法,我想这就是我需要继续的全部内容!
    • 所以,我立即尝试在不使用按钮的情况下调用此函数,并得到错误“自我未定义”。我在 ScreenOne init 类的最后一行添加了 self.tick()。我只是想让它调用一次。我想即使在阅读了很多关于它的文章/博客之后,我也很难理解“自我”。
    • 我现在尝试创建一个使用 Kivy 时钟调度程序的新函数,名为“my_callback(dt):”,并安排 1 秒的时间间隔调用 tick(self, *args) 函数并获取“ fload 对象没有属性 date_label”。如果我注释掉新功能并使用按钮,一切仍然正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多