0

'main_loop' function while loop does not increment self.i value every 5 seconds and 'run' function does not decrement self.mycounter value every 1 second.

Why?

What am I doing wrong?

I do not want to use time.sleep.

class MyThread(BoxLayout):
    stop = []
    timer = []
    times = []

    i = NumericProperty(0)
    mycounter = NumericProperty(0)

    def incrementi(self, *args):
        self.i += 1

    def decrementcounter(self,*args):
        self.mycounter -= 1

    def run(self):
        self.mycounter = 30
        while not self.stop:
            self.timer.append(self.mycounter)
            Clock.schedule_interval(self.decrementcounter, 1.0)
        self.times.append(self.mycounter)
        return self.mycounter

    def main_loop(self):
        self.i = 0
        while True:
            Clock.schedule_interval(self.incrementi, 5.0)
            if self.i == 2:
                self.mycounter = 30
                threading.Thread(target = self.run).start()
            if self.i == 5:
                self.stop.append('dummystring')
            if self.i == 6:
                self.stop.pop(0)
                self.timer = []
            self.ids.lbl.text = "{}".format(self.i)
            if self.i == 7:
                self.i = 0

    def read_it(self):
        threading.Thread(target = self.main_loop).start()

class MyApp(App):
    def build(self):
        self.load_kv('thread.kv')
        return MyThread()

if __name__ == "__main__":
    app = MyApp()
    app.run()

kivy.pv

<MyThread>:
    Button:
        text: "start program"
        on_release: root.read_it()
    Label:
        id: lbl
        text: "current step"
        font_size: 50
  • Nothing will happen in Kivy until your while loop returns, as it blocks the thread. Use a Clock schedule to run your code regularly instead. – inclement Jun 14 '16 at 22:25
  • but I have threads in my while loop ... e.g. I start thread if self.i equals 2...so I can not call while loop 'x' seconds with Clock... what do you propose please? –  Jun 14 '16 at 22:27
  • I don't see why this prevents you calling the function regularly via the clock, but if you really want to do things this way then put the whole function in a thread. – inclement Jun 14 '16 at 22:32

1 Answers1

0

I suggest you to throw away whole while styling if it's not necessary - especially that one in main_loop, which is just checking values. It's not good in kivy if you really don't need that functionality e.g.:

while <some list>:
    value = <some list>.pop()
    # do something

and even here are ways how to do it differently. As inclement suggested, using Clock is the right way. Also a little wrong detail in that particular loop is this:

while True:
    Clock.schedule_interval(self.incrementi, 5.0)

This will schedule interval infinitely many times, which will basically either freeze your app when you run this function or (if run in Thread) cause an endless loop/freeze + create a big memory eater = it will forbid you to Thread.set() i.e. stopping the thread and exiting the app correctly and in the end will crash.

I hope it's typo, because you only need to put it above while loop. Another thing: decrementcounter... It's in a while loop, it'll again create multiple Clocks and cause troubles. The same thing - again, put it either above the loop to make it work.

Basically while with time.sleep(t) is Clock.schedule_interval(some_function, t). It's nice that you want to check for something, but with each Clock.schedule_* you create another clock and I don't see anything that stops it. So basically you'll create infinitely many clocks.

Something more similar to while only(without sleep) is Clock.schedule_interval(some_function) i.e. you leave out time parameter and it'll call the function on each frame which if 60fps, then 60times per second. Quite precise for a simple value checking.

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
  • I use 'while' in 'main_loop' function because I want to constantly monitor 'i' value every 'x' seconds. how can I do it differently without 'while'? I want to start thread so I can run simultaneous function to do other things while I strill want to monitor value of 'i'. So, what is your proposal to solve it? –  Jun 15 '16 at 20:21
  • Next item..'decrement counter'...if 'i' value is between specific range e.g. 2 & 5 I want to run countdown timer so I know how long it took to get from 2 to 5...how can I do it differently without timer without thread especially when time between 2 and 5 may be different each time? –  Jun 15 '16 at 20:24