textual icon indicating copy to clipboard operation
textual copied to clipboard

Feature to Update Widget's Refresh Speed

Open klei22 opened this issue 3 years ago • 5 comments

Hoping to create a widget that I can modify the refresh speed, after it is mounted.

I looked through the source and the documentation, wondering if might already be possible?

klei22 avatar Mar 27 '22 02:03 klei22

I think what you are looking for is set_interval

class MyWidget(Widget):
    def on_mount(self):
        self.set_interval(1, self.refresh)

Or do you mean have one interval on mount and then change it later? I haven't tried, but it seems like calling self.set_interval(...) outside on_mount should also work.

sanders41 avatar Mar 28 '22 01:03 sanders41

Or do you mean have one interval on mount and then change it later?

^Exactly

Hmm, just tried the self.set_interval, and seems like the refresh rate itself is not changed to the new value.

To test this, I just tried setting the interval to self.set_interval(1, self.refresh) in the 'render' method, and this caused exponential growth of the refresh rate. This would make sense if each time render is called it creates a new timer.

Is there a way to specifically increase the refresh rate of the widget after the on_mount has been called?

klei22 avatar Apr 09 '22 03:04 klei22

set_interval will create a new timer each call. You can save the timer object with self.interval = self.set_interval. To change the "Refresh rate" you can stop that interval and create a new one:

self.interval.stop()
self.interval = self.set_interval(0.5, self.refresh)

willmcgugan avatar Apr 09 '22 07:04 willmcgugan

Just made the repo public (and apache-2.0) : ) , working on adding live mod to the refresh rate this branch and hoping this helps: https://github.com/klei22/Speedy-Reader/tree/in_app_wpm_increment_feature

After experimentation, found that calling self.interval.stop() (in this case when pressing "j" or "k") is found to not stop the timer (instead rendering and refreshing continues).

Sharing steps for reproduction:

lines 91 - 92 of speedreader.py:

      def on_mount(self):
          self.interval = self.set_interval(60 / (self.reader_speed / self.chunk), self.refresh)

lines 109 - 116 of speedreader.py, essentially:

       if SpeedReader.new_refresh_rate != self.refresh_rate and self.interval != None:
            self.interval.stop()
            self.output += " -- self.interval.stop() called"

Pressing j or k should makes the SpeedReader.new_refresh_rate != self.refresh_rate (confirmed this by appending a message at the end of the SpeedReader text segment saying -- self.interval.stop() called.

When pressing r to resume or start the autoscroller results in the refreshing continuing showing seemingly that the timer is continuing:

image

image

klei22 avatar Apr 11 '22 02:04 klei22

Figured out how stop refreshing which may help with adjusting refresh rate.

     async def refresh_toggler(self) -> None:
        if not self.done:
            self.refresh()
        else:
            await self.timer.stop()
    
     def on_mount(self):
        self.timer = self.set_interval(3, self.refresh_toggler)

droctothorpe avatar Aug 16 '22 18:08 droctothorpe

https://github.com/Textualize/textual/wiki/Sorry-we-closed-your-issue

willmcgugan avatar Oct 25 '22 09:10 willmcgugan

Did we solve your problem?

Glad we could help!

github-actions[bot] avatar Oct 25 '22 09:10 github-actions[bot]