简体   繁体   中英

Why do Kivy labels not update when another function is running?

I have some test code below, that basically makes a user input on the second page with a counter going up as a label, a text input, and a go button. My code just prints out the difference between the number inputted and what the current count is, as long as the number inputted is lower than the label number. Else it will just print "Finished". But when I run the code Kivy pauses and the label doesn't update, but it prints just fine. Do I need to start teaching myself about python threading or is there something I am missing? I want that label to keep updating if I can as the other function runs.

This is a very small version (and useless beyond my learning purposes) of a larger code to read water tank levels. In that code I have a sonar function constantly running the same way I do here, with a clock interval schedule in the build method of the main app. I have labels tied to that level the sonar method returns, but I want to be able to access and do things with that level with user inputs which doesn't just pause the interface every time those buttons to other methods are pressed.

.py

class Home(Screen):
    global i
    i=1
    def count_up(self):
        global i
        global count
        if i < 100:
            count = (0 + i)
            i += 1
        else:
            i = 1
            count = 0
        App.get_running_app().count=str(count)
        return count

    def finish(self):
        print("Done")

    def go(self, num):
        end_num = int(num.text)
        if end_num < self.count_up():  # add or if valve state equals close here to kill the program
            print(str(self.count_up() - end_num))
            time.sleep(0.5)  # Getting rid of this and using true sonar may fix the problem
            self.go(num)
        else:
            self.finish()

class Second(Screen):
    pass
class WindowManager(ScreenManager):
    pass

class HelpMe(App):
    count = StringProperty("")

    def build(self):
        kv = Builder.load_file("help2.kv")
        self.Home=Home()
        Main = kv.get_screen("Home")
        Clock.schedule_interval(lambda dt: Main.count_up(), 0.1)
        return kv

if __name__ == "__main__":
    HelpMe().run()

.kv

WindowManager:
    Home:
    Second:

<Home>:
    name:"Home"

    GridLayout:
        cols:1

        Button:
            text:"Go"
            on_release:
                app.root.current="Second"
                root.manager.transition.direction="left"

<Second>:
    name:"Second"
    num: num

    GridLayout:
        cols:1

        Label:
            text:app.count

        TextInput:
            id:num
            input_filter:"int"
            multiline:False

        Button:
            text:"Back"
            on_release:
                app.Home.go(num)
                num.text=""
                app.root.current="Home"
                root.manager.transition.direction="right"

If you use time.sleep your GUI will pause. You have to use schedule functions to keep the app running. You can change:

time.sleep(0.5)
self.go(num)

To:

Clock.schedule_once(lambda dt: self.go(num), 0.5)

Also you are referencing the input form every time you call the function go with num . So if you erase it with num.text: "" you will recive an error. To bypass this either remove this statement from kv language or call you function like this:

on_release:
    app.Home.go(num.text)
    num.text=""

And in your go function:

end_num = int(num)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM