使用纯Python更改Kivy中的标签

时间:2017-02-10 19:27:46

标签: python label kivy edit kivy-language

我正在编写一个多子系统项目,该项目涉及3个Raspberry Pis使用套接字通过本地网络相互聊天。在其中一个Pis上,我正在编写一个Kivy应用程序。我正试图在Kivy中获得一个标签,以便当其中一个Pis通过套接字验证它没问题时更改其文本。

.kv文件中标签的定义:

Label:
                            id: distance_label
                            markup:True
                            text:"[size=40]Distance:[/size]\n\n[size=60][color=ff0000]NO[/color][/size]"
                            halign:"center"
                            valign:"top"
                            color:black

然后有一个完全独立的Python线程,我正在操纵套接字。这会ping子系统,然后尝试在成功回复时更改标签:

def test_socket(self, connection):
            Communication.server.send_data(connection,"VERIFY?")
            data_back = Communication.server.receive_data(connection)
            print data_back
            if data_back == "DISTANCE!":
                    # set distance to OK
                    print "Distance is OK"
                    InitScreen().distance_on()

然后尝试触发InitScreen类的distance_on()方法。该方法似乎被触发(如果你把它放在那里它将打印出一个小的调试信息),但令人讨厌的是标签文本不会改变它的原始值。

class InitScreen(Screen):
    ........

    def distance_on(self, *args):
            distance_label = self.ids['distance_label']
            distance_label.text = "[size=40]Distance:[/size]\n\n[size=60][color=008000]OK[/color][/size]"
            print distance_label.text

在代码的另一部分中,我使用Kivy中的on_event函数来使用滑块更改标签的值。这非常有效。我试图使我的代码看起来尽可能与这个工作实例相似,唯一的区别是我没有尝试从一个Kivy事件触发,只是在Python中。

任何人都能解开一些光明吗?这是与调用另一个班级有关的事情吗?方法? ID问题?

这不是一个重复的问题。建议的重复涉及触发Kivy事件的功能。我想从Python本身触发一个Kivy标签更改 - 而不是像触摸按钮那样的Kivy事件。

以下是所有相关代码。我认为这个问题与我使用ScreenManager的事实相混淆,但我不能这样做!

方案:

class Communication(threading.Thread):
    server = serv.Server()

    def run(self):
            self.setup()
            while distance == False:
                    (connection, address) = self.awaiting_socket()
                    self.test_socket(connection)

    def setup(self):
            Communication.server.setup_server()
            print "SUCCESS ON BIND"

    def awaiting_socket(self):
            print "AWAITING"
            (connection, address) = Communication.server.socket_reception()
            return (connection, address)

    def test_socket(self, connection):
            Communication.server.send_data(connection,"VERIFY?")
            data_back = Communication.server.receive_data(connection)
            print data_back
            if data_back == "DISTANCE!":
                    # set distance to OK
                    print "Distance is OK"
                    application.InitScreen.distance_on()
                    #global distance
                    #distance = True
            if data_back == "STEPPER!":
                    # set stepper to OK
                    print "Stepper is OK"
            ..............

class InitScreen(Screen):
    def power_off(self, *args):
            onoffswitch = self.ids["onoffswitch"]
            onoff_value = onoffswitch.active
            if onoff_value == False:
                    subprocess.call(powerdown)

    def distance_on(self):
            distance_label = self.ids["distance_label"]
            distance_label.text = "[size=40]Distance:[/size]\n\n[size=60][color=008000]OK[/color][/size]"

class ScreenManagement(ScreenManager):
    pass

application = Builder.load_file("main.kv")

class LidarApp(App):
           def build(self):
                return application

KIVY DEFINING SCREEN MANAGER:

ScreenManagement:
    transition: FadeTransition()
    InitScreen:
    MainScreen:

问题中的KIVY DEFINING LABEL:

Label:
                            id: distance_label
                            markup:True
                            text:"[size=40]Distance:[/size]\n\n[size=60][color=ff0000]NO[/color][/size]"
                            on_text:
                            halign:"center"
                            valign:"top"
                            color:black

1 个答案:

答案 0 :(得分:0)

正如test_socket中的评论所述,您需要获取当前屏幕。为此,您需要使用ScreenManager.current_screen

Builder.load_file返回一个ScreenManager。这意味着您需要使用application全局变量。

您完成的代码:

def test_socket(self, connection):
    Communication.server.send_data(connection,"VERIFY?")
    data_back = Communication.server.receive_data(connection)
    print data_back
    if data_back == "DISTANCE!":
            # set distance to OK
            print "Distance is OK"
            application.current_screen.distance_on()