code: def invalidate(self):
          
          # Never schedule a second redraw, when a previous one has not yet been
          # executed. (This should protect against other threads calling
          # 'invalidate' many times, resulting in 100% CPU.)
          if self._invalidated:
              return
          else:
              self._invalidated = True
  
          # Trigger event.
          self.on_invalidate.fire()
  
          if self.eventloop is not None:
              def redraw():
                  self._invalidated = False
                  self._redraw()
  
              # Call redraw in the eventloop (thread safe).
              # Usually with the high priority, in order to make the application
              # feel responsive, but this can be tuned by changing the value of
              # `max_render_postpone_time`.
              if self.max_render_postpone_time:
                  _max_postpone_until = time.time() + self.max_render_postpone_time
              else:
                  _max_postpone_until = None
  
              self.eventloop.call_from_executor(
                  redraw, _max_postpone_until=_max_postpone_until)
docs: Thread safe way of sending a repaint trigger to the input event loop.