omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Close Timer in ui Custom Class using @ui.in_background

    Pythonista
    ui.inbackground custom class timer
    2
    4
    4059
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by

      I wanted an auto_close function (async) in a custom ui.View class. I wanted to keep it as simple as possible without using date time and keeping the interface responsive . It's not meant to be exact, but close.
      date time is used, just to to test the approx accuracy.
      Below is a test of what is in my real class. I think the variance could easily be put down to other factors. Just post in case someone has some comments. This is not my forte, but I was happy with my solution. But opened to being to told I lost the plot.

      import ui
      import datetime, time
      
      class Test (ui.View):
      	def __init__(self, duration = 1.0):
      		self.frame = (0,0,300,300)
      		self.background_color = 'white'
      		btn = ui.Button(title = 'start')
      		btn.width = 100
      		btn.border_width = .5
      		# hmmmmmmm, center does not work ( as you would expect it too )
      		# eg. btn.center = self.center
      		btn.center = (self.center[0], self.center[1] - (44/2))
      		btn.action = self.auto_close_timer
      		self.add_subview(btn)
      		self.auto_close_duration = float(duration)
      		
      	@ui.in_background
      	def auto_close_timer(self, sender):
      		# try to stay responsive regardless of the time
      		# set.  its not meant to be exact, but its very close
      		# for this close enough
      		sender.enabled = False
      		n = self.auto_close_duration
      		st = datetime.datetime.now()
      		while True:
      			n -= self.auto_close_duration / 10.
      			if n < 0.0 : break
      			time.sleep(self.auto_close_duration / 10.)
      		#print datetime.datetime.now() - st
      		self.name = str(datetime.datetime.now() - st)
      		sender.enabled = True
      		
      	
      if __name__ == '__main__':
      	t = Test(1.5)
      	t.present('sheet')
      
      JonB 1 Reply Last reply Reply Quote 0
      • JonB
        JonB @Phuket2 last edited by

        @Phuket2 Why not just use ui.delay rather than a sleep loop? If this is supposed to be an inactivity timer, you could just use ui.cancel_delay whenever activity is detected.

        Also, if there is the possibility of any other ui.in_background happening at the same time, you need to use ui.delay or a threading.thread, ( or see my run_async decorator that I have posted before) as no other ui.in_background calls will start until this one has completed.

        Phuket2 2 Replies Last reply Reply Quote 1
        • Phuket2
          Phuket2 @JonB last edited by

          @JonB , I want to cry sometimes. BUT yes, you are 100% correct. Thank you. But that's why I post. It would be horrible to have my code when such an elegant solution is there starring me in the face. But it's my learning curve, I guess.
          Maybe that crazy crap I come up with will come in handy one day 😁

          1 Reply Last reply Reply Quote 0
          • Phuket2
            Phuket2 @JonB last edited by

            @JonB , revised version of the test code. is a lot of extra just for testing. But so clean now for the timer part. Also a lot more accurate timings . Thanks again

            import ui
            import datetime, time
            
            class Test (ui.View):
            	def __init__(self, duration = 1.0):
            		self.frame = (0,0,300,300)
            		self.background_color = 'white'
            		btn = ui.Button(title = 'start')
            		btn.width = 100
            		btn.border_width = .5
            		# hmmmmmmm, center does not work ( as you would expect it too )
            		# eg. btn.center = self.center
            		btn.center = (self.center[0], self.center[1] - (44/2))
            		btn.action = self.JonB_way
            		self.fire_obj = btn
            		self.add_subview(btn)
            		self.auto_close_duration = float(duration)
            		self.start = None
            		
            	def JonB_way(self, sender):
            		self.fire_obj.enabled = False
            		self.start = datetime.datetime.now()
            		ui.delay(self.fire_delay, self.auto_close_duration)
            	
            	def fire_delay(self):
            		self.name = str(datetime.datetime.now() - self.start)
            		self.fire_obj.enabled = True
            
            1 Reply Last reply Reply Quote 0
            • First post
              Last post
            Powered by NodeBB Forums | Contributors